2 * Routines handling protocols with a request/response line, headers,
3 * a blank line, and an optional body.
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
32 #include <epan/strutil.h>
35 #include "req_resp_hdrs.h"
38 * Optionally do reassembly of the request/response line, headers, and body.
41 req_resp_hdrs_do_reassembly(tvbuff_t *tvb, packet_info *pinfo,
42 gboolean desegment_headers, gboolean desegment_body)
47 gint length_remaining, reported_length_remaining;
50 long int content_length;
51 gboolean content_length_found = FALSE;
52 gboolean chunked_encoding = FALSE;
55 * Do header desegmentation if we've been told to.
57 * RFC 2616 defines HTTP messages as being either of the
58 * Request or the Response type
59 * (HTTP-message = Request | Response).
60 * Request and Response are defined as:
61 * Request = Request-Line
64 * | entity-header ) CRLF)
67 * Response = Status-Line
70 * | entity-header ) CRLF)
73 * that's why we can always assume two consecutive line
74 * endings (we allow CR, LF, or CRLF, as some clients
75 * or servers might not use a full CRLF) to mark the end
76 * of the headers. The worst thing that would happen
77 * otherwise would be the packet not being desegmented
78 * or being interpreted as only headers.
80 * RFC 2326 says RTSP works the same way; RFC 3261 says SIP
85 * If header desegmentation is activated, check that all
86 * headers are in this tvbuff (search for an empty line
87 * marking end of headers) or request one more byte (we
88 * don't know how many bytes we'll need, so we just ask
91 if (desegment_headers && pinfo->can_desegment) {
94 next_offset_sav = next_offset;
96 length_remaining = tvb_length_remaining(tvb,
98 reported_length_remaining =
99 tvb_reported_length_remaining(tvb, next_offset);
102 * Request one more byte if there're no
103 * bytes left in the reported data (if there're
104 * bytes left in the reported data, but not in
105 * the available data, requesting more bytes
106 * won't help, as those bytes weren't captured).
108 if (reported_length_remaining < 1) {
109 pinfo->desegment_offset = offset;
110 pinfo->desegment_len = 1;
115 * Request one more byte if we cannot find a
116 * header (i.e. a line end).
118 linelen = tvb_find_line_end(tvb, next_offset,
119 -1, &next_offset, TRUE);
121 length_remaining >= reported_length_remaining) {
123 * Not enough data; ask for one more
126 pinfo->desegment_offset = offset;
127 pinfo->desegment_len = 1;
129 } else if (linelen == 0) {
131 * We found the end of the headers.
137 * Is this a Content-Length or Transfer-Encoding
138 * header? If not, it either means that we are in
139 * a different header line, or that we are
140 * at the end of the headers, or that there
141 * isn't enough data; the two latter cases
142 * have already been handled above.
144 if (desegment_body) {
146 * Check if we've found Content-Length.
148 if (tvb_strncaseeql(tvb, next_offset_sav,
149 "Content-Length:", 15) == 0) {
150 header_val = tvb_get_string(tvb,
151 next_offset_sav + 15,
153 if (sscanf(header_val,
154 "%li", &content_length)
156 content_length_found = TRUE;
158 } else if (tvb_strncaseeql(tvb,
160 "Transfer-Encoding:", 18) == 0) {
162 * Find out if this Transfer-Encoding is
163 * chunked. It should be, since there
164 * really aren't any other types, but
165 * RFC 2616 allows for them.
170 header_val = tvb_get_string(tvb,
171 next_offset_sav + 18, linelen - 18);
173 len = strlen(header_val);
174 /* Skip white space */
175 while (p < header_val + len &&
176 (*p == ' ' || *p == '\t'))
178 if (p <= header_val + len) {
179 if (strncasecmp(p, "chunked", 7)
182 * Don't bother looking
189 chunked_encoding = TRUE;
199 * The above loop ends when we reached the end of the headers, so
200 * there should be content_length bytes after the 4 terminating bytes
201 * and next_offset points to after the end of the headers.
203 if (desegment_body) {
204 if (content_length_found) {
205 /* next_offset has been set to the end of the headers */
206 if (!tvb_bytes_exist(tvb, next_offset, content_length)) {
207 length_remaining = tvb_length_remaining(tvb,
209 reported_length_remaining =
210 tvb_reported_length_remaining(tvb, next_offset);
211 if (length_remaining < reported_length_remaining) {
213 * It's a waste of time asking for more
214 * data, because that data wasn't captured.
218 if (length_remaining == -1)
219 length_remaining = 0;
220 pinfo->desegment_offset = offset;
221 pinfo->desegment_len =
222 content_length - length_remaining;
225 } else if (chunked_encoding) {
227 * This data is chunked, so we need to keep pulling
228 * data until we reach the end of the stream, or a
232 * This doesn't bother with trailing headers; I don't
233 * think they are really used, and we'd have to use
234 * is_http_request_or_reply() to determine if it was
235 * a trailing header, or the start of a new response.
237 gboolean done_chunking = FALSE;
239 while (!done_chunking) {
241 gint chunk_offset = 0;
242 gchar *chunk_string = NULL;
245 length_remaining = tvb_length_remaining(tvb,
247 reported_length_remaining =
248 tvb_reported_length_remaining(tvb,
251 if (reported_length_remaining < 1) {
252 pinfo->desegment_offset = offset;
253 pinfo->desegment_len = 1;
257 linelen = tvb_find_line_end(tvb, next_offset,
258 -1, &chunk_offset, TRUE);
262 reported_length_remaining) {
263 pinfo->desegment_offset = offset;
264 pinfo->desegment_len = 2;
268 /* We have a line with the chunk size in it.*/
269 chunk_string = tvb_get_string(tvb, next_offset,
274 * We don't care about the extensions.
276 if ((c = strchr(c, ';'))) {
280 if ((sscanf(chunk_string, "%x",
281 &chunk_size) < 0) || chunk_size < 0) {
282 /* We couldn't get the chunk size,
288 if (chunk_size == 0) {
290 * This is the last chunk. Let's pull in the
293 linelen = tvb_find_line_end(tvb,
294 chunk_offset, -1, &chunk_offset, TRUE);
298 reported_length_remaining) {
299 pinfo->desegment_offset = offset;
300 pinfo->desegment_len = 1;
304 pinfo->desegment_offset = chunk_offset;
305 pinfo->desegment_len = 0;
306 done_chunking = TRUE;
309 * Skip to the next chunk if we
312 if (reported_length_remaining >
315 next_offset = chunk_offset
319 * Fetch this chunk, plus the
322 pinfo->desegment_offset = offset;
323 pinfo->desegment_len =
325 reported_length_remaining;
336 * No further desegmentation needed.