From: Jim Jagielski Date: Fri, 10 Aug 2007 11:15:40 +0000 (+0000) Subject: Add support of ProxyIOBufferSize for AJP X-Git-Tag: 2.2.5~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58daef03c43c1044f74e1899d4c465ab32ca0f04;p=thirdparty%2Fapache%2Fhttpd.git Add support of ProxyIOBufferSize for AJP git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@564553 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index a6cc74fd246..c69f9ab02da 100644 --- a/STATUS +++ b/STATUS @@ -78,14 +78,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy_ajp: Add support of ProxyIOBufferSize. - Trunk version of patch: - http://svn.apache.org/viewvc?view=rev&rev=467014 - http://svn.apache.org/viewvc?view=rev&revision=467257 - http://svn.apache.org/viewvc?view=rev&revision=510522 - 2.2.x version of patch: - http://people.apache.org/~jim/patches/ProxyIOBufferSize.2.patch - +1: jim, mturk, fuankg PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/modules/proxy/ajp.h b/modules/proxy/ajp.h index 171fb921303..3451a84813a 100644 --- a/modules/proxy/ajp.h +++ b/modules/proxy/ajp.h @@ -131,6 +131,8 @@ struct ajp_msg apr_size_t len; /** The current read position */ apr_size_t pos; + /** The size of the buffer */ + apr_size_t max_size; /** Flag indicating the origing of the message */ int server_side; }; @@ -141,8 +143,10 @@ struct ajp_msg #define AJP13_WS_HEADER 0x1234 #define AJP_HEADER_LEN 4 #define AJP_HEADER_SZ_LEN 2 -#define AJP_MSG_BUFFER_SZ (8*1024) -#define AJP13_MAX_SEND_BODY_SZ (AJP_MSG_BUFFER_SZ - 6) +#define AJP_HEADER_SZ 6 +#define AJP_MSG_BUFFER_SZ 8192 +#define AJP_MAX_BUFFER_SZ 16384 +#define AJP13_MAX_SEND_BODY_SZ (AJP_MAX_BUFFER_SZ - AJP_HEADER_SZ) /** Send a request from web server to container*/ #define CMD_AJP13_FORWARD_REQUEST (unsigned char)2 @@ -335,10 +339,11 @@ apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, * Create an AJP Message from pool * * @param pool memory pool to allocate AJP message from + * @param size size of the buffer to create * @param rmsg Pointer to newly created AJP message * @return APR_SUCCESS or error */ -apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg); +apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg); /** * Recopy an AJP Message to another @@ -405,21 +410,25 @@ apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg); * Build the ajp header message and send it * @param sock backend socket * @param r current request + * @param buffsize max size of the AJP packet. * @uri uri requested uri * @return APR_SUCCESS or error */ apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, + apr_size_t buffsize, apr_uri_t *uri); /** * Read the ajp message and return the type of the message. * @param sock backend socket * @param r current request + * @param buffsize size of the buffer. * @param msg returned AJP message * @return APR_SUCCESS or error */ apr_status_t ajp_read_header(apr_socket_t *sock, request_rec *r, + apr_size_t buffsize, ajp_msg_t **msg); /** diff --git a/modules/proxy/ajp_header.c b/modules/proxy/ajp_header.c index 5d082531f03..a72d47a55e1 100644 --- a/modules/proxy/ajp_header.c +++ b/modules/proxy/ajp_header.c @@ -577,12 +577,13 @@ static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg, */ apr_status_t ajp_send_header(apr_socket_t *sock, request_rec *r, + apr_size_t buffsize, apr_uri_t *uri) { ajp_msg_t *msg; apr_status_t rc; - rc = ajp_msg_create(r->pool, &msg); + rc = ajp_msg_create(r->pool, buffsize, &msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_send_header: ajp_msg_create failed"); @@ -611,6 +612,7 @@ apr_status_t ajp_send_header(apr_socket_t *sock, */ apr_status_t ajp_read_header(apr_socket_t *sock, request_rec *r, + apr_size_t buffsize, ajp_msg_t **msg) { apr_byte_t result; @@ -625,7 +627,7 @@ apr_status_t ajp_read_header(apr_socket_t *sock, } } else { - rc = ajp_msg_create(r->pool, msg); + rc = ajp_msg_create(r->pool, buffsize, msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_read_header: ajp_msg_create failed"); @@ -728,11 +730,11 @@ apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, apr_size_t *len, { apr_status_t rc; - if ((rc = ajp_msg_create(pool, msg)) != APR_SUCCESS) + if ((rc = ajp_msg_create(pool, *len, msg)) != APR_SUCCESS) return rc; ajp_msg_reset(*msg); *ptr = (char *)&((*msg)->buf[6]); - *len = AJP_MSG_BUFFER_SZ-6; + *len = *len - 6; return APR_SUCCESS; } diff --git a/modules/proxy/ajp_msg.c b/modules/proxy/ajp_msg.c index 600fd39e42c..eef2a5381a1 100644 --- a/modules/proxy/ajp_msg.c +++ b/modules/proxy/ajp_msg.c @@ -43,8 +43,8 @@ char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err) rv = apr_palloc(pool, bl); apr_snprintf(rv, bl, "ajp_msg_dump(): %s pos=%" APR_SIZE_T_FMT - " len=%" APR_SIZE_T_FMT " max=%d\n", - err, msg->pos, msg->len, AJP_MSG_BUFFER_SZ); + " len=%" APR_SIZE_T_FMT " max=%" APR_SIZE_T_FMT "\n", + err, msg->pos, msg->len, msg->max_size); bl -= strlen(rv); p = rv + strlen(rv); for (i = 0; i < len; i += 16) { @@ -109,11 +109,11 @@ apr_status_t ajp_msg_check_header(ajp_msg_t *msg, apr_size_t *len) msglen = ((head[2] & 0xff) << 8); msglen += (head[3] & 0xFF); - if (msglen > AJP_MSG_BUFFER_SZ) { + if (msglen > msg->max_size) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "ajp_check_msg_header() incoming message is " - "too big %" APR_SIZE_T_FMT ", max is %d", - msglen, AJP_MSG_BUFFER_SZ); + "too big %" APR_SIZE_T_FMT ", max is %" APR_SIZE_T_FMT, + msglen, msg->max_size); return AJP_ETOBIG; } @@ -147,10 +147,13 @@ apr_status_t ajp_msg_reset(ajp_msg_t *msg) apr_status_t ajp_msg_reuse(ajp_msg_t *msg) { apr_byte_t *buf; + apr_size_t max_size; buf = msg->buf; + max_size = msg->max_size; memset(msg, 0, sizeof(ajp_msg_t)); msg->buf = buf; + msg->max_size = max_size; msg->header_len = AJP_HEADER_LEN; ajp_msg_reset(msg); return APR_SUCCESS; @@ -201,7 +204,7 @@ apr_status_t ajp_msg_append_uint32(ajp_msg_t *msg, apr_uint32_t value) { apr_size_t len = msg->len; - if ((len + 4) > AJP_MSG_BUFFER_SZ) { + if ((len + 4) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_uint32"); } @@ -226,7 +229,7 @@ apr_status_t ajp_msg_append_uint16(ajp_msg_t *msg, apr_uint16_t value) { apr_size_t len = msg->len; - if ((len + 2) > AJP_MSG_BUFFER_SZ) { + if ((len + 2) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_uint16"); } @@ -249,7 +252,7 @@ apr_status_t ajp_msg_append_uint8(ajp_msg_t *msg, apr_byte_t value) { apr_size_t len = msg->len; - if ((len + 1) > AJP_MSG_BUFFER_SZ) { + if ((len + 1) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_uint8"); } @@ -278,7 +281,7 @@ apr_status_t ajp_msg_append_string_ex(ajp_msg_t *msg, const char *value, } len = strlen(value); - if ((msg->len + len + 2) > AJP_MSG_BUFFER_SZ) { + if ((msg->len + len + 2) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_cvt_string"); } @@ -311,7 +314,7 @@ apr_status_t ajp_msg_append_bytes(ajp_msg_t *msg, const apr_byte_t *value, return APR_SUCCESS; /* Shouldn't we indicate an error ? */ } - if ((msg->len + valuelen) > AJP_MSG_BUFFER_SZ) { + if ((msg->len + valuelen) > msg->max_size) { return ajp_log_overflow(msg, "ajp_msg_append_bytes"); } @@ -445,7 +448,7 @@ apr_status_t ajp_msg_get_string(ajp_msg_t *msg, const char **rvalue) status = ajp_msg_get_uint16(msg, &size); start = msg->pos; - if ((status != APR_SUCCESS) || (size + start > AJP_MSG_BUFFER_SZ)) { + if ((status != APR_SUCCESS) || (size + start > msg->max_size)) { return ajp_log_overflow(msg, "ajp_msg_get_string"); } @@ -476,7 +479,7 @@ apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, /* save the current position */ start = msg->pos; - if ((status != APR_SUCCESS) || (size + start > AJP_MSG_BUFFER_SZ)) { + if ((status != APR_SUCCESS) || (size + start > msg->max_size)) { return ajp_log_overflow(msg, "ajp_msg_get_bytes"); } msg->pos += (apr_size_t)size; /* only bytes, no trailer */ @@ -492,10 +495,11 @@ apr_status_t ajp_msg_get_bytes(ajp_msg_t *msg, apr_byte_t **rvalue, * Create an AJP Message from pool * * @param pool memory pool to allocate AJP message from + * @param size size of the buffer to create * @param rmsg Pointer to newly created AJP message * @return APR_SUCCESS or error */ -apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg) +apr_status_t ajp_msg_create(apr_pool_t *pool, apr_size_t size, ajp_msg_t **rmsg) { ajp_msg_t *msg = (ajp_msg_t *)apr_pcalloc(pool, sizeof(ajp_msg_t)); @@ -507,7 +511,7 @@ apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg) msg->server_side = 0; - msg->buf = (apr_byte_t *)apr_palloc(pool, AJP_MSG_BUFFER_SZ); + msg->buf = (apr_byte_t *)apr_palloc(pool, size); /* XXX: This should never happen * In case if the OS cannont allocate 8K of data @@ -523,6 +527,7 @@ apr_status_t ajp_msg_create(apr_pool_t *pool, ajp_msg_t **rmsg) msg->len = 0; msg->header_len = AJP_HEADER_LEN; + msg->max_size = size; *rmsg = msg; return APR_SUCCESS; @@ -543,11 +548,11 @@ apr_status_t ajp_msg_copy(ajp_msg_t *smsg, ajp_msg_t *dmsg) return AJP_EINVAL; } - if (smsg->len > AJP_MSG_BUFFER_SZ) { + if (smsg->len > smsg->max_size) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "ajp_msg_copy(): destination buffer too " - "small %" APR_SIZE_T_FMT ", max size is %d", - smsg->len, AJP_MSG_BUFFER_SZ); + "small %" APR_SIZE_T_FMT ", max size is %" APR_SIZE_T_FMT, + smsg->len, smsg->max_size); return AJP_ETOSMALL; } diff --git a/modules/proxy/ajp_utils.c b/modules/proxy/ajp_utils.c index 17e25bfb78f..5a0e8772690 100644 --- a/modules/proxy/ajp_utils.c +++ b/modules/proxy/ajp_utils.c @@ -31,7 +31,7 @@ apr_status_t ajp_handle_cping_cpong(apr_socket_t *sock, ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "Into ajp_handle_cping_cpong"); - rc = ajp_msg_create(r->pool, &msg); + rc = ajp_msg_create(r->pool, AJP_HEADER_SZ_LEN+1, &msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_handle_cping_cpong: ajp_msg_create failed"); diff --git a/modules/proxy/mod_proxy_ajp.c b/modules/proxy/mod_proxy_ajp.c index 859b837b181..d02b4364d73 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -134,13 +134,24 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, int rv = 0; apr_int32_t conn_poll_fd; apr_pollfd_t *conn_poll; - + proxy_server_conf *psf = + ap_get_module_config(r->server->module_config, &proxy_module); + apr_size_t maxsize = AJP_MSG_BUFFER_SZ; + + if (psf->io_buffer_size_set) + maxsize = psf->io_buffer_size; + if (maxsize > AJP_MAX_BUFFER_SZ) + maxsize = AJP_MAX_BUFFER_SZ; + else if (maxsize < AJP_MSG_BUFFER_SZ) + maxsize = AJP_MSG_BUFFER_SZ; + maxsize = APR_ALIGN(maxsize, 1024); + /* * Send the AJP request to the remote server */ /* send request headers */ - status = ajp_send_header(conn->sock, r, uri); + status = ajp_send_header(conn->sock, r, maxsize, uri); if (status != APR_SUCCESS) { conn->close++; ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, @@ -154,6 +165,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, } /* allocate an AJP message to store the data of the buckets */ + bufsiz = maxsize; status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ @@ -173,7 +185,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, } else { status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, - AJP13_MAX_SEND_BODY_SZ); + maxsize - AJP_HEADER_SZ); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ @@ -226,7 +238,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, /* read the response */ conn->data = NULL; - status = ajp_read_header(conn->sock, r, + status = ajp_read_header(conn->sock, r, maxsize, (ajp_msg_t **)&(conn->data)); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ @@ -252,7 +264,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, conn_poll->desc_type = APR_POLL_SOCKET; conn_poll->desc.s = conn->sock; - bufsiz = AJP13_MAX_SEND_BODY_SZ; + bufsiz = maxsize; for (;;) { switch (result) { case CMD_AJP13_GET_BODY_CHUNK: @@ -267,7 +279,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, - AJP13_MAX_SEND_BODY_SZ); + maxsize - AJP_HEADER_SZ); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_DEBUG, status, r->server, @@ -275,7 +287,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, output_failed = 1; break; } - bufsiz = AJP13_MAX_SEND_BODY_SZ; + bufsiz = maxsize; status = apr_brigade_flatten(input_brigade, buff, &bufsiz); apr_brigade_cleanup(input_brigade); @@ -394,7 +406,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, break; /* read the response */ - status = ajp_read_header(conn->sock, r, + status = ajp_read_header(conn->sock, r, maxsize, (ajp_msg_t **)&(conn->data)); if (status != APR_SUCCESS) { backend_failed = 1;