Tcl Source Code

View Ticket
Login
Ticket UUID: b9d0434667d94e5f9737b87ff024e7bc3baea5d5
Title: default settings request unreliable "deflate" compression
Type: Bug Version: 8.6
Submitter: Malbrouck Created on: 2014-12-11 10:11:43
Subsystem: 29. http Package Assigned To: dkf
Priority: 8 Severity: Important
Status: Closed Last Modified: 2015-05-14 08:13:57
Resolution: Fixed Closed By: dkf
    Closed on: 2015-05-14 08:13:57
Description:
 http::geturl returns "data error" with TCL >8.6 and RIPE's REST API. 

With TCL 8.5 it works: 

% puts $tcl_version 
8.5 
% package require http 
2.7.5 
% http::geturl http://www.hp.com/index.html 
::http::1 
% http::geturl http://rest.db.ripe.net/search 
::http::2 
% 


With 8.6 it doesn't: 

% puts $tcl_version 
8.6 
% info patchlevel 
8.6.1 
% package require http 
2.8.7 
% http::geturl http://www.hp.com/index.html 
::http::1 
% http::geturl http://rest.db.ripe.net/search 
data error 
% 


People reported same problems with TCL 8.6.2 & 8.6.3 in this thread:
https://groups.google.com/forum/#!topic/comp.lang.tcl/NiIKhFgEUBY
User Comments: dkf added on 2015-05-14 08:13:57:

Fixed; we now prefer the gzip transfer encoding because it's widely known that alternatives are wrong on some servers. It's really not our fault, but we can't help that. The default can be overridden by setting the Accept-Encoding header explicitly (using the normal API mechanism for that); there are examples of what to do in Tcl's test suite (http11.test).

I looked into putting in code that would try to guess from the first few bytes of the stream. We won't be trying to do that! It gets really complicated (in terms of just what to read and when) and just switching to gzip works as well (and it's very widely implemented too). I guess we could have done it with a "do what I mean" decompression method, but that's really horrible.

The fix will ship with the next 8.6 patch release. The workaround is to specify Accept-Encoding to be something like identity, which disables compression and works on 8.5 and 8.6.


dkf added on 2015-05-13 22:59:13:

BTW, the response you're looking for is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><whois-resources xmlns:xlink="http://www.w3.org/1999/xlink"><link xlink:type="locator" xlink:href="http://rest.db.ripe.net/search/"/><errormessages><errormessage severity="Error" text="Query param 'query-string' cannot be empty"/></errormessages><terms-and-conditions xlink:type="locator" xlink:href="http://www.ripe.net/db/support/db-terms-conditions.pdf"/></whois-resources>


dkf added on 2015-05-13 22:55:22:

For more details about what's going on, see this Stack Overflow question and its answers.


dkf added on 2015-05-13 22:48:20:

I vaguely remember seeing somewhere that compressed HTTP transfers should always be done as gzip because of different interpretations of other names in weird ways.

That said, your test is completely bogus. You need to strip the headers first!

If I do that and then use zlib decompress on the rest (not zlib inflate) then I get what appears to be reasonable content. Which agrees with what my first paragraph says; there's breakage in the way that this part of the HTTP specification is interpreted. Interoperable code uses gzip.


dgp added on 2015-05-13 12:24:41:
anyone know what the correct inflated result is?

aspect added on 2015-05-13 03:44:48:
The error is definitely in zlib inflate:

======

set s [socket rest.db.ripe.net 80]
fconfigure $s -translation crlf -buffering line
puts $s "GET /search HTTP/1.1"
puts $s "Host: rest.db.ripe.net"
puts $s "Accept-Encoding: deflate"
puts $s "Connection: close"
puts $s ""
puts $s ""

fconfigure $s -encoding binary -translation binary

set bits [read $s]


puts "got [string length $bits] bytes"
puts [zlib inflate $bits]
======

got 556 bytes
data error
    while executing
"zlib inflate $bits"

dgp added on 2015-05-11 18:34:00:
http://core.tcl.tk/tcl/info/e861cc28b065288e

is the checkin that breaks things.  Still possible
that [zlib] troubles are at the root, but seems more
likely this patch just gets some things wrong.

dgp added on 2015-05-01 14:44:43:
Is this really a [zlib] bug then?

nem (claiming to be Neil Madden) added on 2014-12-11 10:33:05:
As described in the linked c.l.t thread, the problem appears to be due to the response being compressed. Tcl appears unable to decompress it correctly. A workaround is to disable the Accept-Encoding header:

% package require http
2.8.8
% http::geturl http://rest.db.ripe.net/search \
    -headers [list Accept-Encoding ""]
::http::1