1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
|
/*
* Copyright (C) 2011-2018 Team Kodi
* This file is part of Kodi - https://kodi.tv
*
* SPDX-License-Identifier: GPL-2.0-or-later
* See LICENSES/README.md for more information.
*
* This code implements parsing of HTTP requests.
* This code was written by Steve Hanov in 2009, no copyright is claimed.
* This code is in the public domain.
* Code was taken from http://refactormycode.com/codes/778-an-efficient-http-parser
*/
#pragma once
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
// A class to incrementally parse an HTTP header as it comes in. It
// lets you know when it has received all required bytes, as specified
// by the content-length header (if present). If there is no content-length,
// it will stop reading after the final "\n\r".
//
// Example usage:
//
// HttpParser parser;
// HttpParser::status_t status;
//
// for( ;; ) {
// // read bytes from socket into buffer, break on error
// status = parser.addBytes( buffer, length );
// if ( status != HttpParser::Incomplete ) break;
// }
//
// if ( status == HttpParser::Done ) {
// // parse fully formed http message.
// }
class HttpParser
{
public:
~HttpParser();
enum status_t {
Done,
Error,
Incomplete
};
status_t addBytes( const char* bytes, unsigned len );
const char* getMethod() const;
const char* getUri() const;
const char* getQueryString() const;
const char* getBody() const;
// key should be in lower case when looking up.
const char* getValue( const char* key ) const;
unsigned getContentLength() const;
private:
void parseHeader();
bool parseRequestLine();
std::string _data;
unsigned _headerStart = 0;
unsigned _parsedTo = 0 ;
int _state = 0 ;
unsigned _keyIndex = 0;
unsigned _valueIndex = 0;
unsigned _contentLength = 0;
unsigned _contentStart = 0;
unsigned _uriIndex = 0;
typedef std::vector<unsigned> IntArray;
IntArray _keys;
enum State {
p_request_line=0,
p_request_line_cr=1,
p_request_line_crlf=2,
p_request_line_crlfcr=3,
p_key=4,
p_key_colon=5,
p_key_colon_sp=6,
p_value=7,
p_value_cr=8,
p_value_crlf=9,
p_value_crlfcr=10,
p_content=11, // here we are done parsing the header.
p_error=12 // here an error has occurred and the parse failed.
};
status_t _status = Incomplete ;
};
|