diff options
author | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:42:52 +0000 |
---|---|---|
committer | initial.commit <initial.commit@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-07-26 22:42:52 +0000 |
commit | 586acc5fe142f498261f52c66862fa417c3d52d2 (patch) | |
tree | c98b3417a883f2477029c8cd5888f4078681e24e /net/http/http_chunked_decoder.cc | |
parent | a814a8d55429605fe6d7045045cd25b6bf624580 (diff) | |
download | chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.zip chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.gz chromium_src-586acc5fe142f498261f52c66862fa417c3d52d2.tar.bz2 |
Add net to the repository.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@14 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http/http_chunked_decoder.cc')
-rw-r--r-- | net/http/http_chunked_decoder.cc | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/net/http/http_chunked_decoder.cc b/net/http/http_chunked_decoder.cc new file mode 100644 index 0000000..059d792 --- /dev/null +++ b/net/http/http_chunked_decoder.cc @@ -0,0 +1,136 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla. + * + * The Initial Developer of the Original Code is + * Netscape Communications. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Darin Fisher <darin@netscape.com> (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +// Derived from: +// mozilla/netwerk/protocol/http/src/nsHttpChunkedDecoder.cpp + +#include "net/http/http_chunked_decoder.h" + +#include "base/logging.h" +#include "net/base/net_errors.h" + +namespace net { + +HttpChunkedDecoder::HttpChunkedDecoder() + : chunk_remaining_(0), + reached_last_chunk_(false), + reached_eof_(false) { +} + +int HttpChunkedDecoder::FilterBuf(char* buf, int buf_len) { + int result = 0; + + while (buf_len) { + if (chunk_remaining_) { + int num = std::min(chunk_remaining_, buf_len); + + buf_len -= num; + chunk_remaining_ -= num; + + result += num; + buf += num; + continue; + } else if (reached_eof_) { + break; // Done! + } + + // Returns bytes consumed or an error code. + int rv = ScanForChunkRemaining(buf, buf_len); + if (rv < 0) + return rv; + + buf_len -= rv; + if (buf_len) + memmove(buf, buf + rv, buf_len); + } + + return result; +} + +int HttpChunkedDecoder::ScanForChunkRemaining(char* buf, int buf_len) { + DCHECK(chunk_remaining_ == 0); + DCHECK(buf_len > 0); + + int result = 0; + + char *p = static_cast<char*>(memchr(buf, '\n', buf_len)); + if (p) { + *p = 0; + if ((p > buf) && (*(p - 1) == '\r')) // Eliminate a preceding CR. + *(p - 1) = 0; + result = static_cast<int>(p - buf) + 1; + + // Make buf point to the full line buffer to parse. + if (!line_buf_.empty()) { + line_buf_.append(buf); + buf = const_cast<char*>(line_buf_.data()); + } + + if (reached_last_chunk_) { + if (*buf) { + DLOG(INFO) << "ignoring http trailer"; + } else { + reached_eof_ = true; + } + } else if (*buf) { + // Ignore any chunk-extensions. + if ((p = strchr(buf, ';')) != NULL) + *p = 0; + + if (!sscanf_s(buf, "%x", &chunk_remaining_)) { + DLOG(ERROR) << "sscanf failed parsing HEX from: " << buf; + return ERR_FAILED; + } + + if (chunk_remaining_ == 0) + reached_last_chunk_ = true; + } + line_buf_.clear(); + } else { + // Save the partial line; wait for more data. + result = buf_len; + + // Ignore a trailing CR + if (buf[buf_len - 1] == '\r') + buf_len--; + + line_buf_.append(buf, buf_len); + } + return result; +} + +} // namespace net |