keith 01/09/10 11:32:36 Modified: jk/java/org/apache/ajp Ajp13.java jk/native/apache-1.3 mod_jk.c jk/native/common jk_ajp_common.c jk_service.h jk_util.c Log: Port chunked encoding input support from jakarta-tomcat ajp13. Revision Changes Path 1.10 +19 -5 jakarta-tomcat-connectors/jk/java/org/apache/ajp/Ajp13.java Index: Ajp13.java =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/java/org/apache/ajp/Ajp13.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- Ajp13.java 2001/08/27 15:33:04 1.9 +++ Ajp13.java 2001/09/10 18:32:36 1.10 @@ -209,7 +209,9 @@ byte []bodyBuff = new byte[MAX_READ_SIZE]; int blen; // Length of current chunk of body data in buffer - int pos; // Current read position within that buffer + int pos; // Current read position within that buffer + + boolean end_of_stream; // true if we've received an empty packet public Ajp13() { super(); @@ -231,7 +233,8 @@ // This is a touch cargo-cultish, but I think wise. blen = 0; - pos = 0; + pos = 0; + end_of_stream = false; } /** @@ -437,7 +440,7 @@ // Check to see if there should be a body packet coming along // immediately after - if(req.getContentLength() > 0) { + if(req.getContentLength() != 0) { /* Read present data */ int err = receive(inBuf); @@ -522,7 +525,7 @@ return len; } - // Not enough data (blen < pos + len) + // Not enough data (blen < pos + len) or chunked encoded int toCopy = len; while(toCopy > 0) { int bytesRemaining = blen - pos; @@ -559,7 +562,10 @@ } // If the server returns an empty packet, assume that that end of - // the stream has been reached (yuck -- fix protocol??). + // the stream has been reached (yuck -- fix protocol??). + if (end_of_stream) { + return false; + } // Why not use outBuf?? inBuf.reset(); @@ -572,6 +578,14 @@ throw new IOException(); } + // No data received. + if( inBuf.getLen() == 0 ) { + pos=0; + blen=0; + end_of_stream = true; + return false; + } + blen = inBuf.peekInt(); pos = 0; inBuf.getBytes(bodyBuff); 1.14 +23 -10 jakarta-tomcat-connectors/jk/native/apache-1.3/mod_jk.c Index: mod_jk.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/apache-1.3/mod_jk.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- mod_jk.c 2001/09/04 13:04:03 1.13 +++ mod_jk.c 2001/09/10 18:32:36 1.14 @@ -275,15 +275,18 @@ if(s && s->ws_private && b && actually_read) { apache_private_data_t *p = s->ws_private; if(!p->read_body_started) { - if(!ap_setup_client_block(p->r, REQUEST_CHUNKED_DECHUNK)) { - if(ap_should_client_block(p->r)) { - p->read_body_started = JK_TRUE; - } + if(ap_should_client_block(p->r)) { + p->read_body_started = JK_TRUE; } } - if(p->read_body_started) { - *actually_read = ap_get_client_block(p->r, b, len); + 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; } } @@ -457,7 +460,9 @@ s->server_software = (char *)ap_get_server_version(); s->method = (char *)r->method; - s->content_length = get_content_length(r); + s->content_length = get_content_length(r); + s->is_chunked = r->read_chunked; + s->no_more_chunks = 0; s->query_string = r->args; /* @@ -945,10 +950,17 @@ { /* Retrieve the worker name stored by jk_translate() */ const char *worker_name = ap_table_get(r->notes, JK_WORKER_ID); + 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(worker_name) { jk_server_conf_t *conf = @@ -978,7 +990,8 @@ int is_recoverable_error = JK_FALSE; rc = end->service(end, &s, l, &is_recoverable_error); - if (s.content_read < s.content_length) { + if (s.content_read < s.content_length || + (s.is_chunked && ! s.no_more_chunks)) { /* * If the servlet engine didn't consume all of the * request data, consume and discard all further 1.9 +35 -15 jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c Index: jk_ajp_common.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_ajp_common.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- jk_ajp_common.c 2001/08/27 15:33:04 1.8 +++ jk_ajp_common.c 2001/09/10 18:32:36 1.9 @@ -687,6 +687,10 @@ unsigned len) { unsigned rdlen = 0; + + if (s->is_chunked && s->no_more_chunks) { + return 0; + } while(rdlen < len) { unsigned this_time = 0; @@ -695,6 +699,9 @@ } if(0 == this_time) { + if (s->is_chunked) { + s->no_more_chunks = 1; /* read no more */ + } break; } rdlen += this_time; @@ -705,13 +712,14 @@ /* - * Read data from AJP13/AJP14 protocol + * Read data from AJP13/AJP14 protocol + * Returns -1 on error, else number of bytes read */ static int ajp_read_into_msg_buff(ajp_endpoint_t *ae, jk_ws_service_t *r, jk_msg_buf_t *msg, - unsigned len, + unsigned len, jk_logger_t *l) { unsigned char *read_buf = jk_b_get_buff(msg); @@ -721,21 +729,33 @@ read_buf += AJP_HEADER_LEN; /* leave some space for the buffer headers */ read_buf += AJP_HEADER_SZ_LEN; /* leave some space for the read length */ - if (ajp_read_fully_from_server(r, read_buf, len) < 0) { + /* Pick the max size since we don't know the content_length */ + if (r->is_chunked && len == 0) { + len = AJP13_MAX_SEND_BODY_SZ; + } + + if ((len = ajp_read_fully_from_server(r, read_buf, len)) < 0) { jk_log(l, JK_LOG_ERROR, "ajp_read_into_msg_buff: Error - ajp_read_fully_from_server failed\n"); - return JK_FALSE; + return -1; } - - ae->left_bytes_to_send -= len; - - if(0 != jk_b_append_int(msg, (unsigned short)len)) { - jk_log(l, JK_LOG_ERROR, "ajp_read_into_msg_buff: Error - jk_b_append_int failed\n"); - return JK_FALSE; + + if (!r->is_chunked) { + ae->left_bytes_to_send -= len; + } + + if (len > 0) { + /* Recipient recognizes empty packet as end of stream, not + an empty body packet */ + if(0 != jk_b_append_int(msg, (unsigned short)len)) { + jk_log(l, JK_LOG_ERROR, + "read_into_msg_buff: Error - jk_b_append_int failed\n"); + return -1; + } } jk_b_set_len(msg, jk_b_get_len(msg) + len); - return JK_TRUE; + return len; } @@ -817,11 +837,11 @@ * for resend if the remote Tomcat is down, a fact we will learn only * doing a read (not yet) */ - if (ae->left_bytes_to_send > 0) { + if (s->is_chunked || ae->left_bytes_to_send > 0) { unsigned len = ae->left_bytes_to_send; if (len > AJP13_MAX_SEND_BODY_SZ) len = AJP13_MAX_SEND_BODY_SZ; - if (! ajp_read_into_msg_buff(ae, s, op->post, len, l)) { + if ((len = ajp_read_into_msg_buff(ae, s, op->post, len, l)) < 0) { /* the browser stop sending data, no need to recover */ op->recoverable = JK_FALSE; return JK_FALSE; @@ -893,7 +913,7 @@ } /* the right place to add file storage for upload */ - if (ajp_read_into_msg_buff(ae, r, msg, len, l)) { + if ((len = ajp_read_into_msg_buff(ae, r, msg, len, l)) >= 0) { r->content_read += len; return JK_AJP13_HAS_RESPONSE; } 1.8 +5 -3 jakarta-tomcat-connectors/jk/native/common/jk_service.h Index: jk_service.h =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_service.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- jk_service.h 2001/07/03 21:56:48 1.7 +++ jk_service.h 2001/09/10 18:32:36 1.8 @@ -169,8 +169,10 @@ unsigned server_port; char *server_software; unsigned content_length; /* integer that represents the content */ - /* length should be 0 if unknown. */ - unsigned content_read; + /* length should be 0 if unknown. */ + unsigned is_chunked; /* 1 if content length is unknown (chunked rq) */ + unsigned no_more_chunks; /* 1 if last chunk has been read */ + unsigned content_read; /* number of bytes read */ /* * SSL information 1.7 +4 -2 jakarta-tomcat-connectors/jk/native/common/jk_util.c Index: jk_util.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native/common/jk_util.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- jk_util.c 2001/09/05 17:05:23 1.6 +++ jk_util.c 2001/09/10 18:32:36 1.7 @@ -749,7 +749,9 @@ s->server_name = NULL; s->server_port = 80; s->server_software = NULL; - s->content_length = 0; + s->content_length = 0; + s->is_chunked = 0; + s->no_more_chunks = 0; s->content_read = 0; s->is_ssl = JK_FALSE; s->ssl_cert = NULL;