Esempio n. 1
0
/* It parse data sent by POST or PUT methods */
int mk_method_parse_data(struct client_session *cs, struct session_request *sr)
{
    mk_pointer tmp;
    long content_length_post = 0;

    content_length_post = mk_method_validate_content_length(cs->body, cs->body_length);

    /* Length Required */
    if (content_length_post == -1) {
        mk_request_error(MK_CLIENT_LENGTH_REQUIRED, cs, sr);
        return -1;
    }

    /* Bad request */
    if (content_length_post <= 0) {
        mk_request_error(MK_CLIENT_BAD_REQUEST, cs, sr);
        return -1;
    }

    /* Content length too large */
    if (content_length_post >= cs->body_size) {
        mk_request_error(MK_CLIENT_REQUEST_ENTITY_TOO_LARGE, cs, sr);
        return -1;
    }

    tmp = mk_request_header_get(&sr->headers_toc, 
                                mk_rh_content_type.data,
                                mk_rh_content_type.len);
    if (!tmp.data) {
        mk_request_error(MK_CLIENT_BAD_REQUEST, cs, sr);
        return -1;
    }
    sr->content_type = tmp;
    sr->content_length = content_length_post;

    return 0;
}
Esempio n. 2
0
/*
 * Check if the client request still has pending data.
 *
 * Return 0 when all parts of the expected data has arrived or -1 when
 * the connection is on a pending status due to HTTP spec.
 *
 * This function is called from request.c :: mk_handler_read(..)
 */
int mk_http_pending_request(struct client_session *cs)
{
    int n;
    char *end;

    if (cs->body_length >= mk_endblock.len) {
        end = (cs->body + cs->body_length) - mk_endblock.len;
    }
    else {
        return -1;
    }

    /* try to match CRLF at the end of the request */
    if (cs->body_pos_end < 0) {
        if (strncmp(end, mk_endblock.data, mk_endblock.len) == 0) {
            cs->body_pos_end = cs->body_length - mk_endblock.len;
        }
        else if ((n = mk_string_search(cs->body, mk_endblock.data, MK_STR_SENSITIVE)) >= 0 ) {
            cs->body_pos_end = n;
        }
        else {
            return -1;
        }
    }

    if (cs->first_method == MK_HTTP_METHOD_UNKNOWN) {
        cs->first_method = mk_http_method_get(cs->body);
    }

    if (cs->first_method == MK_HTTP_METHOD_POST || cs->first_method == MK_HTTP_METHOD_PUT) {
        if (cs->body_pos_end > 0) {
            int content_length;
            int current;

            current = cs->body_length - cs->body_pos_end - mk_endblock.len;
            content_length = mk_method_validate_content_length(cs->body, current);

            MK_TRACE("HTTP DATA %i/%i", current, content_length);

            if (content_length >= config->max_request_size) {
                return 0;
            }

            /* if first block has ended, we need to verify if exists
             * a previous block end, that will means that the POST
             * method has sent the whole information.
             * just for ref: pipelining is not allowed with POST
             */
            if ((unsigned int) cs->body_pos_end == cs->body_length - mk_endblock.len) {
                /* Content-length is required, if is it not found,
                 * we pass as successful in order to raise the error
                 * later
                 */
                if (content_length <= 0) {
                    cs->status = MK_REQUEST_STATUS_COMPLETED;
                    return 0;
                }
                else {
                    return -1;
                }
            }
            else {
                if (current < content_length) {
                    return -1;
                }
                else {
                    cs->status = MK_REQUEST_STATUS_COMPLETED;
                    return 0;
                }
            }
        }
        else {
            return -1;
        }
    }

    cs->status = MK_REQUEST_STATUS_COMPLETED;
    return 0;
}