Branch data Line data Source code
1 : : // $Id: HTTP.h 6942 2009-11-16 03:54:08Z vern $
2 : : //
3 : : // See the file "COPYING" in the main distribution directory for copyright.
4 : :
5 : : #ifndef http_h
6 : : #define http_h
7 : :
8 : : #include "TCP.h"
9 : : #include "ContentLine.h"
10 : : #include "MIME.h"
11 : : #include "binpac_bro.h"
12 : : #include "ZIP.h"
13 : :
14 : : enum CHUNKED_TRANSFER_STATE {
15 : : NON_CHUNKED_TRANSFER,
16 : : BEFORE_CHUNK,
17 : : EXPECT_CHUNK_SIZE,
18 : : EXPECT_CHUNK_DATA,
19 : : EXPECT_CHUNK_DATA_CRLF,
20 : : EXPECT_CHUNK_TRAILER,
21 : : EXPECT_NOTHING,
22 : : };
23 : :
24 : : class HTTP_Entity;
25 : : class HTTP_Message;
26 : : class HTTP_Analyzer;
27 : :
28 : : class HTTP_Entity : public MIME_Entity {
29 : : public:
30 : : HTTP_Entity(HTTP_Message* msg, MIME_Entity* parent_entity,
31 : : int expect_body);
32 : 881 : ~HTTP_Entity()
33 : 881 : {
34 : : #ifdef HAVE_LIBZ
35 [ - + ][ # # ]: 881 : if ( zip )
36 [ # # ][ # # ]: 0 : { zip->Done(); delete zip; }
37 : : #endif
38 [ + - ][ # # ]: 881 : }
39 : :
40 : : void EndOfData();
41 : : void Deliver(int len, const char* data, int trailing_CRLF);
42 : : int Undelivered(int len);
43 : 881 : int BodyLength() const { return body_length; }
44 : 881 : int HeaderLength() const { return header_length; }
45 : 0 : void SkipBody() { deliver_body = 0; }
46 : :
47 : : protected:
48 : : class UncompressedOutput;
49 : : friend class UncompressedOutput;
50 : :
51 : : HTTP_Message* http_message;
52 : : int chunked_transfer_state;
53 : : int content_length;
54 : : int expect_data_length;
55 : : int expect_body;
56 : : int body_length;
57 : : int header_length;
58 : : int deliver_body;
59 : : enum { IDENTITY, GZIP, COMPRESS, DEFLATE } encoding;
60 : : #ifdef HAVE_LIBZ
61 : : ZIP_Analyzer* zip;
62 : : #endif
63 : :
64 : 0 : MIME_Entity* NewChildEntity() { return new HTTP_Entity(http_message, this, 1); }
65 : :
66 : : void DeliverBody(int len, const char* data, int trailing_CRLF);
67 : : void DeliverBodyClear(int len, const char* data, int trailing_CRLF);
68 : :
69 : : void SubmitData(int len, const char* buf);
70 : :
71 : : void SetPlainDelivery(int length);
72 : :
73 : : void SubmitHeader(MIME_Header* h);
74 : : void SubmitAllHeaders();
75 : : };
76 : :
77 : : enum {
78 : : HTTP_BODY_NOT_EXPECTED,
79 : : HTTP_BODY_EXPECTED,
80 : : HTTP_BODY_MAYBE,
81 : : };
82 : :
83 : : // Finishing HTTP Messages:
84 : : //
85 : : // HTTP_Entity::SubmitAllHeaders -> EndOfData (no body)
86 : : // HTTP_Entity::Deliver -> EndOfData (end of body)
87 : : // HTTP_Analyzer::Done -> {Request,Reply}Made (connection terminated)
88 : : // {Request,Reply}Made -> HTTP_Message::Done
89 : : // HTTP_Message::Done -> MIME_Message::Done, EndOfData, HTTP_MessageDone
90 : : // MIME_Entity::EndOfData -> Message::EndEntity
91 : : // HTTP_Message::EndEntity -> Message::Done
92 : : // HTTP_MessageDone -> {Request,Reply}Made
93 : :
94 : : class HTTP_Message : public MIME_Message {
95 : : public:
96 : : HTTP_Message(HTTP_Analyzer* analyzer, ContentLine_Analyzer* cl,
97 : : bool is_orig, int expect_body, int init_header_length);
98 : : ~HTTP_Message();
99 : : void Done(const int interrupted, const char* msg);
100 : 881 : void Done() { Done(0, "message ends normally"); }
101 : :
102 : : int Undelivered(int len);
103 : :
104 : : void BeginEntity(MIME_Entity* /* entity */);
105 : : void EndEntity(MIME_Entity* entity);
106 : : void SubmitHeader(MIME_Header* h);
107 : : void SubmitAllHeaders(MIME_HeaderList& /* hlist */);
108 : : void SubmitData(int len, const char* buf);
109 : : int RequestBuffer(int* plen, char** pbuf);
110 : : void SubmitAllData();
111 : : void SubmitEvent(int event_type, const char* detail);
112 : :
113 : : void SubmitTrailingHeaders(MIME_HeaderList& /* hlist */);
114 : : void SetPlainDelivery(int length);
115 : : void SkipEntityData();
116 : :
117 : 15034 : HTTP_Analyzer* MyHTTP_Analyzer() const
118 : 15034 : { return (HTTP_Analyzer*) analyzer; }
119 : :
120 : : void Weird(const char* msg);
121 : 7890 : bool IsOrig() { return is_orig; }
122 : :
123 : : protected:
124 : : HTTP_Analyzer* analyzer;
125 : : ContentLine_Analyzer* content_line;
126 : : bool is_orig;
127 : :
128 : : vector<const BroString*> buffers;
129 : :
130 : : // Controls the total buffer size within http_entity_data_delivery_size.
131 : : int total_buffer_size;
132 : :
133 : : int buffer_offset, buffer_size;
134 : : BroString* data_buffer;
135 : :
136 : : double start_time;
137 : :
138 : : int body_length; // total length of entity bodies
139 : : int header_length; // total length of headers, including the request/reply line
140 : :
141 : : // Total length of content gaps that are "successfully" skipped.
142 : : // Note: this might NOT include all content gaps!
143 : : int content_gap_length;
144 : :
145 : : HTTP_Entity* current_entity;
146 : :
147 : : int InitBuffer(int length);
148 : : void DeliverEntityData();
149 : :
150 : : Val* BuildMessageStat(const int interrupted, const char* msg);
151 : : };
152 : :
153 : : class HTTP_Analyzer : public TCP_ApplicationAnalyzer {
154 : : public:
155 : : HTTP_Analyzer(Connection* conn);
156 : : ~HTTP_Analyzer();
157 : :
158 : : void Undelivered(TCP_Endpoint* sender, int seq, int len);
159 : :
160 : : void HTTP_Header(int is_orig, MIME_Header* h);
161 : : void HTTP_EntityData(int is_orig, const BroString* entity_data);
162 : : void HTTP_MessageDone(int is_orig, HTTP_Message* message);
163 : : void HTTP_Event(const char* category, const char* detail);
164 : : void HTTP_Event(const char* category, StringVal *detail);
165 : :
166 : : void SkipEntityData(int is_orig);
167 : :
168 : : // Overriden from Analyzer.
169 : : virtual void Done();
170 : : virtual void DeliverStream(int len, const u_char* data, bool orig);
171 : : virtual void Undelivered(int seq, int len, bool orig);
172 : 12416 : virtual int RewritingTrace()
173 [ + - ][ - + ]: 12416 : { return rewriting_http_trace || TCP_ApplicationAnalyzer::RewritingTrace(); }
174 : :
175 : : // Overriden from TCP_ApplicationAnalyzer
176 : : virtual void EndpointEOF(bool is_orig);
177 : : virtual void ConnectionFinished(int half_finished);
178 : : virtual void ConnectionReset();
179 : : virtual void PacketWithRST();
180 : :
181 : 684 : static Analyzer* InstantiateAnalyzer(Connection* conn)
182 : 684 : { return new HTTP_Analyzer(conn); }
183 : :
184 : 1 : static bool Available()
185 [ - + ][ # # ]: 1 : { return (http_request || http_reply) && !FLAGS_use_binpac; }
[ + - ]
186 : :
187 : 428 : int IsConnectionClose() { return connection_close; }
188 : :
189 : : protected:
190 : : void GenStats();
191 : :
192 : : int HTTP_RequestLine(const char* line, const char* end_of_line);
193 : : int HTTP_ReplyLine(const char* line, const char* end_of_line);
194 : :
195 : : void InitHTTPMessage(ContentLine_Analyzer* cl, HTTP_Message*& message, bool is_orig,
196 : : int expect_body, int init_header_length);
197 : :
198 : : const char* PrefixMatch(const char* line, const char* end_of_line,
199 : : const char* prefix);
200 : : const char* PrefixWordMatch(const char* line, const char* end_of_line,
201 : : const char* prefix);
202 : :
203 : : int ParseRequest(const char* line, const char* end_of_line);
204 : : double HTTP_Version(int len, const char* data);
205 : :
206 : : void SetVersion(double& version, double new_version);
207 : :
208 [ # # ][ # # ]: 0 : int RequestExpected() const { return num_requests == 0 || keep_alive; }
209 : :
210 : : void HTTP_Request();
211 : : void HTTP_Reply();
212 : :
213 : : void RequestMade(const int interrupted, const char* msg);
214 : : void ReplyMade(const int interrupted, const char* msg);
215 : : void RequestClash(Val* clash_val);
216 : :
217 : : const BroString* UnansweredRequestMethod();
218 : :
219 : : void ParseVersion(data_chunk_t ver, const uint32* host, bool user_agent);
220 : : int HTTP_ReplyCode(const char* code_str);
221 : : int ExpectReplyMessageBody();
222 : :
223 : : StringVal* TruncateURI(StringVal* uri);
224 : :
225 : : int request_state, reply_state;
226 : : int num_requests, num_replies;
227 : : int num_request_lines, num_reply_lines;
228 : : double request_version, reply_version;
229 : : int keep_alive;
230 : : int connection_close;
231 : : int request_ongoing, reply_ongoing;
232 : :
233 : : Val* request_method;
234 : :
235 : : // request_URI is in the original form (may contain '%<hex><hex>'
236 : : // sequences).
237 : : Val* request_URI;
238 : :
239 : : // unescaped_URI does not contain escaped sequences.
240 : : Val* unescaped_URI;
241 : :
242 : : std::queue<Val*> unanswered_requests;
243 : :
244 : : int reply_code;
245 : : Val* reply_reason_phrase;
246 : :
247 : : ContentLine_Analyzer* content_line_orig;
248 : : ContentLine_Analyzer* content_line_resp;
249 : :
250 : : HTTP_Message* request_message;
251 : : HTTP_Message* reply_message;
252 : : };
253 : :
254 : : extern int is_reserved_URI_char(unsigned char ch);
255 : : extern int is_unreserved_URI_char(unsigned char ch);
256 : : extern void escape_URI_char(unsigned char ch, unsigned char*& p);
257 : : extern BroString* unescape_URI(const u_char* line, const u_char* line_end,
258 : : Analyzer* analyzer);
259 : :
260 : : #endif
|