• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Derived from:
6 //   mozilla/netwerk/protocol/http/src/nsHttpChunkedDecoder.h
7 // The license block is:
8 /* ***** BEGIN LICENSE BLOCK *****
9  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
10  *
11  * The contents of this file are subject to the Mozilla Public License Version
12  * 1.1 (the "License"); you may not use this file except in compliance with
13  * the License. You may obtain a copy of the License at
14  * http://www.mozilla.org/MPL/
15  *
16  * Software distributed under the License is distributed on an "AS IS" basis,
17  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
18  * for the specific language governing rights and limitations under the
19  * License.
20  *
21  * The Original Code is Mozilla.
22  *
23  * The Initial Developer of the Original Code is
24  * Netscape Communications.
25  * Portions created by the Initial Developer are Copyright (C) 2001
26  * the Initial Developer. All Rights Reserved.
27  *
28  * Contributor(s):
29  *   Darin Fisher <darin@netscape.com> (original author)
30  *
31  * Alternatively, the contents of this file may be used under the terms of
32  * either the GNU General Public License Version 2 or later (the "GPL"), or
33  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
34  * in which case the provisions of the GPL or the LGPL are applicable instead
35  * of those above. If you wish to allow use of your version of this file only
36  * under the terms of either the GPL or the LGPL, and not to allow others to
37  * use your version of this file under the terms of the MPL, indicate your
38  * decision by deleting the provisions above and replace them with the notice
39  * and other provisions required by the GPL or the LGPL. If you do not delete
40  * the provisions above, a recipient may use your version of this file under
41  * the terms of any one of the MPL, the GPL or the LGPL.
42  *
43  * ***** END LICENSE BLOCK ***** */
44 
45 #ifndef NET_HTTP_HTTP_CHUNKED_DECODER_H_
46 #define NET_HTTP_HTTP_CHUNKED_DECODER_H_
47 
48 #include <string>
49 
50 #include "net/base/net_export.h"
51 
52 namespace net {
53 
54 // From RFC2617 section 3.6.1, the chunked transfer coding is defined as:
55 //
56 //   Chunked-Body    = *chunk
57 //                     last-chunk
58 //                     trailer
59 //                     CRLF
60 //   chunk           = chunk-size [ chunk-extension ] CRLF
61 //                     chunk-data CRLF
62 //   chunk-size      = 1*HEX
63 //   last-chunk      = 1*("0") [ chunk-extension ] CRLF
64 //
65 //   chunk-extension = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
66 //   chunk-ext-name  = token
67 //   chunk-ext-val   = token | quoted-string
68 //   chunk-data      = chunk-size(OCTET)
69 //   trailer         = *(entity-header CRLF)
70 //
71 // The chunk-size field is a string of hex digits indicating the size of the
72 // chunk.  The chunked encoding is ended by any chunk whose size is zero,
73 // followed by the trailer, which is terminated by an empty line.
74 //
75 // NOTE: This implementation does not bother to parse trailers since they are
76 // not used on the web.
77 //
78 class NET_EXPORT_PRIVATE HttpChunkedDecoder {
79  public:
80   // The maximum length of |line_buf_| between calls to FilterBuff().
81   // Exposed for tests.
82   static const size_t kMaxLineBufLen;
83 
84   HttpChunkedDecoder();
85 
86   // Indicates that a previous call to FilterBuf encountered the final CRLF.
reached_eof()87   bool reached_eof() const { return reached_eof_; }
88 
89   // Returns the number of bytes after the final CRLF.
bytes_after_eof()90   int bytes_after_eof() const { return bytes_after_eof_; }
91 
92   // Called to filter out the chunk markers from buf and to check for end-of-
93   // file.  This method modifies |buf| inline if necessary to remove chunk
94   // markers.  The return value indicates the final size of decoded data stored
95   // in |buf|.  Call reached_eof() after this method to check if end-of-file
96   // was encountered.
97   int FilterBuf(char* buf, int buf_len);
98 
99  private:
100   // Scans |buf| for the next chunk delimiter.  This method returns the number
101   // of bytes consumed from |buf|.  If found, |chunk_remaining_| holds the
102   // value for the next chunk size.
103   int ScanForChunkRemaining(const char* buf, int buf_len);
104 
105   // Converts string |start| of length |len| to a numeric value.
106   // |start| is a string of type "chunk-size" (hex string).
107   // If the conversion succeeds, returns true and places the result in |out|.
108   static bool ParseChunkSize(const char* start, int len, int* out);
109 
110   // Indicates the number of bytes remaining for the current chunk.
111   int chunk_remaining_;
112 
113   // A small buffer used to store a partial chunk marker.
114   std::string line_buf_;
115 
116   // True if waiting for the terminal CRLF of a chunk's data.
117   bool chunk_terminator_remaining_;
118 
119   // Set to true when FilterBuf encounters the last-chunk.
120   bool reached_last_chunk_;
121 
122   // Set to true when FilterBuf encounters the final CRLF.
123   bool reached_eof_;
124 
125   // The number of extraneous unfiltered bytes after the final CRLF.
126   int bytes_after_eof_;
127 };
128 
129 }  // namespace net
130 
131 #endif  // NET_HTTP_HTTP_CHUNKED_DECODER_H_
132