]> git.ipfire.org Git - thirdparty/squid.git/blob - src/http/one/Parser.h
Merged from trunk rev.13445
[thirdparty/squid.git] / src / http / one / Parser.h
1 #ifndef _SQUID_SRC_HTTP_ONE_PARSER_H
2 #define _SQUID_SRC_HTTP_ONE_PARSER_H
3
4 #include "anyp/ProtocolVersion.h"
5 #include "http/one/forward.h"
6 #include "SBuf.h"
7
8 namespace Http {
9 namespace One {
10
11 // Parser states
12 enum ParseState {
13 HTTP_PARSE_NONE, ///< initialized, but nothing usefully parsed yet
14 HTTP_PARSE_FIRST, ///< HTTP/1 message first-line
15 HTTP_PARSE_MIME, ///< HTTP/1 mime-header block
16 HTTP_PARSE_DONE ///< parsed a message header, or reached a terminal syntax error
17 };
18
19 /** HTTP/1.x protocol parser
20 *
21 * Works on a raw character I/O buffer and tokenizes the content into
22 * the major CRLF delimited segments of an HTTP/1 procotol message:
23 *
24 * \item first-line (request-line / simple-request / status-line)
25 * \item mime-header 0*( header-name ':' SP field-value CRLF)
26 */
27 class Parser : public RefCountable
28 {
29 explicit Parser(const Parser&); // do not implement
30 Parser& operator =(const Parser&); // do not implement
31
32 public:
33 typedef SBuf::size_type size_type;
34
35 Parser() { clear(); }
36 virtual ~Parser() {}
37
38 /// Set this parser back to a default state.
39 /// Will DROP any reference to a buffer (does not free).
40 virtual void clear();
41
42 /// attempt to parse a message from the buffer
43 /// \retval true if a full message was found and parsed
44 /// \retval false if incomplete, invalid or no message was found
45 virtual bool parse(const SBuf &aBuf) = 0;
46
47 /** Whether the parser is waiting on more data to complete parsing a message.
48 * Use to distinguish between incomplete data and error results
49 * when parse() returns false.
50 */
51 bool needsMoreData() const {return parsingStage_!=HTTP_PARSE_DONE;}
52
53 /// size in bytes of the first line including CRLF terminator
54 virtual size_type firstLineSize() const = 0;
55
56 /// size in bytes of the message headers including CRLF terminator(s)
57 /// but excluding first-line bytes
58 size_type headerBlockSize() const {return mimeHeaderBlock_.length();}
59
60 /// size in bytes of HTTP message block, includes first-line and mime headers
61 /// excludes any body/entity/payload bytes
62 /// excludes any garbage prefix before the first-line
63 size_type messageHeaderSize() const {return firstLineSize() + headerBlockSize();}
64
65 /// buffer containing HTTP mime headers, excluding message first-line.
66 SBuf mimeHeader() const {return mimeHeaderBlock_;}
67
68 /// the protocol label for this message
69 const AnyP::ProtocolVersion & messageProtocol() const {return msgProtocol_;}
70
71 /**
72 * Scan the mime header block (badly) for a header with teh given name.
73 *
74 * BUG: omits lines when searching for headers with obs-fold or multiple entries.
75 *
76 * BUG: limits output to just 1KB when Squid accepts up to 64KB line length.
77 *
78 * \return A pointer to a field-value of the first matching field-name, or NULL.
79 */
80 char *getHeaderField(const char *name);
81
82 /// the remaining unprocessed section of buffer
83 const SBuf &remaining() const {return buf_;}
84
85 protected:
86 /// RFC 7230 section 2.6 - 7 magic octets
87 static const SBuf Http1magic;
88
89 /// bytes remaining to be parsed
90 SBuf buf_;
91
92 /// what stage the parser is currently up to
93 ParseState parsingStage_;
94
95 /// what protocol label has been found in the first line (if any)
96 AnyP::ProtocolVersion msgProtocol_;
97
98 /// buffer holding the mime headers (if any)
99 SBuf mimeHeaderBlock_;
100 };
101
102 } // namespace One
103 } // namespace Http
104
105 #endif /* _SQUID_SRC_HTTP_ONE_PARSER_H */