1 #ifndef _SQUID_SRC_Http1Parser_H
2 #define _SQUID_SRC_Http1Parser_H
4 #include "base/RefCount.h"
5 #include "http/ProtocolVersion.h"
6 #include "http/StatusCode.h"
11 #define HTTP_PARSE_NONE 0 // nothing. completely unset state.
12 #define HTTP_PARSE_NEW 1 // initialized, but nothing usefully parsed yet.
13 #define HTTP_PARSE_FIRST 2 // have parsed request first line
14 #define HTTP_PARSE_DONE 99 // have done with parsing so far
16 /** HTTP protocol parser.
18 * Works on a raw character I/O buffer and tokenizes the content into
19 * either an error state or, an HTTP procotol request major segments:
21 * \item Request Line (method, URL, protocol, version)
22 * \item Mime header block
24 class Http1Parser
: public RefCountable
27 typedef RefCount
<Http1Parser
> Pointer
;
29 Http1Parser() { clear(); }
31 /** Initialize a new parser.
32 * Presenting it a buffer to work on and the current length of available
34 * NOTE: This is *not* the buffer size, just the parse-able data length.
35 * The parse routines may be called again later with more data.
37 Http1Parser(const char *aBuf
, int len
) { reset(aBuf
,len
); };
39 /// Set this parser back to a default state.
40 /// Will DROP any reference to a buffer (does not free).
43 /// Reset the parser for use on a new buffer.
44 void reset(const char *aBuf
, int len
);
46 /** Whether the parser is already done processing the buffer.
47 * Use to determine between incomplete data and errors results
48 * from the parse methods.
50 bool isDone() const {return completedState_
==HTTP_PARSE_DONE
;}
52 /// size in bytes of the first line (request-line)
53 /// including CRLF terminator
54 int64_t firstLineSize() const {return req
.end
- req
.start
+ 1;}
56 /// size in bytes of the message headers including CRLF terminator
57 /// but excluding request-line bytes
58 int64_t headerBlockSize() const {return hdr_end
- hdr_start
+ 1;}
60 /// size in bytes of HTTP message block, includes request-line and mime headers
61 /// excludes any body/entity/payload bytes
62 int64_t messageHeaderSize() const {return hdr_end
- req
.start
+ 1;}
64 /// buffer containing HTTP mime headers
66 const char *rawHeaderBuf() {return buf
+ hdr_start
;}
68 /** Attempt to parse a request.
69 * \return true if a valid request was parsed.
70 * \note Use isDone() method to determine between incomplete parse and errors.
72 // TODO: parse more than just the request-line
76 * Attempt to parse the first line of a new request message.
79 * RFC 1945 section 5.1
80 * RFC 2616 section 5.1
82 * Parsing state is stored between calls. However the current implementation
83 * begins parsing from scratch on every call.
84 * The return value tells you whether the parsing state fields are valid or not.
86 * \retval -1 an error occurred. request_parse_status indicates HTTP status result.
87 * \retval 1 successful parse. member fields contain the request-line items
88 * \retval 0 more data is needed to complete the parse
90 int parseRequestFirstLine();
96 /// Offsets for pieces of the (HTTP request) Request-Line as per RFC 2616
97 struct request_offsets
{
99 int m_start
, m_end
; // method
100 int u_start
, u_end
; // url
101 int v_start
, v_end
; // version (full text)
104 /// the protocol label for this message
105 const AnyP::ProtocolVersion
& messageProtocol() const {return msgProtocol_
;}
107 // Offsets for pieces of the MiME Header segment
108 int hdr_start
, hdr_end
;
110 // TODO: Offsets for pieces of the (HTTP reply) Status-Line as per RFC 2616
112 /** HTTP status code to be used on the invalid-request error page
113 * Http::scNone indicates incomplete parse, Http::scOkay indicates no error.
115 Http::StatusCode request_parse_status
;
118 /// byte offset for non-parsed region of the buffer
121 /// what stage the parser is currently up to
122 uint8_t completedState_
;
124 /// what protocol label has been found in the first line
125 AnyP::ProtocolVersion msgProtocol_
;
130 #endif /* _SQUID_SRC_Http1Parser_H */