From aab07de155c27a0c80d1a2481b1f53ece0ed5737 Mon Sep 17 00:00:00 2001 From: Jean-Frederic Clere Date: Mon, 23 Oct 2006 15:31:59 +0000 Subject: [PATCH] At support for ProxyIOBufferSize in AJP. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@467014 13f79535-47bb-0310-9956-ffa450edef68 --- modules/proxy/ajp.h | 9 ++++++++- modules/proxy/ajp_header.c | 10 ++++++---- modules/proxy/ajp_msg.c | 33 +++++++++++++++++++-------------- modules/proxy/ajp_utils.c | 2 +- modules/proxy/mod_proxy_ajp.c | 21 ++++++++++++++++----- 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/modules/proxy/ajp.h b/modules/proxy/ajp.h index 011e655f6b..60e503c7cf 100644 --- a/modules/proxy/ajp.h +++ b/modules/proxy/ajp.h @@ -118,6 +118,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; }; @@ -322,10 +324,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 @@ -392,21 +395,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 4f27732644..f48aa37fc7 100644 --- a/modules/proxy/ajp_header.c +++ b/modules/proxy/ajp_header.c @@ -574,12 +574,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"); @@ -608,6 +609,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; @@ -622,7 +624,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"); @@ -725,11 +727,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 61f0135181..db8b6946cc 100644 --- a/modules/proxy/ajp_msg.c +++ b/modules/proxy/ajp_msg.c @@ -44,7 +44,7 @@ char * ajp_msg_dump(apr_pool_t *pool, ajp_msg_t *msg, char *err) 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); + 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); + 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 + 3) > AJP_MSG_BUFFER_SZ) { + if ((msg->len + len + 3) > 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); + smsg->len, smsg->max_size); return AJP_ETOSMALL; } diff --git a/modules/proxy/ajp_utils.c b/modules/proxy/ajp_utils.c index 17e25bfb78..5a0e877269 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 624909924a..d8bbc2070e 100644 --- a/modules/proxy/mod_proxy_ajp.c +++ b/modules/proxy/mod_proxy_ajp.c @@ -133,13 +133,23 @@ 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 = AP_IOBUFSIZE; + + if (psf->io_buffer_size_set) + maxsize = psf->io_buffer_size; + if (maxsize > 65536) + maxsize = 65536; + if (maxsize%1024) + maxize = ((maxsize/1024) + 1 ) * 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, @@ -153,6 +163,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 */ @@ -225,7 +236,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 */ @@ -251,7 +262,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; while (isok) { switch (result) { case CMD_AJP13_GET_BODY_CHUNK: @@ -273,7 +284,7 @@ static int ap_proxy_ajp_request(apr_pool_t *p, request_rec *r, "ap_get_brigade failed"); break; } - bufsiz = AJP13_MAX_SEND_BODY_SZ; + bufsiz = maxsize; status = apr_brigade_flatten(input_brigade, buff, &bufsiz); apr_brigade_cleanup(input_brigade); @@ -379,7 +390,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) { isok = 0; -- 2.40.0