Hello all,
I found myself interacting with a HTTP server that returns 100 Continue responses to HTTP POST requests. The pike HTTP client treats those as the final response, but they’re are meant to be considered intermediate responses. I couldn’t figure out if there was a way to get it to continue past that, and it doesn’t look like there is. The standard says a server shouldn’t send them if they aren’t requested, but also says that clients must treat them as informational and carry on.
I have a proposed fix, but since that’s a messing with a pretty widely used bit of code, I wanted to get feedback before I start making changes. I don’t know if there are other similar scenarios that this fix doesn’t cover; I’d be happy to hear feedback on that as well.
In Protocols.pmod/HTTP.pmod/Query.pike, following this line:
int bytes_read = sscanf(headerbuf,"%s%*[ ]%d%*[ ]%s%*[\r]",protocol,status,status_desc);
add:
// we don't expect continue responses, but we must deal with them,
// and treat them as informational
if(status == 100) {
int q = sizeof(headerbuf);
// find the end of the response message, and move past the newlines present.
// since the whole request has been sent already, we just have to wait for the response,
// if it isn’t already in the buffer. Either way, there should be trailing line endings,
// as those were required to be present for us to have gotten this far.
while(q < sizeof(buf)) {
if(buf[q] == '\n' || buf[q] == 'r') continue;
break;
}
// reset the buffer to the point just past the continue response and start over.
buf = buf[q+1..];
// a better approach might be a do-while loop, but this is a bit clearer,
// and we shouldn't find ourselves recursing more than once.
return ponder_answer();
}
I think this affects all versions of pike (certainly 8.x and 9.x).
Thanks in advance!
Bill