/** * Log an AJP message * * @param request The current request * @param msg AJP Message to dump * @param err error string to display * @return APR_SUCCESS or error */ apr_status_t ajp_msg_log(request_rec *r, ajp_msg_t *msg, char *err) { int level; apr_size_t count; char *buf, *next; apr_status_t rc = APR_SUCCESS; if (APLOGrtrace7(r)) { level = APLOG_TRACE7; count = 1024; if (APLOGrtrace8(r)) { level = APLOG_TRACE8; count = AJP_MAX_BUFFER_SZ; } rc = ajp_msg_dump(r->pool, msg, err, count, &buf); if (rc == APR_SUCCESS) { while ((next = ap_strchr(buf, '\n'))) { *next = '\0'; /* Intentional no APLOGNO */ ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf); buf = next + 1; } /* Intentional no APLOGNO */ ap_log_rerror(APLOG_MARK, level, 0, r, "%s", buf); } } return rc; }
static ngx_int_t ngx_http_ajp_process_header(ngx_http_request_t *r) { u_char *pos, *last, type, reuse; uint16_t length; ngx_int_t rc; ngx_buf_t *buf; ajp_msg_t *msg; ngx_http_ajp_ctx_t *a; ngx_http_upstream_t *u; ngx_http_ajp_loc_conf_t *alcf; a = ngx_http_get_module_ctx(r, ngx_http_ajp_module); alcf = ngx_http_get_module_loc_conf(r, ngx_http_ajp_module); if (a == NULL || alcf == NULL) { return NGX_ERROR; } ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "ngx_http_ajp_process_header: state(%d)", a->state); u = r->upstream; msg = ajp_msg_reuse(&a->msg); buf = msg->buf = &u->buffer; while (buf->pos < buf->last) { ngx_log_error(NGX_LOG_DEBUG, r->connection->log, 0, "ngx_http_ajp_process_header: parse response, " "pos:%p, last:%p", buf->pos, buf->last); /* save the position for returning NGX_AGAIN */ pos = buf->pos; last = buf->last; if (ngx_buf_size(msg->buf) < AJP_HEADER_LEN + 1) { return ngx_http_ajp_move_buffer(r, buf, pos, last); } rc = ajp_msg_parse_begin(msg); if (rc != NGX_OK) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_ajp_process_header: bad header\n" "%s", ajp_msg_dump(r->pool, msg, "bad header")); return NGX_ERROR; } rc = ajp_msg_get_uint8(msg, (u_char *)&type); if (rc != NGX_OK) { return NGX_ERROR; } switch (type) { case CMD_AJP13_GET_BODY_CHUNK: rc = ajp_msg_get_uint16(msg, &length); if (rc == AJP_EOVERFLOW) { return ngx_http_ajp_move_buffer(r, buf, pos, last); } rc = ngx_http_upstream_send_request_body(r, u); if (rc != NGX_OK) { return rc; } break; case CMD_AJP13_SEND_HEADERS: rc = ajp_unmarshal_response(msg, r, alcf); if (rc == NGX_OK) { a->state = ngx_http_ajp_st_response_parse_headers_done; return NGX_OK; } else if (rc == AJP_EOVERFLOW) { a->state = ngx_http_ajp_st_response_recv_headers; /* reinit the headers_int list, the memory may be stale */ ngx_list_reinit(&u->headers_in.headers); /* It's an uncomplete AJP packet, move back to the header * of packet, and parse the header again in next call */ return ngx_http_ajp_move_buffer(r, buf, pos, last); } else { return NGX_ERROR; } break; case CMD_AJP13_SEND_BODY_CHUNK: buf->pos = pos; a->state = ngx_http_ajp_st_response_body_data_sending; /* input_filter function will process these data */ return NGX_OK; case CMD_AJP13_END_RESPONSE: rc = ajp_msg_get_uint8(msg, &reuse); if (rc == AJP_EOVERFLOW) { return ngx_http_ajp_move_buffer(r, buf, pos, last); } ngx_http_ajp_end_response(r, reuse); buf->last_buf = 1; return NGX_OK; default: ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "ngx_http_ajp_process_header: " "bad_packet_type(%d)\n%s", type, ajp_msg_dump(r->pool, msg, "bad type")); return NGX_ERROR; } } return NGX_AGAIN; }