LCOV - code coverage report
Current view: top level - msus/webserver - request_parser.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 32 35 91.4 %
Date: 2018-01-11 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /*
       2             : START OF LICENSE STUB
       3             :     DeDOS: Declarative Dispersion-Oriented Software
       4             :     Copyright (C) 2017 University of Pennsylvania, Georgetown University
       5             : 
       6             :     This program is free software: you can redistribute it and/or modify
       7             :     it under the terms of the GNU General Public License as published by
       8             :     the Free Software Foundation, either version 3 of the License, or
       9             :     (at your option) any later version.
      10             : 
      11             :     This program is distributed in the hope that it will be useful,
      12             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :     GNU General Public License for more details.
      15             : 
      16             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : END OF LICENSE STUB
      19             : */
      20             : #include "webserver/connection-handler.h"
      21             : #include "logging.h"
      22             : 
      23             : #ifdef __GNUC__
      24             : #define UNUSED __attribute__ ((unused))
      25             : #else
      26             : #define UNUSED
      27             : #endif
      28             : 
      29         144 : static int url_callback(http_parser *parser, const char *at, size_t length) {
      30         144 :     struct parser_state *state = parser->data;
      31         144 :     strncpy(&state->url[state->url_len], at, length);
      32         144 :     state->url[state->url_len + length] = '\0';
      33         144 :     state->url_len += length;
      34         144 :     log(LOG_HTTP_PARSING, "Got URL: %s", state->url);
      35         144 :     return 0;
      36             : }
      37             : 
      38         140 : static int headers_complete_callback(http_parser *parser) {
      39         140 :     struct parser_state *state = parser->data;
      40         140 :     state->headers_complete = 1;
      41         140 :     log(LOG_HTTP_PARSING, "Got end of headers");
      42         140 :     return 0;
      43             : }
      44             : 
      45         858 : static int header_field_or_value_callback(http_parser UNUSED *parser, 
      46             :                                           const char UNUSED *at, 
      47             :                                           size_t UNUSED length) {
      48             : #if LOG_HTTP_PARSING
      49             :     char cpy[length+1];
      50             :     strncpy(cpy, at, length);
      51             :     cpy[length] = '\0'
      52             :     log(LOG_HTTP_PARSING, "Got header field %s", cpy);
      53             : #endif
      54         858 :     return 0;
      55             : }
      56             : 
      57             : 
      58         144 : void init_parser_state(struct parser_state *state) {
      59         144 :     memset(state, 0, sizeof(*state));
      60         144 :     state->settings.on_url = url_callback;
      61         144 :     state->settings.on_header_field = header_field_or_value_callback;
      62         144 :     state->settings.on_header_value = header_field_or_value_callback;
      63         144 :     state->settings.on_headers_complete = headers_complete_callback;
      64         144 :     http_parser_init(&state->parser, HTTP_REQUEST);
      65         144 :     state->parser.data = (void*)state;
      66         144 : }
      67             : 
      68         144 : int parse_http(struct parser_state *state, char *buf, ssize_t bytes) {
      69         144 :     if (state == NULL) {
      70           0 :         log_error("Cannot handle connection with NULL state");
      71           0 :         return WS_ERROR;
      72             :     }
      73             : 
      74         144 :     if (state->headers_complete) {
      75           0 :         log_warn("Parsing even though header is already complete");
      76             :     }
      77             : 
      78         144 :     size_t nparsed = http_parser_execute(&state->parser, &state->settings, 
      79             :                                          buf, bytes);
      80             : 
      81         144 :     if (nparsed != bytes) {
      82           1 :         buf[bytes] = '\0';
      83           1 :         log_error("Error parsing HTTP request %s (rcvd: %d, parsed: %d)",
      84             :                 buf, (int)bytes, (int)nparsed);
      85           1 :         return WS_ERROR;
      86             :     }
      87             : 
      88         143 :     return state->headers_complete && state->url_len ? WS_COMPLETE : WS_INCOMPLETE_READ;
      89             : }
      90             : 

Generated by: LCOV version 1.10