📄 ajp_header.c
字号:
/* 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, (unsigned short) atoi(envvar))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "Error ajp_marshal_into_msgb - " "Error appending the SSL key size"); return APR_EGENERAL; } } } /* 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_error(APLOG_MARK, APLOG_ERR, 0, r->server, "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_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_marshal_into_msgb: " "Error appending the message end"); return AJP_EOVERFLOW; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_marshal_into_msgb: Done"); return APR_SUCCESS;}/*AJPV13_RESPONSE/AJPV14_RESPONSE:= response_prefix (2) status (short) status_msg (short) num_headers (short) num_headers*(res_header_name header_value) *body_chunk terminator boolean <! -- recycle connection or not -->req_header_name := sc_req_header_name | (string)res_header_name := sc_res_header_name | (string)header_value := (string)body_chunk := length (short) body length*(var binary) */static int addit_dammit(void *v, const char *key, const char *val){ apr_table_addn(v, key, val); return 1;}static apr_status_t ajp_unmarshal_response(ajp_msg_t *msg, request_rec *r, proxy_dir_conf *dconf){ apr_uint16_t status; apr_status_t rc; const char *ptr; apr_uint16_t num_headers; int i; rc = ajp_msg_get_uint16(msg, &status); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_unmarshal_response: Null status"); return rc; } r->status = status; rc = ajp_msg_get_string(msg, &ptr); if (rc == APR_SUCCESS) {#if defined(AS400) || defined(_OSD_POSIX) /* EBCDIC platforms */ ptr = apr_pstrdup(r->pool, ptr); ap_xlate_proto_from_ascii(ptr, strlen(ptr));#endif r->status_line = apr_psprintf(r->pool, "%d %s", status, ptr); } else { r->status_line = NULL; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_unmarshal_response: status = %d", status); rc = ajp_msg_get_uint16(msg, &num_headers); if (rc == APR_SUCCESS) { apr_table_t *save_table; /* 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 { r->headers_out = NULL; num_headers = 0; } ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_unmarshal_response: Number of headers is = %d", num_headers); for(i = 0 ; i < (int) num_headers ; i++) { apr_uint16_t name; const char *stringname; const char *value; rc = ajp_msg_peek_uint16(msg, &name); if (rc != APR_SUCCESS) { return rc; } if ((name & 0XFF00) == 0XA000) { ajp_msg_get_uint16(msg, &name); stringname = long_res_header_for_sc(name); if (stringname == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_unmarshal_response: " "No such sc (%08x)", name); return AJP_EBAD_HEADER; } } else { name = 0; rc = ajp_msg_get_string(msg, &stringname); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_unmarshal_response: " "Null header name"); return rc; }#if defined(AS400) || defined(_OSD_POSIX) ap_xlate_proto_from_ascii(stringname, strlen(stringname));#endif } rc = ajp_msg_get_string(msg, &value); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_unmarshal_response: " "Null header value"); return rc; } /* Set-Cookie need additional processing */ if (!strcasecmp(stringname, "Set-Cookie")) { value = ap_proxy_cookie_reverse_map(r, dconf, value); } /* Location, Content-Location, URI and Destination need additional * processing */ else if (!strcasecmp(stringname, "Location") || !strcasecmp(stringname, "Content-Location") || !strcasecmp(stringname, "URI") || !strcasecmp(stringname, "Destination")) { value = ap_proxy_location_reverse_map(r, dconf, value); }#if defined(AS400) || defined(_OSD_POSIX) ap_xlate_proto_from_ascii(value, strlen(value));#endif ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_unmarshal_response: Header[%d] [%s] = [%s]", i, stringname, value); apr_table_add(r->headers_out, stringname, value); /* Content-type needs an additional handling */ if (strcasecmp(stringname, "Content-Type") == 0) { /* add corresponding filter */ ap_set_content_type(r, apr_pstrdup(r->pool, value)); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_unmarshal_response: ap_set_content_type done"); } } 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){ ajp_msg_t *msg; apr_status_t rc; 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"); return rc; } rc = ajp_marshal_into_msgb(msg, r, uri); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_send_header: ajp_marshal_into_msgb failed"); return rc; } rc = ajp_ilink_send(sock, msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_send_header: ajp_ilink_send failed"); return rc; } return APR_SUCCESS;}/* * 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; if (*msg) { rc = ajp_msg_reuse(*msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_read_header: ajp_msg_reuse failed"); return rc; } } else { 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"); return rc; } } ajp_msg_reset(*msg); rc = ajp_ilink_receive(sock, *msg); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_read_header: ajp_ilink_receive failed"); return rc; } rc = ajp_msg_peek_uint8(*msg, &result); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_read_header: ajp_ilink_received %02x", result); return APR_SUCCESS;}/* parse the msg to read the type */int ajp_parse_type(request_rec *r, ajp_msg_t *msg){ apr_byte_t result; ajp_msg_peek_uint8(msg, &result); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "ajp_parse_type: got %02x", result); return (int) result;}/* parse the header */apr_status_t ajp_parse_header(request_rec *r, proxy_dir_conf *conf, ajp_msg_t *msg){ apr_byte_t result; apr_status_t rc; rc = ajp_msg_get_uint8(msg, &result); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_parse_headers: ajp_msg_get_byte failed"); return rc; } if (result != CMD_AJP13_SEND_HEADERS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_parse_headers: wrong type %02x expecting 0x04", result); return AJP_EBAD_HEADER; } return ajp_unmarshal_response(msg, r, conf);}/* 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_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_parse_data: ajp_msg_get_byte failed"); return rc; } if (result != CMD_AJP13_SEND_BODY_CHUNK) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, "ajp_parse_data: wrong type %02x expecting 0x03", result); 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_error(APLOG_MARK, APLOG_ERR, 0, r->server, "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;}/* * Allocate a msg to send data */apr_status_t ajp_alloc_data_msg(apr_pool_t *pool, char **ptr, apr_size_t *len, ajp_msg_t **msg){ apr_status_t rc; if ((rc = ajp_msg_create(pool, *len, msg)) != APR_SUCCESS) return rc; ajp_msg_reset(*msg); *ptr = (char *)&((*msg)->buf[6]); *len = *len - 6; return APR_SUCCESS;}/* * Send the data message */apr_status_t ajp_send_data_msg(apr_socket_t *sock, ajp_msg_t *msg, apr_size_t len){ msg->buf[4] = (apr_byte_t)((len >> 8) & 0xFF); msg->buf[5] = (apr_byte_t)(len & 0xFF); msg->len += len + 2; /* + 1 XXXX where is '\0' */ return ajp_ilink_send(sock, msg);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -