• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 The Chromium Authors
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 <stddef.h>
49 #include <stdint.h>
50 
51 #include <string>
52 
53 #include "base/containers/span.h"
54 #include "net/base/net_export.h"
55 
56 namespace net {
57 
58 // From RFC2617 section 3.6.1, the chunked transfer coding is defined as:
59 //
60 //   Chunked-Body    = *chunk
61 //                     last-chunk
62 //                     trailer
63 //                     CRLF
64 //   chunk           = chunk-size [ chunk-extension ] CRLF
65 //                     chunk-data CRLF
66 //   chunk-size      = 1*HEX
67 //   last-chunk      = 1*("0") [ chunk-extension ] CRLF
68 //
69 //   chunk-extension = *( ";" chunk-ext-name [ "=" chunk-ext-val ] )
70 //   chunk-ext-name  = token
71 //   chunk-ext-val   = token | quoted-string
72 //   chunk-data      = chunk-size(OCTET)
73 //   trailer         = *(entity-header CRLF)
74 //
75 // The chunk-size field is a string of hex digits indicating the size of the
76 // chunk.  The chunked encoding is ended by any chunk whose size is zero,
77 // followed by the trailer, which is terminated by an empty line.
78 //
79 // NOTE: This implementation does not bother to parse trailers since they are
80 // not used on the web.
81 //
82 class NET_EXPORT_PRIVATE HttpChunkedDecoder {
83  public:
84   // The maximum length of |line_buf_| between calls to FilterBuff().
85   // Exposed for tests.
86   static const size_t kMaxLineBufLen;
87 
88   HttpChunkedDecoder();
89 
90   // Indicates that a previous call to FilterBuf encountered the final CRLF.
reached_eof()91   bool reached_eof() const { return reached_eof_; }
92 
93   // Returns the number of bytes after the final CRLF.
bytes_after_eof()94   int bytes_after_eof() const { return bytes_after_eof_; }
95 
96   // Called to filter out the chunk markers from buf and to check for end-of-
97   // file.  This method modifies |buf| inline if necessary to remove chunk
98   // markers.  The return value indicates the final size of decoded data stored
99   // in |buf|.  Call reached_eof() after this method to check if end-of-file
100   // was encountered.
101   int FilterBuf(base::span<uint8_t> buf);
102 
103  private:
104   // Scans |buf| for the next chunk delimiter.  This method returns the number
105   // of bytes consumed from |buf|.  If found, |chunk_remaining_| holds the
106   // value for the next chunk size.
107   int ScanForChunkRemaining(base::span<const uint8_t> buf);
108 
109   // Converts the buffer |buf| to a numeric value.
110   // |buf| is a buffer containing a "chunk-size" (hex string).
111   // If the conversion succeeds, returns true and places the result in |out|.
112   static bool ParseChunkSize(base::span<const uint8_t> buf, uint64_t* out);
113 
114   // Indicates the number of bytes remaining for the current chunk.
115   // Using uint64_t as it can exceed size_t.
116   uint64_t chunk_remaining_ = 0;
117 
118   // A small buffer used to store a partial chunk marker.
119   std::string line_buf_;
120 
121   // True if waiting for the terminal CRLF of a chunk's data.
122   bool chunk_terminator_remaining_ = false;
123 
124   // Set to true when FilterBuf encounters the last-chunk.
125   bool reached_last_chunk_ = false;
126 
127   // Set to true when FilterBuf encounters the final CRLF.
128   bool reached_eof_ = false;
129 
130   // The number of extraneous unfiltered bytes after the final CRLF.
131   int bytes_after_eof_ = 0;
132 };
133 
134 }  // namespace net
135 
136 #endif  // NET_HTTP_HTTP_CHUNKED_DECODER_H_
137