/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License.
*/
/* ssl_key_size is required by Servlet 2.3 API */ if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r,
AJP13_SSL_KEY_SIZE_INDICATOR))
&& envvar[0]) {
if (ajp_msg_append_uint8(msg, SC_A_SSL_KEY_SIZE)
|| ajp_msg_append_uint16(msg, (unsignedshort) atoi(envvar))) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00979) "ajp_marshal_into_msgb: " "Error appending the SSL key size"); return APR_EGENERAL;
}
}
} /* If the method was unrecognized, encode it as an attribute */ if (method == SC_M_JK_STORED) { if (ajp_msg_append_uint8(msg, SC_A_STORED_METHOD)
|| ajp_msg_append_string(msg, r->method)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02438) "ajp_marshal_into_msgb: " "Error appending the method '%s' as request attribute",
r->method); return AJP_EOVERFLOW;
}
} /* Forward the SSL protocol name. * Modern Tomcat versions know how to retrieve * the protocol name from this attribute.
*/ if (is_ssl) { if ((envvar = ap_proxy_ssl_val(r->pool, r->server, r->connection, r,
AJP13_SSL_PROTOCOL_INDICATOR))
&& envvar[0]) { constchar *key = SC_A_SSL_PROTOCOL; if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
ajp_msg_append_string(msg, key) ||
ajp_msg_append_string(msg, envvar)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02830) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s",
key, envvar); return AJP_EOVERFLOW;
}
}
} /* Forward the remote port information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getRemotePort(), * we provide the port to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the remote port from this attribute.
*/
{ constchar *key = SC_A_REQ_REMOTE_PORT; char *val = apr_itoa(r->pool, r->useragent_addr->port); if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
ajp_msg_append_string(msg, key) ||
ajp_msg_append_string(msg, val)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00980) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s",
key, val); return AJP_EOVERFLOW;
}
} /* Forward the local ip address information, which was forgotten * from the builtin data of the AJP 13 protocol. * Since the servlet spec allows to retrieve it via getLocalAddr(), * we provide the address to the Tomcat connector as a request * attribute. Modern Tomcat versions know how to retrieve * the local address from this attribute.
*/
{ constchar *key = SC_A_REQ_LOCAL_ADDR; char *val = r->connection->local_ip; if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
ajp_msg_append_string(msg, key) ||
ajp_msg_append_string(msg, val)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02646) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s",
key, val); return AJP_EOVERFLOW;
}
} /* Use the environment vars prefixed with AJP_ * and pass it to the header striping that prefix.
*/ for (i = 0; i < (apr_uint32_t)arr->nelts; i++) { if (!strncmp(elts[i].key, "AJP_", 4)) { if (ajp_msg_append_uint8(msg, SC_A_REQ_ATTRIBUTE) ||
ajp_msg_append_string(msg, elts[i].key + 4) ||
ajp_msg_append_string(msg, elts[i].val)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00981) "ajp_marshal_into_msgb: " "Error appending attribute %s=%s",
elts[i].key, elts[i].val); return AJP_EOVERFLOW;
}
}
}
if (ajp_msg_append_uint8(msg, SC_A_ARE_DONE)) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00982) "ajp_marshal_into_msgb: " "Error appending the message end"); return AJP_EOVERFLOW;
}
/* First, tuck away all already existing cookies */ /* * Could optimize here, but just in case we want to * also save other headers, keep this logic.
*/
save_table = apr_table_make(r->pool, num_headers + 2);
apr_table_do(addit_dammit, save_table, r->headers_out, "Set-Cookie", NULL);
r->headers_out = save_table;
} else { /* * Reset headers, but not to NULL because things below the chain expect * this to be non NULL e.g. the ap_content_length_filter.
*/
r->headers_out = apr_table_make(r->pool, 1);
num_headers = 0;
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10405) "ajp_unmarshal_response: Bad number of headers"); return rc;
}
ap_log_rerror(APLOG_MARK, APLOG_TRACE4, 0, r, "ajp_unmarshal_response: Number of headers is = %d",
num_headers);
for (i = 0; i < (int)num_headers; i++) {
apr_uint16_t name; constchar *stringname; constchar *value;
rc = ajp_msg_peek_uint16(msg, &name); if (rc != APR_SUCCESS) { return rc;
}
/* AJP has its own body framing mechanism which we don't * match against any provided Content-Length, so let the * core determine C-L vs T-E based on what's actually sent.
*/ if (!apr_table_get(r->subprocess_env, AP_TRUST_CGILIKE_CL_ENVVAR))
apr_table_unset(r->headers_out, "Content-Length");
apr_table_unset(r->headers_out, "Transfer-Encoding");
return APR_SUCCESS;
}
/* * Build the ajp header message and send it
*/
apr_status_t ajp_send_header(apr_socket_t *sock,
request_rec *r,
apr_size_t buffsize,
apr_uri_t *uri, constchar *secret)
{
ajp_msg_t *msg;
apr_status_t rc;
/* * Read the ajp message and return the type of the message.
*/
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;
apr_status_t rc;
/* parse the body and return data address and length */
apr_status_t ajp_parse_data(request_rec *r, ajp_msg_t *msg,
apr_uint16_t *len, char **ptr)
{
apr_byte_t result;
apr_status_t rc;
apr_uint16_t expected_len;
rc = ajp_msg_get_uint8(msg, &result); if (rc != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00996) "ajp_parse_data: ajp_msg_get_byte failed"); return rc;
} if (result != CMD_AJP13_SEND_BODY_CHUNK) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00997) "ajp_parse_data: wrong type %s (0x%02x) expecting %s (0x%02x)",
ajp_type_str(result), result,
ajp_type_str(CMD_AJP13_SEND_BODY_CHUNK), CMD_AJP13_SEND_BODY_CHUNK); return AJP_EBAD_HEADER;
}
rc = ajp_msg_get_uint16(msg, len); if (rc != APR_SUCCESS) { return rc;
} /* * msg->len contains the complete length of the message including all * headers. So the expected length for a CMD_AJP13_SEND_BODY_CHUNK is * msg->len minus the sum of * AJP_HEADER_LEN : The length of the header to every AJP message. * AJP_HEADER_SZ_LEN : The header giving the size of the chunk. * 1 : The CMD_AJP13_SEND_BODY_CHUNK indicator byte (0x03). * 1 : The last byte of this message always seems to be * 0x00 and is not part of the chunk.
*/
expected_len = msg->len - (AJP_HEADER_LEN + AJP_HEADER_SZ_LEN + 1 + 1); if (*len != expected_len) {
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00998) "ajp_parse_data: Wrong chunk length. Length of chunk is %i," " expected length is %i.", *len, expected_len); return AJP_EBAD_HEADER;
}
*ptr = (char *)&(msg->buf[msg->pos]); return APR_SUCCESS;
}
/* Check the reuse flag in CMD_AJP13_END_RESPONSE */
apr_status_t ajp_parse_reuse(request_rec *r, ajp_msg_t *msg,
apr_byte_t *reuse)
{
apr_byte_t result;
apr_status_t rc;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.