bool headers_almost_done (int ch, ParserSettings settings) {
if (LF != ch) {
return false;
}
if (0 != (flags & F_TRAILING)) {
/* End of a chunked request */
settings.RaiseOnHeadersComplete(this);
settings.RaiseOnMessageComplete(this);
state = new_message();
return true;
}
nread = 0;
if (0 != (flags & F_UPGRADE) || HttpMethod.HTTP_CONNECT == method) upgrade = true;
/* Here we call the headers_complete callback. This is somewhat
* different than other callbacks because if the user returns 1, we
* will interpret that as saying that this message has no body. This
* is needed for the annoying case of recieving a response to a HEAD
* request.
*/
/* (responses to HEAD request contain a CONTENT-LENGTH header
* but no content)
*
* Consider what to do here: I don't like the idea of the callback
* interface having a different contract in the case of HEAD
* responses. The alternatives would be either to:
*
* a.) require the header_complete callback to implement a different
* interface or
*
* b.) provide an overridden execute(bla, bla, bool
* parsingHeader) implementation ...
*/
/*TODO TODO TODO TODO TODO TODO TODO TODO TODO TODO */
if (null != settings.OnHeadersComplete) {
settings.RaiseOnHeadersComplete(this);
//return;
}
// if (null != settings.on_headers_complete) {
// switch (settings.on_headers_complete.cb(parser)) {
// case 0:
// break;
//
// case 1:
// flags |= F_SKIPBODY;
// break;
//
// default:
// return p - data; /* Error */ // TODO // RuntimeException ?
// }
// }
// Exit, the rest of the connect is in a different protocol.
if (upgrade) {
settings.RaiseOnMessageComplete(this);
return true;
}
if (0 != (flags & F_SKIPBODY)) {
settings.RaiseOnMessageComplete(this);
state = new_message();
} else if (0 != (flags & F_CHUNKED)) {
/* chunked encoding - ignore Content-Length header */
state = State.chunk_size_start;
} else {
if (content_length == 0) {
/* Content-Length header given but zero: Content-Length: 0\r\n */
settings.RaiseOnMessageComplete(this);
state = new_message();
} else if (content_length > 0) {
/* Content-Length header given and non-zero */
state = State.body_identity;
} else {
if (type == ParserType.HTTP_REQUEST || http_should_keep_alive()) {
/* Assume content-length 0 - read the next */
settings.RaiseOnMessageComplete(this);
state = new_message();
} else {
/* Read body until EOF */
state = State.body_identity_eof;
}
}
}
return true;
} // headers_almost_fone