Skip to content

Commit

Permalink
Fix WebSocket input buffering.
Browse files Browse the repository at this point in the history
  • Loading branch information
FooBarWidget committed Apr 3, 2013
1 parent 6ba2ecc commit 0190873
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 20 deletions.
5 changes: 3 additions & 2 deletions ext/common/agents/HelperAgent/RequestHandler.h
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -621,7 +621,7 @@ class RequestHandler {
} }
} }


static long long getLongLongOption(const ClientPtr &client, const StaticString &name, long long defaultValue = -1) { static long long getULongLongOption(const ClientPtr &client, const StaticString &name, long long defaultValue = -1) {
ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name); ScgiRequestParser::const_iterator it = client->scgiParser.getHeaderIterator(name);
if (it != client->scgiParser.end()) { if (it != client->scgiParser.end()) {
long long result = stringToULL(it->second); long long result = stringToULL(it->second);
Expand Down Expand Up @@ -1354,6 +1354,7 @@ class RequestHandler {
if (errnoCode == ECONNRESET) { if (errnoCode == ECONNRESET) {
// We might as well treat ECONNRESET like an EOF. // We might as well treat ECONNRESET like an EOF.
// http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket // http://stackoverflow.com/questions/2974021/what-does-econnreset-mean-in-the-context-of-an-af-local-socket
RH_TRACE(client, 3, "Client socket ECONNRESET error; treating it as EOF");
onClientEof(client); onClientEof(client);
} else { } else {
stringstream message; stringstream message;
Expand Down Expand Up @@ -1707,7 +1708,7 @@ class RequestHandler {
* onClientData exits. * onClientData exits.
*/ */
parser.rebuildData(modified); parser.rebuildData(modified);
client->contentLength = getLongLongOption(client, "CONTENT_LENGTH"); client->contentLength = getULongLongOption(client, "CONTENT_LENGTH");
fillPoolOptions(client); fillPoolOptions(client);
if (!client->connected()) { if (!client->connected()) {
return consumed; return consumed;
Expand Down
38 changes: 20 additions & 18 deletions ext/nginx/ContentHandler.c
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ static void abort_request(ngx_http_request_t *r);
static void finalize_request(ngx_http_request_t *r, ngx_int_t rc); static void finalize_request(ngx_http_request_t *r, ngx_int_t rc);




static void static unsigned int
uint_to_str(ngx_uint_t i, u_char *str, ngx_uint_t size) { uint_to_str(ngx_uint_t i, u_char *str, ngx_uint_t size) {
ngx_memzero(str, size); unsigned int len = ngx_snprintf(str, size - 1, "%ui", i) - str;
ngx_snprintf(str, size, "%ui", i); str[len] = '\0';
return len;
} }


static FileType static FileType
Expand Down Expand Up @@ -362,8 +363,8 @@ create_request(ngx_http_request_t *r)
u_char ch; u_char ch;
const char * helper_agent_request_socket_password_data; const char * helper_agent_request_socket_password_data;
unsigned int helper_agent_request_socket_password_len; unsigned int helper_agent_request_socket_password_len;
u_char buf[sizeof("4294967296")]; u_char buf[sizeof("4294967296") + 1];
size_t len, size, key_len, val_len, content_length; size_t len, size, key_len, val_len;
const u_char *app_type_string; const u_char *app_type_string;
size_t app_type_string_len; size_t app_type_string_len;
int server_name_len; int server_name_len;
Expand Down Expand Up @@ -417,15 +418,15 @@ create_request(ngx_http_request_t *r)
* Determine the request header length. * Determine the request header length.
**************************************************/ **************************************************/


/* Length of the Content-Length header. */ len = 0;
if (r->headers_in.content_length_n < 0) {
content_length = 0; /* Length of the Content-Length header. A value of -1 means that the content
} else { * length is unspecified, which is the case for e.g. WebSocket requests. */
content_length = r->headers_in.content_length_n; if (r->headers_in.content_length_n >= 0) {
len += sizeof("CONTENT_LENGTH") +
uint_to_str(r->headers_in.content_length_n, buf, sizeof(buf)) +
1; /* +1 for trailing null */
} }
uint_to_str(content_length, buf, sizeof(buf));
/* +1 for trailing null */
len = sizeof("CONTENT_LENGTH") + ngx_strlen(buf) + 1;


/* DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ /* DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */
len += sizeof("DOCUMENT_ROOT") + context->public_dir.len + 1; len += sizeof("DOCUMENT_ROOT") + context->public_dir.len + 1;
Expand Down Expand Up @@ -615,12 +616,13 @@ create_request(ngx_http_request_t *r)
b->last = ngx_snprintf(b->last, 10, "%ui", len); b->last = ngx_snprintf(b->last, 10, "%ui", len);
*b->last++ = (u_char) ':'; *b->last++ = (u_char) ':';


/* Build CONTENT_LENGTH header. This must always be sent, even if 0. */ if (r->headers_in.content_length_n >= 0) {
b->last = ngx_copy(b->last, "CONTENT_LENGTH", b->last = ngx_copy(b->last, "CONTENT_LENGTH",
sizeof("CONTENT_LENGTH")); sizeof("CONTENT_LENGTH"));


b->last = ngx_snprintf(b->last, 10, "%ui", content_length); b->last = ngx_snprintf(b->last, 10, "%ui", r->headers_in.content_length_n);
*b->last++ = (u_char) 0; *b->last++ = (u_char) 0;
}


/* Build DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */ /* Build DOCUMENT_ROOT, SCRIPT_NAME, RAILS_RELATIVE_URL_ROOT, PATH_INFO and REQUEST_URI. */
b->last = ngx_copy(b->last, "DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")); b->last = ngx_copy(b->last, "DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT"));
Expand Down

0 comments on commit 0190873

Please sign in to comment.