Blocked by lack of HTTP/1.1 indicator on responses.
Better support is nearly ready but has not made this release.
{
assert(rep == NULL);
- if (!multipartRangeRequest() && !http->request->flags.chunked_reply) {
+ if (!multipartRangeRequest()) {
size_t length = lengthToSend(bodyData.range());
noteSentBodyBytes (length);
AsyncCall::Pointer call = commCbCall(33, 5, "clientWriteBodyComplete",
MemBuf mb;
mb.init();
- if (multipartRangeRequest())
- packRange(bodyData, &mb);
- else
- packChunk(bodyData, mb);
+ packRange(bodyData, &mb);
if (mb.contentSize()) {
/* write */
writeComplete(fd(), NULL, 0, COMM_OK);
}
-/**
- * Packs bodyData into mb using chunked encoding. Packs the last-chunk
- * if bodyData is empty.
- */
-void
-ClientSocketContext::packChunk(const StoreIOBuffer &bodyData, MemBuf &mb)
-{
- const uint64_t length =
- static_cast<uint64_t>(lengthToSend(bodyData.range()));
- noteSentBodyBytes(length);
-
- mb.Printf("%"PRIX64"\r\n", length);
- mb.append(bodyData.data, length);
- mb.Printf("\r\n");
-}
-
/** put terminating boundary for multiparts */
static void
clientPackTermBound(String boundary, MemBuf * mb)
#endif
if (bodyData.data && bodyData.length) {
- if (multipartRangeRequest())
- packRange(bodyData, mb);
- else if (http->request->flags.chunked_reply) {
- packChunk(bodyData, *mb);
- } else {
+ if (!multipartRangeRequest()) {
size_t length = lengthToSend(bodyData.range());
noteSentBodyBytes (length);
mb->append(bodyData.data, length);
+ } else {
+ packRange(bodyData, mb);
}
}
return;
}
- // After sending Transfer-Encoding: chunked (at least), always send
- // the last-chunk if there was no error, ignoring responseFinishedOrFailed.
- const bool mustSendLastChunk = http->request->flags.chunked_reply &&
- !http->request->flags.stream_error && !context->startOfOutput();
- if (responseFinishedOrFailed(rep, receivedData) && !mustSendLastChunk) {
+ if (responseFinishedOrFailed(rep, receivedData)) {
context->writeComplete(fd, NULL, 0, COMM_OK);
PROF_stop(clientSocketRecipient);
return;
private:
CBDATA_CLASS(ClientSocketContext);
void prepareReply(HttpReply * rep);
- void packChunk(const StoreIOBuffer &bodyData, MemBuf &mb);
void packRange(StoreIOBuffer const &, MemBuf * mb);
void deRegisterWithConn();
void doClose();
if (http->flags.done_copying)
return 1;
- if (http->request->flags.chunked_reply && !flags.complete) {
- // last-chunk was not sent
- return 0;
- }
-
/*
* Handle STORE_OK objects.
* objectLen(entry) will be set proprely.
debugs(88, 5, "clientReplyStatus: transfer is DONE");
/* Ok we're finished, but how? */
- const int64_t expectedBodySize =
- http->storeEntry()->getReply()->bodySize(http->request->method);
- if (!http->request->flags.proxy_keepalive && expectedBodySize < 0) {
+ if (http->storeEntry()->getReply()->bodySize(http->request->method) < 0) {
debugs(88, 5, "clientReplyStatus: closing, content_length < 0");
return STREAM_FAILED;
}
return STREAM_FAILED;
}
- if (expectedBodySize >= 0 && !http->gotEnough()) {
+ if (!http->gotEnough()) {
debugs(88, 5, "clientReplyStatus: client didn't get all it expected");
return STREAM_UNPLANNED_COMPLETE;
}
#endif
- const bool maySendChunkedReply = !request->multipartRangeRequest() &&
- (request->http_ver >= HttpVersion(1, 1));
-
/* Check whether we should send keep-alive */
if (!Config.onoff.error_pconns && reply->sline.status >= 400 && !request->flags.must_keepalive) {
debugs(33, 3, "clientBuildReplyHeader: Error, don't keep-alive");
} else if (request->flags.connection_auth && !reply->keep_alive) {
debugs(33, 2, "clientBuildReplyHeader: Connection oriented auth but server side non-persistent");
request->flags.proxy_keepalive = 0;
- } else if (reply->bodySize(request->method) < 0 && !maySendChunkedReply) {
+ } else if (reply->bodySize(request->method) < 0) {
debugs(88, 3, "clientBuildReplyHeader: can't keep-alive, unknown body size" );
request->flags.proxy_keepalive = 0;
} else if (fdUsageHigh()&& !request->flags.must_keepalive) {
request->flags.proxy_keepalive = 0;
}
- // Decide if we send chunked reply
- if (maySendChunkedReply &&
- request->flags.proxy_keepalive &&
- reply->bodySize(request->method) < 0) {
- debugs(88, 3, "clientBuildReplyHeader: chunked reply");
- request->flags.chunked_reply = 1;
- hdr->putStr(HDR_TRANSFER_ENCODING, "chunked");
- }
-
/* Append VIA */
if (Config.onoff.via) {
LOCAL_ARRAY(char, bbuf, MAX_URL + 32);
debugs(88, 5, "clientReplyContext::sendStreamError: A stream error has occured, marking as complete and sending no data.");
StoreIOBuffer localTempBuffer;
flags.complete = 1;
- http->request->flags.stream_error = 1;
localTempBuffer.flags.error = result.flags.error;
clientStreamCallback((clientStreamNode*)http->client_stream.head->data, http, NULL,
localTempBuffer);
struct request_flags {
- request_flags(): range(0),nocache(0),ims(0),auth(0),cachable(0),hierarchical(0),loopdetect(0),proxy_keepalive(0),proxying(0),refresh(0),redirected(0),need_validation(0),accelerated(0),ignore_cc(0),intercepted(0),spoof_client_ip(0),internal(0),internalclient(0),must_keepalive(0),chunked_reply(0),stream_error(0),destinationIPLookedUp_(0) {
+ request_flags(): range(0),nocache(0),ims(0),auth(0),cachable(0),hierarchical(0),loopdetect(0),proxy_keepalive(0),proxying(0),refresh(0),redirected(0),need_validation(0),accelerated(0),ignore_cc(0),intercepted(0),spoof_client_ip(0),internal(0),internalclient(0),must_keepalive(0),destinationIPLookedUp_(0) {
#if HTTP_VIOLATIONS
nocache_hack = 0;
#endif
unsigned int pinned:1; /* Request sent on a pinned connection */
unsigned int auth_sent:1; /* Authentication forwarded */
unsigned int no_direct:1; /* Deny direct forwarding unless overriden by always_direct. Used in accelerator mode */
- unsigned int chunked_reply:1; /**< Reply with chunked transfer encoding */
- unsigned int stream_error:1; /**< Whether stream error has occured */
// When adding new flags, please update cloneAdaptationImmune() as needed.