]>
Commit | Line | Data |
---|---|---|
1b51ee7b AJ |
1 | #ifndef _SQUID_SRC_HTTP_ONEREQUESTPARSER_H |
2 | #define _SQUID_SRC_HTTP_ONEREQUESTPARSER_H | |
4c14658e | 3 | |
25f0d354 | 4 | #include "base/RefCount.h" |
274bd5ad | 5 | #include "http/forward.h" |
5aedd08d | 6 | #include "http/ProtocolVersion.h" |
9ff1b8ca | 7 | #include "http/RequestMethod.h" |
955394ce | 8 | #include "http/StatusCode.h" |
eb1bd364 | 9 | #include "SBuf.h" |
4c14658e | 10 | |
bb86dcd4 | 11 | namespace Http { |
1b51ee7b | 12 | namespace One { |
bb86dcd4 | 13 | |
4c14658e AJ |
14 | // Parser states |
15 | #define HTTP_PARSE_NONE 0 // nothing. completely unset state. | |
16 | #define HTTP_PARSE_NEW 1 // initialized, but nothing usefully parsed yet. | |
b6a7fc85 | 17 | #define HTTP_PARSE_FIRST 2 // have parsed request first line |
f4880526 | 18 | #define HTTP_PARSE_MIME 3 // have located end of mime header block |
87abd755 | 19 | #define HTTP_PARSE_DONE 99 // have done with parsing so far |
4c14658e AJ |
20 | |
21 | /** HTTP protocol parser. | |
22 | * | |
7322c9dd AJ |
23 | * Works on a raw character I/O buffer and separates the content into |
24 | * either an error state or HTTP procotol major sections: | |
4c14658e | 25 | * |
7322c9dd AJ |
26 | * \item first-line (request-line / simple-request / status-line) |
27 | * \item mime-header block | |
4c14658e | 28 | */ |
7322c9dd | 29 | class Parser : public RefCountable |
4c14658e AJ |
30 | { |
31 | public: | |
7322c9dd | 32 | Parser() { clear(); } |
4c14658e AJ |
33 | |
34 | /** Initialize a new parser. | |
7322c9dd | 35 | * Presenting it a buffer to work on and the current length of available data. |
4c14658e AJ |
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. | |
38 | */ | |
7322c9dd | 39 | Parser(const char *aBuf, int len) { reset(aBuf,len); }; |
4c14658e AJ |
40 | |
41 | /// Set this parser back to a default state. | |
42 | /// Will DROP any reference to a buffer (does not free). | |
7322c9dd | 43 | virtual void clear(); |
4c14658e AJ |
44 | |
45 | /// Reset the parser for use on a new buffer. | |
46 | void reset(const char *aBuf, int len); | |
47 | ||
87abd755 AJ |
48 | /** Whether the parser is already done processing the buffer. |
49 | * Use to determine between incomplete data and errors results | |
50 | * from the parse methods. | |
51 | */ | |
52 | bool isDone() const {return completedState_==HTTP_PARSE_DONE;} | |
b6a7fc85 | 53 | |
7322c9dd | 54 | /// size in bytes of the first line |
7e1d6c48 | 55 | /// including CRLF terminator |
7322c9dd | 56 | virtual int64_t firstLineSize() const = 0; |
7e1d6c48 | 57 | |
f4880526 | 58 | /// size in bytes of the message headers including CRLF terminator(s) |
7322c9dd | 59 | /// but excluding first-line bytes |
eb1bd364 | 60 | int64_t headerBlockSize() const {return mimeHeaderBlock_.length();} |
7e1d6c48 | 61 | |
7322c9dd | 62 | /// size in bytes of HTTP message block, includes first-line and mime headers |
7e1d6c48 | 63 | /// excludes any body/entity/payload bytes |
7322c9dd | 64 | /// excludes any garbage prefix before the first-line |
f4880526 | 65 | int64_t messageHeaderSize() const {return firstLineSize() + headerBlockSize();} |
7e1d6c48 | 66 | |
7322c9dd | 67 | /// buffer containing HTTP mime headers, excluding message first-line. |
eb1bd364 | 68 | const char *rawHeaderBuf() {return mimeHeaderBlock_.c_str();} |
7e1d6c48 | 69 | |
7322c9dd AJ |
70 | /// attempt to parse a message from the buffer |
71 | virtual bool parse() = 0; | |
72 | ||
73 | /// the protocol label for this message | |
74 | const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;} | |
afff15b2 | 75 | |
a4181565 AJ |
76 | /** |
77 | * \return A pointer to a field-value of the first matching field-name, or NULL. | |
78 | */ | |
79 | char *getHeaderField(const char *name); | |
80 | ||
4c14658e | 81 | public: |
4c14658e AJ |
82 | const char *buf; |
83 | int bufsiz; | |
74f478f8 | 84 | |
7322c9dd AJ |
85 | protected: |
86 | /// what stage the parser is currently up to | |
87 | uint8_t completedState_; | |
88 | ||
89 | /// what protocol label has been found in the first line | |
90 | AnyP::ProtocolVersion msgProtocol_; | |
91 | ||
92 | /// byte offset for non-parsed region of the buffer | |
93 | size_t parseOffset_; | |
94 | ||
95 | /// buffer holding the mime headers | |
96 | SBuf mimeHeaderBlock_; | |
97 | }; | |
98 | ||
99 | /** HTTP protocol request parser. | |
100 | * | |
101 | * Works on a raw character I/O buffer and tokenizes the content into | |
102 | * either an error state or, an HTTP procotol request major segments: | |
103 | * | |
104 | * \item Request Line (method, URL, protocol, version) | |
105 | * \item Mime header block | |
106 | */ | |
107 | class RequestParser : public Http1::Parser | |
108 | { | |
109 | public: | |
110 | /* Http::One::Parser API */ | |
111 | RequestParser() : Parser() {} | |
112 | RequestParser(const char *aBuf, int len) : Parser(aBuf, len) {} | |
113 | virtual void clear(); | |
114 | virtual int64_t firstLineSize() const {return req.end - req.start + 1;} | |
115 | virtual bool parse(); | |
5aedd08d | 116 | |
9ff1b8ca AJ |
117 | /// the HTTP method if this is a request message |
118 | const HttpRequestMethod & method() const {return method_;} | |
274bd5ad | 119 | |
9ff1b8ca AJ |
120 | /// the request-line URI if this is a request message, or an empty string. |
121 | const SBuf &requestUri() const {return uri_;} | |
5f3cc9a2 | 122 | |
4c14658e | 123 | /** HTTP status code to be used on the invalid-request error page |
955394ce | 124 | * Http::scNone indicates incomplete parse, Http::scOkay indicates no error. |
4c14658e | 125 | */ |
955394ce | 126 | Http::StatusCode request_parse_status; |
b6a7fc85 AJ |
127 | |
128 | private: | |
c11191e0 AJ |
129 | bool skipGarbageLines(); |
130 | int parseRequestFirstLine(); | |
131 | ||
5ff9a17a AJ |
132 | /// Offsets for pieces of the (HTTP request) Request-Line as per RFC 2616 |
133 | struct request_offsets { | |
134 | int start, end; | |
135 | int m_start, m_end; // method | |
136 | int u_start, u_end; // url | |
137 | int v_start, v_end; // version (full text) | |
138 | } req; | |
139 | ||
274bd5ad | 140 | /// what request method has been found on the first line |
9ff1b8ca | 141 | HttpRequestMethod method_; |
f4880526 | 142 | |
5f3cc9a2 AJ |
143 | /// raw copy of the origina client reqeust-line URI field |
144 | SBuf uri_; | |
4c14658e AJ |
145 | }; |
146 | ||
1b51ee7b | 147 | } // namespace One |
bb86dcd4 AJ |
148 | } // namespace Http |
149 | ||
e02d9044 | 150 | #endif /* _SQUID_SRC_HTTP_HTTP1PARSER_H */ |