1 #ifndef _SQUID_SRC_HTTP_ONEREQUESTPARSER_H
2 #define _SQUID_SRC_HTTP_ONEREQUESTPARSER_H
4 #include "base/RefCount.h"
5 #include "http/forward.h"
6 #include "http/ProtocolVersion.h"
7 #include "http/RequestMethod.h"
8 #include "http/StatusCode.h"
15 #define HTTP_PARSE_NONE 0 // nothing. completely unset state.
16 #define HTTP_PARSE_NEW 1 // initialized, but nothing usefully parsed yet.
17 #define HTTP_PARSE_FIRST 2 // have parsed request first line
18 #define HTTP_PARSE_MIME 3 // have located end of mime header block
19 #define HTTP_PARSE_DONE 99 // have done with parsing so far
21 /** HTTP protocol parser.
23 * Works on a raw character I/O buffer and tokenizes the content into
24 * either an error state or HTTP procotol major sections:
26 * \item first-line (request-line / simple-request / status-line)
27 * \item mime-header block
29 class Parser
: public RefCountable
34 /** Initialize a new parser.
35 * Presenting it a buffer to work on and the current length of available data.
36 * NOTE: This is *not* the buffer size, just the parse-able data length.
37 * The parse routines may be called again later with more data.
39 Parser(const char *aBuf
, int len
) { reset(aBuf
,len
); }
41 /// Set this parser back to a default state.
42 /// Will DROP any reference to a buffer (does not free).
45 /// Reset the parser for use on a new buffer.
46 void reset(const char *aBuf
, int len
);
48 /** Adjust parser state to account for a buffer shift of n bytes.
50 * The leftmost n bytes bytes have been dropped and all other
51 * bytes shifted left n positions.
53 virtual void noteBufferShift(int64_t n
) = 0;
55 /** Whether the parser is already done processing the buffer.
56 * Use to determine between incomplete data and errors results
59 bool isDone() const {return completedState_
==HTTP_PARSE_DONE
;}
61 /// number of bytes in buffer before the message
62 virtual int64_t messageOffset() const = 0;
64 /// size in bytes of the first line including CRLF terminator
65 virtual int64_t firstLineSize() const = 0;
67 /// size in bytes of the message headers including CRLF terminator(s)
68 /// but excluding first-line bytes
69 int64_t headerBlockSize() const {return mimeHeaderBlock_
.length();}
71 /// size in bytes of HTTP message block, includes first-line and mime headers
72 /// excludes any body/entity/payload bytes
73 /// excludes any garbage prefix before the first-line
74 int64_t messageHeaderSize() const {return firstLineSize() + headerBlockSize();}
76 /// buffer containing HTTP mime headers, excluding message first-line.
77 const char *rawHeaderBuf() {return mimeHeaderBlock_
.c_str();}
79 /// attempt to parse a message from the buffer
80 virtual bool parse() = 0;
82 /// the protocol label for this message
83 const AnyP::ProtocolVersion
& messageProtocol() const {return msgProtocol_
;}
86 * \return A pointer to a field-value of the first matching field-name, or NULL.
88 char *getHeaderField(const char *name
);
95 /// what stage the parser is currently up to
96 uint8_t completedState_
;
98 /// what protocol label has been found in the first line
99 AnyP::ProtocolVersion msgProtocol_
;
101 /// byte offset for non-parsed region of the buffer
104 /// buffer holding the mime headers
105 SBuf mimeHeaderBlock_
;
108 /** HTTP protocol request parser.
110 * Works on a raw character I/O buffer and tokenizes the content into
111 * either an error state or, an HTTP procotol request major segments:
113 * \item Request Line (method, URL, protocol, version)
114 * \item Mime header block
116 class RequestParser
: public Http1::Parser
119 /* Http::One::Parser API */
120 RequestParser() : Parser() {}
121 RequestParser(const char *aBuf
, int len
) : Parser(aBuf
, len
) {}
122 virtual void clear();
123 virtual void noteBufferShift(int64_t n
);
124 virtual int64_t messageOffset() const {return req
.start
;}
125 virtual int64_t firstLineSize() const {return req
.end
- req
.start
+ 1;}
126 virtual bool parse();
128 /// the HTTP method if this is a request message
129 const HttpRequestMethod
& method() const {return method_
;}
131 /// the request-line URI if this is a request message, or an empty string.
132 const SBuf
&requestUri() const {return uri_
;}
134 /** HTTP status code to be used on the invalid-request error page
135 * Http::scNone indicates incomplete parse, Http::scOkay indicates no error.
137 Http::StatusCode request_parse_status
;
140 bool skipGarbageLines();
141 int parseRequestFirstLine();
143 /// Offsets for pieces of the (HTTP request) Request-Line as per RFC 2616
144 struct request_offsets
{
146 int m_start
, m_end
; // method
147 int u_start
, u_end
; // url
148 int v_start
, v_end
; // version (full text)
151 /// what request method has been found on the first line
152 HttpRequestMethod method_
;
154 /// raw copy of the origina client reqeust-line URI field
161 #endif /* _SQUID_SRC_HTTP_HTTP1PARSER_H */