larryi 01/09/02 19:15:26 Modified: src/native/mod_jk/apache1.3 mod_jk.c src/native/mod_jk/netscape jk_nsapi_plugin.c Log: Update to work with recent changes in Ajp13.java.The absence of a content-length header is interpreted to mean an unknown, but non-zero length. For a zero length body, a content-length header saying so is now required. The init_ws_service() method now adds a content-length header if not present and the length is zero. Revision Changes Path 1.11 +47 -18 jakarta-tomcat/src/native/mod_jk/apache1.3/mod_jk.c Index: mod_jk.c =================================================================== RCS file: /home/cvs/jakarta-tomcat/src/native/mod_jk/apache1.3/mod_jk.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- mod_jk.c 2001/09/01 01:53:25 1.10 +++ mod_jk.c 2001/09/03 02:15:26 1.11 @@ -272,14 +272,14 @@ } } - if(p->read_body_started) { - long rv; - if ((rv = ap_get_client_block(p->r, b, len)) < 0) { - *actually_read = 0; + if(p->read_body_started) { + long rv; + if ((rv = ap_get_client_block(p->r, b, len)) < 0) { + *actually_read = 0; } else { - *actually_read = (unsigned) rv; - } - return JK_TRUE; + *actually_read = (unsigned) rv; + } + return JK_TRUE; } } return JK_FALSE; @@ -457,8 +457,8 @@ s->server_software = (char *)ap_get_server_version(); s->method = (char *)r->method; - s->content_length = get_content_length(r); - s->is_chunked = r->read_chunked; + s->content_length = get_content_length(r); + s->is_chunked = r->read_chunked; s->no_more_chunks = 0; s->query_string = r->args; s->req_uri = r->uri; @@ -515,13 +515,17 @@ s->headers_values = NULL; s->num_headers = 0; if(r->headers_in && ap_table_elts(r->headers_in)) { + BOOL need_content_length_header = (s->content_length == 0); array_header *t = ap_table_elts(r->headers_in); if(t && t->nelts) { int i; table_entry *elts = (table_entry *)t->elts; s->num_headers = t->nelts; - s->headers_names = ap_palloc(r->pool, sizeof(char *) * t->nelts); - s->headers_values = ap_palloc(r->pool, sizeof(char *) * t->nelts); + /* allocate an extra header slot in case we need to add a content-length header */ + s->headers_names = ap_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); + s->headers_values = ap_palloc(r->pool, sizeof(char *) * (t->nelts + 1)); + if(!s->headers_names || !s->headers_values) + return JK_FALSE; for(i = 0 ; i < t->nelts ; i++) { char *hname = ap_pstrdup(r->pool, elts[i].key); s->headers_values[i] = ap_pstrdup(r->pool, elts[i].val); @@ -530,8 +534,31 @@ *hname = tolower(*hname); hname++; } + if(need_content_length_header && + !strncmp(s->headers_values[i],"content-length",14)) { + need_content_length_header = FALSE; + } + } + /* Add a content-length = 0 header if needed. + * Ajp13 assumes an absent content-length header means an unknown, + * but non-zero length body. + */ + if(need_content_length_header) { + s->headers_names[s->num_headers] = "content-length"; + s->headers_values[s->num_headers] = "0"; + s->num_headers++; } } + /* Add a content-length = 0 header if needed.*/ + else if (need_content_length_header) { + s->headers_names = ap_palloc(r->pool, sizeof(char *)); + s->headers_values = ap_palloc(r->pool, sizeof(char *)); + if(!s->headers_names || !s->headers_values) + return JK_FALSE; + s->headers_names[0] = "content-length"; + s->headers_values[0] = "0"; + s->num_headers++; + } } return JK_TRUE; @@ -789,16 +816,17 @@ { /* Retrieve the worker name stored by jk_translate() */ const char *worker_name = ap_table_get(r->notes, JK_WORKER_ID); - int rc; + int rc; if(r->proxyreq) { return HTTP_INTERNAL_SERVER_ERROR; - } - + } + /* Set up r->read_chunked flags for chunked encoding, if present */ - if(rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) { - return rc; - } + if(rc = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) { + return rc; + } + if(worker_name) { jk_server_conf_t *conf = @@ -836,7 +864,8 @@ * If the servlet engine didn't consume all of the * request data, consume and discard all further * characters left to read from client - */ + */ + char *buff = ap_palloc(r->pool, 2048); if (buff != NULL) { int rd; 1.4 +34 -7 jakarta-tomcat/src/native/mod_jk/netscape/jk_nsapi_plugin.c Index: jk_nsapi_plugin.c =================================================================== RCS file: /home/cvs/jakarta-tomcat/src/native/mod_jk/netscape/jk_nsapi_plugin.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- jk_nsapi_plugin.c 2001/06/14 16:49:07 1.3 +++ jk_nsapi_plugin.c 2001/09/03 02:15:26 1.4 @@ -56,7 +56,7 @@ /*************************************************************************** * Description: NSAPI plugin for Netscape servers * * Author: Gal Shachor <[EMAIL PROTECTED]> * - * Version: $Revision: 1.3 $ * + * Version: $Revision: 1.4 $ * ***************************************************************************/ @@ -471,6 +471,8 @@ static int setup_http_headers(nsapi_private_data_t *private_data, jk_ws_service_t *s) { + BOOL need_content_length_header = (s->content_length == 0); + pblock *headers_jar = private_data->rq->headers; int cnt; int i; @@ -483,9 +485,13 @@ } } + s->headers_names = NULL; + s->headers_values = NULL; + s->num_headers = cnt; if(cnt) { - s->headers_names = jk_pool_alloc(&private_data->p, cnt * sizeof(char *)); - s->headers_values = jk_pool_alloc(&private_data->p, cnt * sizeof(char *)); + /* allocate an extra header slot in case we need to add a content-length header */ + s->headers_names = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); + s->headers_values = jk_pool_alloc(&private_data->p, (cnt + 1) * sizeof(char *)); if(s->headers_names && s->headers_values) { for(i = 0, cnt = 0 ; i < headers_jar->hsize ; i++) { @@ -493,18 +499,39 @@ while(h && h->param) { s->headers_names[cnt] = h->param->name; s->headers_values[cnt] = h->param->value; + if(need_content_length_header && + !strncmp(h->param->name,"content-length",14)) { + need_content_length_header = FALSE; + } cnt++; h = h->next; } } + /* Add a content-length = 0 header if needed. + * Ajp13 assumes an absent content-length header means an unknown, + * but non-zero length body. + */ + if(need_content_length_header) { + s->headers_names[cnt] = "content-length"; + s->headers_values[cnt] = "0"; + cnt++; + } s->num_headers = cnt; return JK_TRUE; } } else { - s->num_headers = cnt; - s->headers_names = NULL; - s->headers_values = NULL; - return JK_TRUE; + if (need_content_length_header) { + s->headers_names = jk_pool_alloc(&private_data->p, sizeof(char *)); + s->headers_values = jk_pool_alloc(&private_data->p, sizeof(char *)); + if(s->headers_names && s->headers_values) { + s->headers_names[0] = "content-length"; + s->headers_values[0] = "0"; + s->num_headers++; + return JK_TRUE; + } + } + else + return JK_TRUE; } return JK_FALSE;