]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ChunkedCodingParser.cc
2 #include "base/TextException.h"
4 #include "ChunkedCodingParser.h"
7 ChunkedCodingParser::Step
ChunkedCodingParser::psChunkBeg
= &ChunkedCodingParser::parseChunkBeg
;
8 ChunkedCodingParser::Step
ChunkedCodingParser::psChunkBody
= &ChunkedCodingParser::parseChunkBody
;
9 ChunkedCodingParser::Step
ChunkedCodingParser::psChunkEnd
= &ChunkedCodingParser::parseChunkEnd
;
10 ChunkedCodingParser::Step
ChunkedCodingParser::psTrailer
= &ChunkedCodingParser::parseTrailer
;
11 ChunkedCodingParser::Step
ChunkedCodingParser::psMessageEnd
= &ChunkedCodingParser::parseMessageEnd
;
13 ChunkedCodingParser::ChunkedCodingParser()
18 void ChunkedCodingParser::reset()
21 theChunkSize
= theLeftBodySize
= 0;
22 doNeedMoreData
= false;
23 theIn
= theOut
= NULL
;
26 bool ChunkedCodingParser::parse(MemBuf
*rawData
, MemBuf
*parsedContent
)
28 Must(rawData
&& parsedContent
);
30 theOut
= parsedContent
;
32 // we must reset this all the time so that mayContinue() lets us
33 // output more content if we stopped due to needsMoreSpace() before
34 doNeedMoreData
= !theIn
->hasContent();
36 while (mayContinue()) {
40 return theStep
== psMessageEnd
;
43 bool ChunkedCodingParser::needsMoreData() const
45 return doNeedMoreData
;
48 bool ChunkedCodingParser::needsMoreSpace() const
51 return theStep
== psChunkBody
&& !theOut
->hasPotentialSpace();
54 bool ChunkedCodingParser::mayContinue() const
56 return !needsMoreData() && !needsMoreSpace() && theStep
!= psMessageEnd
;
59 void ChunkedCodingParser::parseChunkBeg()
61 Must(theChunkSize
<= 0); // Should(), really
66 if (findCrlf(crlfBeg
, crlfEnd
)) {
67 debugs(94,7, "found chunk-size end: " << crlfBeg
<< "-" << crlfEnd
);
71 if (StringToInt64(theIn
->content(), size
, &p
, 16)) {
73 throw TexcHere("negative chunk size");
77 theIn
->consume(crlfEnd
);
78 theChunkSize
= theLeftBodySize
= size
;
79 debugs(94,7, "found chunk: " << theChunkSize
);
80 theStep
= theChunkSize
== 0 ? psTrailer
: psChunkBody
;
84 throw TexcHere("corrupted chunk size");
87 doNeedMoreData
= true;
90 void ChunkedCodingParser::parseChunkBody()
92 Must(theLeftBodySize
> 0); // Should, really
94 const size_t availSize
= min(theLeftBodySize
, (uint64_t)theIn
->contentSize());
95 const size_t safeSize
= min(availSize
, (size_t)theOut
->potentialSpaceSize());
97 doNeedMoreData
= availSize
< theLeftBodySize
;
98 // and we may also need more space
100 theOut
->append(theIn
->content(), safeSize
);
101 theIn
->consume(safeSize
);
102 theLeftBodySize
-= safeSize
;
104 if (theLeftBodySize
== 0)
105 theStep
= psChunkEnd
;
107 Must(needsMoreData() || needsMoreSpace());
110 void ChunkedCodingParser::parseChunkEnd()
112 Must(theLeftBodySize
== 0); // Should(), really
117 if (findCrlf(crlfBeg
, crlfEnd
)) {
119 throw TexcHere("found data bewteen chunk end and CRLF");
123 theIn
->consume(crlfEnd
);
124 theChunkSize
= 0; // done with the current chunk
125 theStep
= psChunkBeg
;
129 doNeedMoreData
= true;
132 void ChunkedCodingParser::parseTrailer()
134 Must(theChunkSize
== 0); // Should(), really
136 while (mayContinue())
137 parseTrailerHeader();
140 void ChunkedCodingParser::parseTrailerHeader()
145 if (findCrlf(crlfBeg
, crlfEnd
)) {
148 ; //theTrailer.append(theIn->content(), crlfEnd);
150 theIn
->consume(crlfEnd
);
153 theStep
= psMessageEnd
;
158 doNeedMoreData
= true;
161 void ChunkedCodingParser::parseMessageEnd()
163 // termination step, should not be called
164 Must(false); // Should(), really
168 bool ChunkedCodingParser::findCrlf(size_t &crlfBeg
, size_t &crlfEnd
)
170 // XXX: This code was copied, with permission, from another software.
171 // There is a similar and probably better code inside httpHeaderParse
172 // but it seems difficult to isolate due to parsing-unrelated bloat.
173 // Such isolation should probably be done before this class is used
174 // for handling of traffic "more external" than ICAP.
176 const char *buf
= theIn
->content();
177 size_t size
= theIn
->contentSize();
181 bool slashed
= false;
183 for (size_t i
= 0; i
< size
; ++i
) {
189 const char c
= buf
[i
];
191 // handle quoted strings
199 } else if (c
== '"') {
205 if (crOff
< 0) { // looking for the first CR or LF
215 } else { // skipping CRs, looking for the first LF