activeRequest->responseHeadersComplete();
_contentDecoder.initWithRequest(activeRequest);
+ if (!activeRequest->serverSupportsPipelining()) {
+ SG_LOG(SG_IO, SG_DEBUG, _connectionId << " disabling pipelining since server does not support it");
+ _maxPipelineLength = 1;
+ }
+
if (chunkedTransfer) {
setState(STATE_GETTING_CHUNKED);
} else if (noMessageBody || (bodyTransferSize == 0)) {
_responseLength(0),
_receivedBodyBytes(0),
_ready_state(UNSENT),
- _willClose(false)
+ _willClose(false),
+ _connectionCloseHeader(false)
{
}
void Request::responseHeader(const std::string& key, const std::string& value)
{
if( key == "connection" ) {
- _willClose = (value.find("close") != std::string::npos);
+ _connectionCloseHeader = (value.find("close") != std::string::npos);
+ // track willClose seperately because other conditions (abort, for
+ // example) can also set it
+ _willClose = _connectionCloseHeader;
} else if (key == "content-length") {
int sz = strutils::to_int(value);
setResponseLength(sz);
return _willClose || (_responseVersion != HTTP_1_1);
}
+//------------------------------------------------------------------------------
+bool Request::serverSupportsPipelining() const
+{
+ return (_responseVersion == HTTP_1_1) && !_connectionCloseHeader;
+}
+
//------------------------------------------------------------------------------
bool Request::isComplete() const
{
bool closeAfterComplete() const;
bool isComplete() const;
+ /**
+ * Check if the server response indicates pipelining should be continued.
+ * Currently tests that HTTP_1_1 is explicitly supported, and that the
+ * server/proxy did not request Connection: close
+ */
+ bool serverSupportsPipelining() const;
+
protected:
Request(const std::string& url, const std::string method = "GET");
ReadyState _ready_state;
bool _willClose;
+ bool _connectionCloseHeader;
};
typedef SGSharedPtr<Request> Request_ptr;