2 #ifndef SQUID_BODY_PIPE_H
3 #define SQUID_BODY_PIPE_H
6 #include "base/AsyncCall.h"
7 #include "base/AsyncJob.h"
11 // Interface for those who want to produce body content for others.
12 // BodyProducer is expected to create the BodyPipe.
13 // One pipe cannot have more than one producer.
14 class BodyProducer
: virtual public AsyncJob
17 BodyProducer():AsyncJob("BodyProducer") {}
18 virtual ~BodyProducer() {}
20 virtual void noteMoreBodySpaceAvailable(RefCount
<BodyPipe
> bp
) = 0;
21 virtual void noteBodyConsumerAborted(RefCount
<BodyPipe
> bp
) = 0;
24 void stopProducingFor(RefCount
<BodyPipe
> &pipe
, bool atEof
);
27 // Interface for those who want to consume body content from others.
28 // BodyConsumer is expected to register with an existing BodyPipe
29 // by calling BodyPipe::setConsumer().
30 // One pipe cannot have more than one consumer.
31 class BodyConsumer
: virtual public AsyncJob
34 BodyConsumer():AsyncJob("BodyConsumer") {}
35 virtual ~BodyConsumer() {}
37 virtual void noteMoreBodyDataAvailable(RefCount
<BodyPipe
> bp
) = 0;
38 virtual void noteBodyProductionEnded(RefCount
<BodyPipe
> bp
) = 0;
39 virtual void noteBodyProducerAborted(RefCount
<BodyPipe
> bp
) = 0;
42 void stopConsumingFrom(RefCount
<BodyPipe
> &pipe
);
45 // Makes raw buffer checkin/checkout interface efficient and exception-safe.
46 // Either append or consume operations can be performed on a checkedout buffer.
47 class BodyPipeCheckout
50 friend class BodyPipe
;
53 BodyPipeCheckout(BodyPipe
&pipe
); // checks out
54 ~BodyPipeCheckout(); // aborts checkout unless checkedIn
61 const uint64_t offset
; // of current content, relative to the body start
64 const size_t checkedOutSize
;
68 BodyPipeCheckout(const BodyPipeCheckout
&); // prevent copying
69 BodyPipeCheckout
&operator =(const BodyPipeCheckout
&); // prevent assignment
72 // Connects those who produces message body content with those who
73 // consume it. For example, connects ConnStateData with FtpStateData OR
74 // ICAPModXact with HttpStateData.
75 class BodyPipe
: public RefCountable
78 typedef RefCount
<BodyPipe
> Pointer
;
79 typedef BodyProducer Producer
;
80 typedef BodyConsumer Consumer
;
81 typedef BodyPipeCheckout Checkout
;
83 enum { MaxCapacity
= SQUID_TCP_SO_RCVBUF
};
85 friend class BodyPipeCheckout
;
88 BodyPipe(Producer
*aProducer
);
89 ~BodyPipe(); // asserts that producer and consumer are cleared
91 void setBodySize(uint64_t aSize
); // set body size
92 bool bodySizeKnown() const { return theBodySize
>= 0; }
93 uint64_t bodySize() const;
94 uint64_t consumedSize() const { return theGetSize
; }
95 bool productionEnded() const { return !theProducer
; }
97 // called by producers
98 void clearProducer(bool atEof
); // aborts or sends eof
99 size_t putMoreData(const char *buf
, size_t size
);
100 bool mayNeedMoreData() const { return !bodySizeKnown() || needsMoreData(); }
101 bool needsMoreData() const { return bodySizeKnown() && unproducedSize() > 0; }
102 uint64_t unproducedSize() const; // size of still unproduced data
103 bool stillProducing(const Producer
*producer
) const { return theProducer
== producer
; }
104 void expectProductionEndAfter(uint64_t extraSize
); ///< sets or checks body size
106 // called by consumers
107 bool setConsumerIfNotLate(Consumer
*aConsumer
);
108 void clearConsumer(); // aborts if still piping
109 size_t getMoreData(MemBuf
&buf
);
110 void consume(size_t size
);
111 bool expectMoreAfter(uint64_t offset
) const;
112 bool exhausted() const; // saw eof/abort and all data consumed
113 bool stillConsuming(const Consumer
*consumer
) const { return theConsumer
== consumer
; }
115 // start or continue consuming when there is no consumer
116 void enableAutoConsumption();
118 const MemBuf
&buf() const { return theBuf
; }
120 const char *status() const; // for debugging only
123 // lower-level interface used by Checkout
124 MemBuf
&checkOut(); // obtain raw buffer
125 void checkIn(Checkout
&checkout
); // return updated raw buffer
126 void undoCheckOut(Checkout
&checkout
); // undo checkout efffect
128 void scheduleBodyDataNotification();
129 void scheduleBodyEndNotification();
131 // keep counters in sync and notify producer or consumer
132 void postConsume(size_t size
);
133 void postAppend(size_t size
);
135 void startAutoConsumption(); // delayed start of enabled consumption
138 int64_t theBodySize
; // expected total content length, if known
139 Producer
*theProducer
; // content producer, if any
140 Consumer
*theConsumer
; // content consumer, if any
142 uint64_t thePutSize
; // ever-increasing total
143 uint64_t theGetSize
; // ever-increasing total
145 MemBuf theBuf
; // produced but not yet consumed content, if any
147 bool mustAutoConsume
; // consume when there is no consumer
148 bool isCheckedOut
; // to keep track of checkout violations
150 CBDATA_CLASS2(BodyPipe
);
153 #endif /* SQUID_BODY_PIPE_H */