summaryrefslogtreecommitdiff
path: root/src/ChunkedDecoder.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-07-11 14:15:36 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-07-11 14:15:36 +0000
commit20cea7f69386c74676fb0e6765a3e6eb3df3d0bd (patch)
tree3b262e123cfe22ea5e8b617d241297d017d5d99d /src/ChunkedDecoder.cc
parenteecb81dc60d0b9bb85b411efecb272b1404f071a (diff)
2010-07-11 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Fixed ChunkedDecoder. It does not read trailer and final CRLF. * src/ChunkedDecoder.cc * src/ChunkedDecoder.h * test/ChunkedDecoderTest.cc
Diffstat (limited to 'src/ChunkedDecoder.cc')
-rw-r--r--src/ChunkedDecoder.cc31
1 files changed, 29 insertions, 2 deletions
diff --git a/src/ChunkedDecoder.cc b/src/ChunkedDecoder.cc
index 57f1d722..55068545 100644
--- a/src/ChunkedDecoder.cc
+++ b/src/ChunkedDecoder.cc
@@ -64,6 +64,27 @@ static bool readChunkSize(uint64_t& chunkSize, std::string& in)
return true;
}
+static bool readTrailer(std::string& in)
+{
+ std::string::size_type crlfPos = in.find(A2STR::CRLF);
+ if(crlfPos == std::string::npos) {
+ return false;
+ }
+ if(crlfPos == 0) {
+ return true;
+ } else {
+ if(in.size() > crlfPos+3) {
+ if(in[crlfPos+2] == '\r' && in[crlfPos+3] == '\n') {
+ return true;
+ } else {
+ throw DL_ABORT_EX("No CRLF at the end of chunk stream.");
+ }
+ } else {
+ return false;
+ }
+ }
+}
+
static bool readData(std::string& out, uint64_t& chunkSize, std::string& in)
{
uint64_t readlen = std::min(chunkSize, static_cast<uint64_t>(in.size()));
@@ -91,8 +112,7 @@ std::string ChunkedDecoder::decode(const unsigned char* inbuf, size_t inlen)
if(state_ == READ_SIZE) {
if(readChunkSize(chunkSize_, buf_)) {
if(chunkSize_ == 0) {
- state_ = STREAM_END;
- break;
+ state_ = READ_TRAILER;
} else {
state_ = READ_DATA;
}
@@ -105,6 +125,13 @@ std::string ChunkedDecoder::decode(const unsigned char* inbuf, size_t inlen)
} else {
break;
}
+ } else if(state_ == READ_TRAILER) {
+ if(readTrailer(buf_)) {
+ state_ = STREAM_END;
+ break;
+ } else {
+ break;
+ }
}
}
return outbuf;