]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/adaptation/icap/ModXact.h
SourceFormat Enforcement
[thirdparty/squid.git] / src / adaptation / icap / ModXact.h
index f0e23cede39e998a8a2a270a9c236633e397cacb..4694d64a94a8ea5122fed3f297ce18a629e0c51d 100644 (file)
  * receive the HTTP body.
  */
 
-
 class ChunkedCodingParser;
 
 namespace Adaptation
 {
-namespace Icap {
+namespace Icap
+{
 
 // estimated future presence and size of something (e.g., HTTP body)
 
@@ -105,7 +105,6 @@ private:
     State theState;
 };
 
-
 // maintains preview-related sizes
 
 class Preview
@@ -135,7 +134,8 @@ class ModXact: public Xaction, public BodyProducer, public BodyConsumer
 {
 
 public:
-    ModXact(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, ServiceRep::Pointer &s);
+    ModXact(HttpMsg *virginHeader, HttpRequest *virginCause, ServiceRep::Pointer &s);
+    virtual ~ModXact();
 
     // BodyProducer methods
     virtual void noteMoreBodySpaceAvailable(BodyPipe::Pointer);
@@ -155,18 +155,26 @@ public:
 
     // service waiting
     void noteServiceReady();
+    void noteServiceAvailable();
 
 public:
     InOut virgin;
     InOut adapted;
 
-protected:
     // bypasses exceptions if needed and possible
     virtual void callException(const std::exception &e);
 
+    /// record error detail in the virgin request if possible
+    virtual void detailError(int errDetail);
+    // Icap::Xaction API
+    virtual void clearError();
+
 private:
     virtual void start();
 
+    /// locates the request, either as a cause or as a virgin message itself
+    const HttpRequest &virginRequest() const; // Must always be available
+
     void estimateVirginBody();
     void makeAdaptedBodyPipe(const char *what);
 
@@ -180,6 +188,7 @@ private:
     void writePreviewBody();
     void writePrimeBody();
     void writeSomeBody(const char *label, size_t size);
+    void decideWritingAfterPreview(const char *previewKind);
 
     void startReading();
     void readMore();
@@ -191,6 +200,7 @@ private:
     bool virginBodyEndReached(const VirginBodyAct &act) const;
 
     void makeRequestHeaders(MemBuf &buf);
+    void makeAllowHeader(MemBuf &buf);
     void makeUsernameHeader(const HttpRequest *request, MemBuf &buf);
     void addLastRequestChunk(MemBuf &buf);
     void openChunk(MemBuf &buf, size_t chunkSize, bool ieof);
@@ -201,6 +211,9 @@ private:
     void decideOnPreview();
     void decideOnRetries();
     bool shouldAllow204();
+    bool shouldAllow206any();
+    bool shouldAllow206in();
+    bool shouldAllow206out();
     bool canBackupEverything() const;
 
     void prepBackup(size_t expectedSize);
@@ -221,14 +234,16 @@ private:
     bool validate200Ok();
     void handle200Ok();
     void handle204NoContent();
+    void handle206PartialContent();
     void handleUnknownScode();
 
     void bypassFailure();
 
     void startSending();
-    void disableBypass(const char *reason);
+    void disableBypass(const char *reason, bool includeGroupBypass);
 
     void prepEchoing();
+    void prepPartialBodyEchoing(uint64_t pos);
     void echoMore();
 
     virtual bool doneAll() const;
@@ -250,8 +265,7 @@ private:
     bool gotEncapsulated(const char *section) const;
     void checkConsuming();
 
-
-    HttpReply *icapReply;
+    virtual void finalizeLogInfo();
 
     SizedEstimate virginBody;
     VirginBodyAct virginBodyWriting; // virgin body writing state
@@ -262,6 +276,20 @@ private:
     ChunkedCodingParser *bodyParser; // ICAP response body parser
 
     bool canStartBypass; // enables bypass of transaction failures
+    bool protectGroupBypass; // protects ServiceGroup-wide bypass of failures
+
+    /**
+     * size of HTTP header in ICAP reply or -1 if there is not any encapsulated
+     * message data
+     */
+    int64_t replyHttpHeaderSize;
+    /**
+     * size of dechunked HTTP body in ICAP reply or -1 if there is not any
+     * encapsulated message data
+     */
+    int64_t replyHttpBodySize;
+
+    int adaptHistoryId; ///< adaptation history slot reservation
 
     class State
     {
@@ -273,6 +301,10 @@ private:
 
         bool serviceWaiting; // waiting for ICAP service options
         bool allowedPostview204; // mmust handle 204 No Content outside preview
+        bool allowedPostview206; // must handle 206 Partial Content outside preview
+        bool allowedPreview206; // must handle 206 Partial Content inside preview
+        bool readyForUob; ///< got a 206 response and expect a use-origin-body
+        bool waitedForService; ///< true if was queued at least once
 
         // will not write anything [else] to the ICAP server connection
         bool doneWriting() const { return writing == writingReallyDone; }
@@ -280,7 +312,8 @@ private:
         // will not use virgin.body_pipe
         bool doneConsumingVirgin() const {
             return writing >= writingAlmostDone
-                   && (sending == sendingAdapted || sending == sendingDone);
+                   && ((sending == sendingAdapted && !readyForUob) ||
+                       sending == sendingDone);
         }
 
         // parsed entire ICAP response from the ICAP server
@@ -314,18 +347,22 @@ private:
 class ModXactLauncher: public Launcher
 {
 public:
-    ModXactLauncher(Adaptation::Initiator *anInitiator, HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer s);
+    ModXactLauncher(HttpMsg *virginHeader, HttpRequest *virginCause, Adaptation::ServicePointer s);
 
 protected:
     virtual Xaction *createXaction();
 
+    virtual void swanSong();
+
+    /// starts or stops transaction accounting in ICAP history
+    void updateHistory(bool start);
+
     InOut virgin;
 
 private:
     CBDATA_CLASS2(ModXactLauncher);
 };
 
-
 } // namespace Icap
 } // namespace Adaptation