/*
- * Copyright (C) 1996-2014 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
#include "adaptation/icap/Launcher.h"
#include "adaptation/icap/Xaction.h"
#include "BodyPipe.h"
+#include "http/one/forward.h"
/*
* ICAPModXact implements ICAP REQMOD and RESPMOD transaction using
* receive the HTTP body.
*/
-class ChunkedCodingParser;
-
namespace Adaptation
{
namespace Icap
enum State { stDisabled, stWriting, stIeof, stDone } theState;
};
+/// Parses and stores ICAP trailer header block.
+class TrailerParser
+{
+public:
+ TrailerParser() : trailer(hoReply), hdr_sz(0) {}
+ /// Parses trailers stored in a buffer.
+ /// \returns true and sets hdr_sz on success
+ /// \returns false and sets *error to zero when needs more data
+ /// \returns false and sets *error to a positive Http::StatusCode on error
+ bool parse(const char *buf, int len, int atEnd, Http::StatusCode *error);
+ HttpHeader trailer;
+ /// parsed trailer size if parse() was successful
+ size_t hdr_sz; // pedantic XXX: wrong type dictated by HttpHeader::parse() API
+};
+
class ModXact: public Xaction, public BodyProducer, public BodyConsumer
{
CBDATA_CLASS(ModXact);
virtual void detailError(int errDetail);
// Icap::Xaction API
virtual void clearError();
+ /// The master transaction log entry
+ virtual AccessLogEntry::Pointer masterLogEntry() { return alMaster; }
private:
virtual void start();
void decideOnParsingBody();
void parseBody();
+ void parseIcapTrailer();
void maybeAllocateHttpMsg();
void handle100Continue();
void prepEchoing();
void prepPartialBodyEchoing(uint64_t pos);
void echoMore();
+ void updateSources(); ///< Update the HttpMsg sources
virtual bool doneAll() const;
virtual void swanSong();
void stopReceiving();
void stopSending(bool nicely);
void stopWriting(bool nicely);
- void stopParsing();
+ void stopParsing(const bool checkUnparsedData = true);
void stopBackup();
virtual void fillPendingStatus(MemBuf &buf) const;
virtual bool fillVirginHttpHeader(MemBuf&) const;
private:
+ /// parses a message header or trailer
+ /// \returns true on success
+ /// \returns false if more data is needed
+ /// \throw TextException on unrecoverable error
+ template<class Part>
+ bool parsePart(Part *part, const char *description);
+
void packHead(MemBuf &httpBuf, const HttpMsg *head);
void encapsulateHead(MemBuf &icapBuf, const char *section, MemBuf &httpBuf, const HttpMsg *head);
bool gotEncapsulated(const char *section) const;
+ /// whether ICAP response header indicates HTTP header presence
+ bool expectHttpHeader() const;
+ /// whether ICAP response header indicates HTTP body presence
+ bool expectHttpBody() const;
+ /// whether ICAP response header indicates ICAP trailers presence
+ bool expectIcapTrailers() const;
void checkConsuming();
virtual void finalizeLogInfo();
uint64_t virginConsumed; // virgin data consumed so far
Preview preview; // use for creating (writing) the preview
- ChunkedCodingParser *bodyParser; // ICAP response body parser
+ Http1::TeChunkedParser *bodyParser; // ICAP response body parser
bool canStartBypass; // enables bypass of transaction failures
bool protectGroupBypass; // protects ServiceGroup-wide bypass of failures
int adaptHistoryId; ///< adaptation history slot reservation
+ TrailerParser *trailerParser;
+
class State
{
parsing == psHttpHeader;
}
- enum Parsing { psIcapHeader, psHttpHeader, psBody, psDone } parsing;
+ enum Parsing { psIcapHeader, psHttpHeader, psBody, psIcapTrailer, psDone } parsing;
// measures ICAP request writing progress
enum Writing { writingInit, writingConnect, writingHeaders,
} // namespace Adaptation
#endif /* SQUID_ICAPMOD_XACT_H */
+