]> git.ipfire.org Git - thirdparty/squid.git/blame - src/http/Http1Parser.h
Shuffle request_header_max_size limit checks into RequestParser
[thirdparty/squid.git] / src / http / Http1Parser.h
CommitLineData
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 11namespace Http {
1b51ee7b 12namespace 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 29class Parser : public RefCountable
4c14658e
AJ
30{
31public:
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 81public:
4c14658e
AJ
82 const char *buf;
83 int bufsiz;
74f478f8 84
7322c9dd
AJ
85protected:
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 */
107class RequestParser : public Http1::Parser
108{
109public:
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
128private:
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 */