-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: HEAD requests return a body #5
Comments
Reposting comment from mailing list in case this is useful: In CBLRouter.java on line 256 HEAD is turned into a GET. That decision turns out to have some ugly implications. Specifically it means that the response to the HEAD request contains a body. Per section 9.4 of RFC 2616 that is explicitly illegal. But lots of illegal things happen all the time. The reason this one matters is that it causes Ektorp to lose its mind. Or maybe it's the StdHttpClient that is losing its mind. Hard to say. But I get the same broken behavior when I use AndroidHttpClient. I have traces below that document the stack losing its mind. I ran exactly the same Ektorp code against Erlang CouchDB and it worked just fine. So this is caused by the behavior of the Android Listener. Note btw, especially in the first request below, that the Android Listener also loses its mind. So I don't know if the HEAD request fix is enough. There might be other evil things going on here. See the traces for details. My plan right now is to try and figure out how to build couchbase-lite-android-core to fix the bug in CBLRouter.java. Then to build the Listener project with the new couchbase lite core and then see if that fixes anything. I'm posting this just in case someone already knows about this and can save me time with statements like: No! Stop! That won't work! :) Or better yet: Yeah, we know, here's the fix! In any case the proof of the evil this causes is below. Also note at the very end of this mail I have the actual code I'm using. Please take a look at the trace below. What do you notice about it? There are at least two errors. The first error is that the Android Listener responded with a response body to a HEAD request. Per section 9.4 of RFC 2616 "The HEAD method is identical to GET except that the server MUST NOT return a message-body in the response." So what is that response body doing there? Now look at the POST. We just did a HEAD request for /test/ that return 200 OK. Now we do a POST to /test/ and we get a 404? There were no other requesters so um... what the heck? Now, please, scroll down past the example. Because it gets worse. HEAD /test/ HTTP/1.1 HTTP/1.1 200 Ok 73 POST /test/ HTTP/1.1 HTTP/1.1 404 Not found 80 I repeated the exact same code, literally no changes. But now see what happened. First, I got a bunch of protocol errors from my sniffer, it complained: 6 [HTTPLint] The HTTP Chunked response body was incomplete; most likely lacking the final 0-size chunk. To see what it's complaining about please look at the trace below. Notice what's happening now. Now the HEAD suddenly doesn't have a response body. Which is good, but um... why was it in the first response? But wait, it gets better. Do you notice that transfer-encoding: chunked? Why is there a transfer encoding on a response with no content? Except... well it sorta does have content. A chunk with 0x73 (aka 115) but nothing attached to it. What's interesting is that if you scroll up and look at the HEAD response above it was also exactly 0x73 bytes. So what seems to be happening is that the server wants to return a response that is 0x73 bytes long but doesn't. Thus producing malformed HTTP. Note, btw, that if you look at the second POST it somehow 'knocked loose' that content but now it's just a completely syntactic mess so the whole connection collapses. Please, just one more scroll! Please scroll past this example. HEAD /test/ HTTP/1.1 HTTP/1.1 200 Ok 73 HTTP/1.1 500 Fiddler - Bad Response [Fiddler] Response Header parsing failed. This can be caused by an illegal HTTP response earlier on this reused server socket-- for instance, a HTTP/304 response which illegally contains a body. Response Data: <plaintext> 7B 22 64 69 73 6B 5F 73 69 7A 65 22 3A 31 30 32 34 30 30 2C 22 75 70 64 {"disk_size":102400,"upd So I try the requests again and now get different errors! 8 [HTTPLint] The HTTP Chunked response body was incomplete; most likely lacking the final 0-size chunk. Now look. Same HEAD requests but now the response really don't have a response body at all. Although it does claim to use transfer-encoding: chunked which isn't good. But look carefully at the POST response. Other than the fact that it completely screwed up the syntax the response is a success!!!!!! I think this is the point where I break down into tears. HEAD /test/ HTTP/1.1 HTTP/1.1 200 Ok POST /test/ HTTP/1.1 {"blogArticleName":"foo","blogArticleContent":"AbcDef!"} HTTP/1.1 201 Created 66
|
Comment from @snej: Sounds like a simple oversight in the Java port; no need for length arguments to convince us! The Objective-C version skips sending the response body if the request is a HEAD (see CBL_Router.m:593 in the current sources) but that probably got lost in translation. Could you file an issue against Couchbase Lite-Android in Github? Just note that HEAD shouldn’t return a body. |
@tahmmee would it be possible to add a test to the REST api tests to detect this issue? |
yeah, just today I noticed that we do not have tests for HEAD request |
The specs don't need to reference HEAD because any resource that supports GET must support HEAD and the behavior is specified by RFC 2616. So HEAD support is 'automatic'. For what it's worth Ektorp uses Head to test if a DB exists. From: Andrei Baranouski [mailto:notifications@github.com] yeah, just today I noticed that we do not have tests for HEAD request — |
@andreibaranouski / @tahmmee seems like we should add a test for correct HEAD behavior on at least a few of the REST api calls. What do you guys think? |
ticket for implementation http://www.couchbase.com/issues/browse/CBQE-1618 |
CBLRouter.java intentionally treats a HEAD as a GET which means a body gets returned which causes all sorts of problems for libraries like Ektorp.
The text was updated successfully, but these errors were encountered: