Пример #1
0
/* Returns 0 on success and nonzero on failure. */
int http_parse_status_line(const char *line, struct http_response *response)
{
    const char *p, *q;

    http_response_init(response);

    /* Version. */
    p = parse_http_version(line, &response->version);
    if (p == line)
        return -1;
    while (*p == ' ')
        p++;

    /* Status code. */
    errno = 0;
    response->code = parse_long(p, (char **) &q);
    if (errno != 0 || q == p)
        return -1;
    p = q;

    /* Reason phrase. */
    while (*p == ' ')
        p++;
    q = p;
    while (!is_crlf(q))
        q++;
    /* We expect that the CRLF ends the string. */
    if (*skip_crlf(q) != '\0')
        return -1;
    response->phrase = mkstr(p, q);

    return 0;
}
Пример #2
0
int parser_handle_status_line(struct http_parser *parser, const char *buf) {
    struct http_parser_status status;

    //printf("got status line \"%s\"\n", buf);

    // Get the first word of the line (HTTP version)
    char *space = strchr(buf, ' ');
    if (!space) {
        fprintf(stderr, "Missing space\n");
        return -1;
    }
    *space = '\0';
    parse_http_version(&status.http_version, (char *)buf);
    buf = space+1;

    // Get the second word of the line (status code)
    space = strchr(buf, ' ');
    if (!space) {
        fprintf(stderr, "Missing second space\n");
        return -1;
    }
    *space = '\0';
    status.code = atoi(buf);
    status.reason = space+1;

    printf("HTTP/%hhi.%hhi %hd %s\n", status.http_version.major_version,
            status.http_version.minor_version, status.code, status.reason);
    parser_callback(parser, on_status, &status);
    return 0;
}
Пример #3
0
static const char* parse_response(const char* buf, const char* buf_end,
				  int* minor_version, int* status,
				  const char** msg, size_t* msg_len,
				  struct phr_header* headers,
				  size_t* num_headers, size_t max_headers,
				  int* ret)
{
  /* parse "HTTP/1.x" */
  if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) {
    return NULL;
  }
  /* skip space */
  if (*buf++ != ' ') {
    *ret = -1;
    return NULL;
  }
  /* parse status code */
  if ((buf = parse_int(buf, buf_end, status, ret)) == NULL) {
    return NULL;
  }
  /* skip space */
  if (*buf++ != ' ') {
    *ret = -1;
    return NULL;
  }
  /* get message */
  if ((buf = get_token_to_eol(buf, buf_end, msg, msg_len, ret)) == NULL) {
    return NULL;
  }
  
  return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
}
Пример #4
0
const char* parse_request(const char* buf, const char* buf_end,
			  const char** method, size_t* method_len,
			  const char** path, size_t* path_len,
			  int* minor_version, struct phr_header* headers,
			  size_t* num_headers, size_t max_headers, int* ret)
{
  /* skip first empty line (some clients add CRLF after POST content) */
  CHECK_EOF();
  if (*buf == '\015') {
    ++buf;
    EXPECT_CHAR('\012');
  } else if (*buf == '\012') {
    ++buf;
  }
  
  /* parse request line */
  ADVANCE_TOKEN(*method, *method_len);
  ++buf;
  ADVANCE_TOKEN(*path, *path_len);
  ++buf;
  if ((buf = parse_http_version(buf, buf_end, minor_version, ret)) == NULL) {
    return NULL;
  }
  if (*buf == '\015') {
    ++buf;
    EXPECT_CHAR('\012');
  } else if (*buf == '\012') {
    ++buf;
  } else {
    *ret = -1;
    return NULL;
  }
  
  return parse_headers(buf, buf_end, headers, num_headers, max_headers, ret);
}
Пример #5
0
static bool parse_request_line(Iterator& it, Request& request)
{
    bool ret = true;
    ret = ret && parse_method(it, request);
    ret = ret && parse_uri(it, request);
    ret = ret && parse_http_version(it, request);
    ret = ret && expect(it, HTTP_DELIMITER);
    return ret;
}
Пример #6
0
// Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
const char* parse_status_line(unsigned char** p)
{
	if (parse_http_version(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_status_code(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_reason_phrase(p))
		return ERR;
	return parse_crlf(p);
}
Пример #7
0
// Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
const char* parse_request_line(unsigned char** p)
{
	if (parse_method(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_request_uri(p))
		return ERR;
	if (parse_space(p))
		return ERR;
	if (parse_http_version(p))
		return ERR;
	return parse_crlf(p);
}
Пример #8
0
Файл: post.c Проект: xtools/xt
void parse_incoming_message_status_line(xt_net_http_post_t *http_post)
{
  assert(http_post);
  char *first_newline;
  char *remaining_message;
  unsigned short line_size;
  char *line;
  char *http_method_string;
  char *resource_path_string;
  char *http_version_string;
  char *strtok_r_char;

  strtok_r_char = NULL;

  remaining_message = http_post->in_buffer
    + http_post->in_buffer_parse_position;

  first_newline = strstr(remaining_message, "\r\n");
  if (first_newline) {
    line_size = first_newline - http_post->in_buffer;
    line = malloc(line_size + 1);
    if (line) {
      memcpy(line, http_post->in_buffer, line_size);
      *(line + line_size) = '\0';

      http_method_string = strtok_r(line, " ", &strtok_r_char);
      resource_path_string = strtok_r(NULL, " ", &strtok_r_char);
      http_version_string = strtok_r(NULL, " ", &strtok_r_char);

      if (http_method_string && resource_path_string && http_version_string) {
        http_post->in_http_method = parse_http_method(http_method_string);
        http_post->in_resource_path = strdup(resource_path_string);
        http_post->in_http_version = parse_http_version(http_version_string);
        http_post->in_buffer_have_status_line = xt_core_bool_true;
        http_post->in_buffer_parse_position += line_size + 2;
      } else {
        printf("http_post received malformed http status line from "
            "client %i\n", http_post->socket);
      }

      free(line);
    } else {
      xt_core_trace("malloc");
    }
  }
}
Пример #9
0
http_request_t *parse_http_request(http_parser_t *parser, const char *data, size_t len)
{
    if (!parser || !data || !len)
        return NULL;

    parser->data = data;
    parser->len = len;

    parser->parse_ptr = (char*)data;

    parse_method(parser);
    parse_char(parser, ' ');
    parse_absolute_path(parser);
    parse_params(parser);
    parse_char(parser, ' ');
    parse_http_version(parser);
    parse_crlf(parser);
    while (parse_message_header(parser) == 0)
        ;

    return &parser->req;
}
Пример #10
0
int http_parse_request_line(const char *line, struct http_request *request)
{
    const char *p, *q;
    struct uri *uri;
    char *uri_s;

    http_request_init(request);

    p = line;
    while (*p == ' ')
        p++;

    /* Method (CONNECT, GET, etc.). */
    q = p;
    while (is_token_char(*q))
        q++;
    if (p == q)
        goto badreq;
    request->method = mkstr(p, q);

    /* URI. */
    p = q;
    while (*p == ' ')
        p++;
    q = p;
    while (*q != '\0' && *q != ' ')
        q++;
    if (p == q)
        goto badreq;
    uri_s = mkstr(p, q);

    /* RFC 2616, section 5.1.1: The method is case-sensitive.
       RFC 2616, section 5.1.2:
         Request-URI    = "*" | absoluteURI | abs_path | authority
       The absoluteURI form is REQUIRED when the request is being made to a
       proxy... The authority form is only used by the CONNECT method. */
    if (strcmp(request->method, "CONNECT") == 0) {
        uri = uri_parse_authority(&request->uri, uri_s);
    } else {
        uri = uri_parse(&request->uri, uri_s);
    }
    free(uri_s);
    if (uri == NULL)
        /* The URI parsing failed. */
        goto badreq;

    /* Version number. */
    p = q;
    while (*p == ' ')
        p++;
    if (*p == '\0') {
        /* No HTTP/X.X version number indicates version 0.9. */
        request->version = HTTP_09;
    } else {
        q = parse_http_version(p, &request->version);
        if (p == q)
            goto badreq;
    }

    return 0;

badreq:
    http_request_free(request);
    return 400;
}
Пример #11
0
int parser_handle_request_line(struct http_parser *parser, const char *buf) {
    struct http_parser_request req;
    char *uri;

    //printf("got request line \"%s\"\n", buf);

    // Get the first word of the line (request method)
    char *first = strchr(buf, ' ');
    if (!first) {
        fprintf(stderr, "Missing space\n");
        return -1;
    }
    *first = '\0';
    req.method = (char *)buf;
    uri = first+1;

    // Get the last word of the line (HTTP version)
    char *last = strrchr(uri, ' ');
    if (last) {
        *last = '\0';
    }
    parse_http_version(&req.http_version, last ? last+1 : NULL);

    // Look for scheme before "://"
    char *colon = strchr(uri, ':');
    if (colon && colon[1] == '/' && colon[2] == '/') {
        *colon = '\0';
        char *scheme = uri;
        uri = colon + 3;
        req.uri.scheme = !strcasecmp("http", scheme)
            ? http_scheme_http
            : http_scheme_other;
    } else {
        // Be lenient and assume http if no scheme is given
        req.uri.scheme = http_scheme_http;
    }

    // Get the hostname, port and path
    char *slash = strchr(uri, '/');
    if (slash && slash != uri) {
        *slash = '\0';
        char *host = uri;
        uri = slash + 1;

        colon = strchr(host, ':');
        if (colon) {
            *colon = '\0';
            req.uri.port = atoi(colon + 1);
        } else {
            req.uri.port = 80;
        }
        req.uri.host = host;
    } else {
        req.uri.host = NULL;
    }

    // Note: the path has initial slash removed
    req.uri.path = uri;

    parser_callback(parser, on_request, &req);
    return 0;
}
Пример #12
0
/**
 * Parses the client request. The request is parsed to properly consume
 * the request data, identifying GET and HEAD HTTP methods. Most of the
 * data read is actually discarded, in the current implementation.
 */
void parse_request(struct parser *p) {
    int r;

    if(!read_socket(p))
        return;

    switch (p->state) {
    case PARSING_START:
        p->mark = 0;
        p->state = PARSING_METHOD;
        debug("parse started");

    case PARSING_METHOD:
        r = parse_request_method(p);
        if (r != PARSING_DONE)
            break;
        p->state = PARSING_URI;
        debug("parsed method: %d", p->request.method);

    case PARSING_URI:
        r = parse_request_uri(p);
        if (r != PARSING_DONE)
            break;
        p->state = PARSING_VERSION;
        debug("parsed uri");

    case PARSING_VERSION:
        r = parse_http_version(p);
        if (r != PARSING_DONE)
            break;
        p->state = PARSING_HEADERS;
        debug("parsed http version");

    case PARSING_HEADERS:
    case PARSING_HEADER_NAME:
    case PARSING_HEADER_NAME_ANY:
    case PARSING_HEADER_VALUE:
    case PARSING_HEADER_CONTENT_LENGTH:
        r = parse_headers(p);
        if (r != PARSING_DONE)
            break;
        p->state = PARSING_BODY;
        debug("parsed headers");
        debug("content-length: %ld", p->request.content_length);

    case PARSING_BODY:
        r = parse_body(p);
        if (r != PARSING_DONE)
            break;
        p->state = PARSING_DONE;
        debug("parsed body");
        return;

    default:
        debug("illegal parser state: %d", p->state);
        p->state = PARSING_ERROR;
        p->error = E_PARSE;
        return;
    }

    if (r == PARSING_ERROR) {
        p->state = PARSING_ERROR;
        if (p->error == E_NONE)
            p->error = E_PARSE;
    }
    return;
}