Exemplo n.º 1
0
static int header_initial_cmp (Slrn_Header_Type **unsorted, Slrn_Header_Type **sorted) /*{{{*/
{
    return header_cmp(Sort_Functions, unsorted, sorted);
}
Exemplo n.º 2
0
static int header_thread_cmp (Slrn_Header_Type **unsorted, Slrn_Header_Type **sorted) /*{{{*/
{
    return header_cmp(Sort_Thread_Functions, unsorted, sorted);
}
Exemplo n.º 3
0
static inline int header_lookup(struct mk_http_parser *p, char *buffer)
{
    int i;
    int len;
    int pos;
    long val;
    char *endptr;
    char *tmp;

    struct mk_http_header *header;
    struct mk_http_header *header_extra;
    struct row_entry *h;

    len = (p->header_sep - p->header_key);

    for (i = p->header_min; i <= p->header_max; i++) {
        h = &mk_headers_table[i];

        /* Check string length first */
        if (h->len != len) {
            continue;
        }

        if (header_cmp(h->name + 1, buffer + p->header_key + 1, len - 1) == 0) {
            /* We got a header match, register the header index */
            header = &p->headers[i];
            header->type = i;
            header->key.data = buffer + p->header_key;
            header->key.len  = len;
            header->val.data = buffer + p->header_val;
            header->val.len  = p->end - p->header_val;
            p->header_count++;
            mk_list_add(&header->_head, &p->header_list);

            if (i == MK_HEADER_HOST) {
                /* Handle a possible port number in the Host header */
                int sep = str_searchr(header->val.data, ':', header->val.len);
                if (sep > 0) {
                    int plen;
                    short int port_size = 6;
                    char port[port_size];

                    plen = header->val.len - sep - 1;
                    if (plen <= 0 || plen >= port_size) {
                        return -MK_CLIENT_BAD_REQUEST;
                    }
                    memcpy(&port, header->val.data + sep + 1, plen);
                    port[plen] = '\0';

                    errno = 0;
                    val = strtol(port, &endptr, 10);
                    if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
                        || (errno != 0 && val == 0)) {
                        return -MK_CLIENT_BAD_REQUEST;
                    }

                    if (endptr == port || *endptr != '\0') {
                        return -MK_CLIENT_BAD_REQUEST;
                    }

                    p->header_host_port = val;

                    /* Re-set the Host header value without port */
                    header->val.len = sep;
                }
            }
            else if (i == MK_HEADER_CONTENT_LENGTH) {
                errno = 0;
                val = strtol(header->val.data, &endptr, 10);
                if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
                    || (errno != 0 && val == 0)) {
                    return -MK_CLIENT_REQUEST_ENTITY_TOO_LARGE;
                }
                if (endptr == header->val.data) {
                    return -1;
                }
                if (val < 0) {
                    return -1;
                }

                p->header_content_length = val;
            }
            else if (i == MK_HEADER_CONNECTION) {
                /* Check Connection: Keep-Alive */
                if (header->val.len == sizeof(MK_CONN_KEEP_ALIVE) - 1) {
                    if (header_cmp(MK_CONN_KEEP_ALIVE,
                                   header->val.data,
                                   header->val.len ) == 0) {
                        p->header_connection = MK_HTTP_PARSER_CONN_KA;
                    }
                }
                /* Check Connection: Close */
                else if (header->val.len == sizeof(MK_CONN_CLOSE) -1) {
                    if (header_cmp(MK_CONN_CLOSE,
                                   header->val.data, header->val.len) == 0) {
                        p->header_connection = MK_HTTP_PARSER_CONN_CLOSE;
                    }
                }
                else {
                    p->header_connection = MK_HTTP_PARSER_CONN_UNKNOWN;

                    /* Try to find some known values */

                    /* Connection: upgrade */
                    pos = mk_string_search_n(header->val.data,
                                             "Upgrade",
                                             MK_STR_INSENSITIVE,
                                             header->val.len);
                    if (pos >= 0) {
                        p->header_connection = MK_HTTP_PARSER_CONN_UPGRADE;
                    }

                    /* Connection: HTTP2-Settings */
                    pos = mk_string_search_n(header->val.data,
                                             "HTTP2-Settings",
                                             MK_STR_INSENSITIVE,
                                             header->val.len);
                    if (pos >= 0) {
                        p->header_connection |= MK_HTTP_PARSER_CONN_HTTP2_SE;
                    }
                }
            }
            else if (i == MK_HEADER_UPGRADE) {
                    if (header_cmp(MK_UPGRADE_H2C,
                                   header->val.data, header->val.len) == 0) {
                        p->header_upgrade = MK_HTTP_PARSER_UPGRADE_H2C;
                    }
            }

            return 0;
        }
    }

    /*
     * The header_lookup did not match any known header, so we register this
     * entry into the headers_extra array.
     */
    if (p->headers_extra_count < MK_HEADER_EXTRA_SIZE) {
        header_extra = &p->headers_extra[p->headers_extra_count];
        header_extra->key.data = tmp = (buffer + p->header_key);
        header_extra->key.len  = len;

        /* Transform the header key string to lowercase */
        for (i = 0; i < len; i++) {
            tmp[i] = tolower(tmp[i]);
        }

        header_extra->val.data = buffer + p->header_val;
        header_extra->val.len  = p->end - p->header_val;
        p->headers_extra_count++;
        p->header_count++;
        mk_list_add(&header_extra->_head, &p->header_list);
        return 0;
    }

    /*
     * Header is unknown and we cannot store it on our extra headers
     * list as it's already full. Request is too large.
     */
    return -MK_CLIENT_REQUEST_ENTITY_TOO_LARGE;
}