Esempio n. 1
0
/* 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_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00994)
               "ajp_parse_headers: ajp_msg_get_byte failed");
        return rc;
    }
    if (result != CMD_AJP13_SEND_HEADERS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00995)
               "ajp_parse_headers: wrong type %s (0x%02x) expecting %s (0x%02x)",
               ajp_type_str(result), result,
               ajp_type_str(CMD_AJP13_SEND_HEADERS), CMD_AJP13_SEND_HEADERS);
        return AJP_EBAD_HEADER;
    }
    return ajp_unmarshal_response(msg, r, conf);
}
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;
}