Tcl Source Code

Artifact [b72e651cb5]
Login

Artifact b72e651cb5b0c33e6cd1eef1f7cd56b2dc9ef806:

Attachment "http.tcl.patch" to ticket [1470377fff] added by sloach 2006-04-14 21:05:42.
--- http.tcl.old	2006-04-14 09:47:49.000000000 -0400
+++ http.tcl	2006-04-14 09:47:32.000000000 -0400
@@ -267,6 +267,8 @@
         body            {}
 	status		""
 	http            ""
+        chunked         false
+        buf             ""
     }
     # These flags have their types verified [Bug 811170]
     array set type {
@@ -870,6 +872,13 @@
 		# grab the optional charset information
 		regexp -nocase {charset\s*=\s*(\S+)} $type x state(charset)
 	    }
+            if {[regexp -nocase {^transfer-encoding:(.+)$} $line x type]} {
+                # see if we are expecting a chunked response
+                if {[string trim $type] eq "chunked"} \
+                {
+                    set state(chunked) true
+                }
+            }
 	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
 		set state(totalsize) [string trim $length]
 	    }
@@ -890,7 +899,43 @@
 		set block [read $s $state(-blocksize)]
 		set n [string length $block]
 		if {$n >= 0} {
-		    append state(body) $block
+                    if {$state(chunked)} \
+                    {
+                        # De-chunk the response from buf into body.
+                        append state(buf) $block
+                        scan $state(buf) %s size
+                        while {$size > 0} {
+                            set hdrlen [expr {[string length $size] + 2}]
+                            set chunkSize [format %d 0x$size]
+                            set i [expr {$chunkSize + $hdrlen}]
+                            if {[string length $state(buf)] < $i + 2} {
+                                # wait for the entire chunk
+                                break
+                            }
+                            append state(body) [string range \
+                                    $state(buf) $hdrlen [expr {$i - 1}]]
+                            set state(buf) [string range \
+                                    $state(buf) [expr {$i + 2}] end]
+                            if {[string first \r\n $state(buf)] == -1} {
+                                # wait for size of next chunk
+                                break
+                            }
+                            scan $state(buf) %s size
+                        }
+                        if {$size == 0} {
+                            # last chunk has been read, assume we can just
+                            # discard the rest, but make sure we have enough
+                            set i [string first \r\n\r\n $state(buf)]
+                            if {$i < 0} {
+                                # keep waiting for more data
+                                break
+                            }
+                            set state(buf) ""
+                            Eof $token
+                        }
+                    } else {
+		        append state(body) $block
+                    }
 		}
 	    }
 	    if {$n >= 0} {