[squid-dev] [PATCH] Http::ProtocolVersion update
Amos Jeffries
squid3 at treenet.co.nz
Sun Dec 7 06:56:22 UTC 2014
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
As mentioned by Alex in the FTP server addition the
Http::ProtocolVersion(*) does not work sufficiently well as a class
hierarchy and should be re-implemented as global functions.
This patch does that re-implementation.
Convert Http::ProtocolVersion to two functions:
* Http::ProtocolVersion() providing the default Squid HTTP version
level, and
* Http::ProtocolVersion(unsigned, unsigned) providing the HTTP version
details for the given level.
NP: using two overloaded functions instead of one with default
parameter values because with HTTP/0.x and HTTP/2.x we cannot safely
default just the minor value. ie. using two functions prevents
mistakenly using HTTP/2.1, HTTP/0.1 or HTTP/1.0 if the second
parameter is omitted.
All variables must now be of type AnyP::ProtocolVersion, and should be
constructed from an appropriate Foo::ProtocolVersion() function.
Amos
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (MingW32)
iQEcBAEBAgAGBQJUg/oWAAoJELJo5wb/XPRjWkIIALNtUpyqnQohpye5vzZvTdaK
Vib1f0kas2YBURCrtYvLmwt5KIRVsKiwcyofIL0M2l2OEr2ptJhq5Gw2oHAcNZTb
WSN9CmZ+WVR+NBLcSKbKN+tppFTlN9VAgMlRiz1qcFjG4y+mHSBsZiXj9obmp4BJ
avffJHy/5H9tU78c2jTEe487rsIY+jVUcO6yk5FmhjIQ9oi3nEb4SgHs6gTYdTT5
dsQTqaBaMr6wmWGF1FVWiOAvJktEtOyUqFjaVRq3V0Y++XfZH9eWJedpGxtMNvUQ
gOrw5FwcGSTPKTGJlb9hXl2YqmnrXNNlBHcsbD5vC2bnB7xnZ7M7Hm5oeU9Kg/o=
=J2dr
-----END PGP SIGNATURE-----
-------------- next part --------------
=== modified file 'src/AccessLogEntry.h'
--- src/AccessLogEntry.h 2014-11-20 08:57:14 +0000
+++ src/AccessLogEntry.h 2014-12-06 16:46:01 +0000
@@ -55,41 +55,41 @@
// TCP/IP level details about the server or peer connection
// are stored in hier.tcpServer
/** \brief This subclass holds log info for HTTP protocol
* \todo Inner class declarations should be moved outside
* \todo details of HTTP held in the parent class need moving into here.
*/
class HttpDetails
{
public:
HttpDetails() : method(Http::METHOD_NONE), code(0), content_type(NULL),
timedout(false),
aborted(false),
clientRequestSz(),
clientReplySz() {}
HttpRequestMethod method;
int code;
const char *content_type;
- Http::ProtocolVersion version;
+ AnyP::ProtocolVersion version;
bool timedout; ///< terminated due to a lifetime or I/O timeout
bool aborted; ///< other abnormal termination (e.g., I/O error)
/// compute suffix for the status access.log field
const char *statusSfx() const {
return timedout ? "_TIMEDOUT" : (aborted ? "_ABORTED" : "");
}
/// counters for the original request received from client
// TODO calculate header and payload better (by parser)
// XXX payload encoding overheads not calculated at all yet.
MessageSizes clientRequestSz;
/// counters for the response sent to client
// TODO calculate header and payload better (by parser)
// XXX payload encoding overheads not calculated at all yet.
MessageSizes clientReplySz;
} http;
=== modified file 'src/HttpMsg.cc'
--- src/HttpMsg.cc 2014-09-14 12:43:00 +0000
+++ src/HttpMsg.cc 2014-12-06 18:24:23 +0000
@@ -283,41 +283,41 @@
/* handy: resets and returns -1 */
int
HttpMsg::httpMsgParseError()
{
reset();
return -1;
}
void
HttpMsg::setContentLength(int64_t clen)
{
header.delById(HDR_CONTENT_LENGTH); // if any
header.putInt64(HDR_CONTENT_LENGTH, clen);
content_length = clen;
}
bool
HttpMsg::persistent() const
{
- if (http_ver > Http::ProtocolVersion(1, 0)) {
+ if (http_ver > Http::ProtocolVersion(1,0)) {
/*
* for modern versions of HTTP: persistent unless there is
* a "Connection: close" header.
*/
return !httpHeaderHasConnDir(&header, "close");
} else {
/* for old versions of HTTP: persistent if has "keep-alive" */
return httpHeaderHasConnDir(&header, "keep-alive");
}
}
void HttpMsg::packInto(Packer *p, bool full_uri) const
{
packFirstLineInto(p, full_uri);
header.packInto(p);
packerAppend(p, "\r\n", 2);
}
void HttpMsg::hdrCacheInit()
{
=== modified file 'src/HttpMsg.h'
--- src/HttpMsg.h 2014-09-14 12:43:00 +0000
+++ src/HttpMsg.h 2014-12-06 16:48:11 +0000
@@ -30,41 +30,41 @@
void packInto(Packer * p, bool full_uri) const;
///< produce a message copy, except for a few connection-specific settings
virtual HttpMsg *clone() const = 0; ///< \todo rename: not a true copy?
/// [re]sets Content-Length header and cached value
void setContentLength(int64_t clen);
/**
* \retval true the message sender asks to keep the connection open.
* \retval false the message sender will close the connection.
*
* Factors other than the headers may result in connection closure.
*/
bool persistent() const;
public:
/// HTTP-Version field in the first line of the message.
/// see RFC 7230 section 3.1
- Http::ProtocolVersion http_ver;
+ AnyP::ProtocolVersion http_ver;
HttpHeader header;
HttpHdrCc *cache_control;
/* Unsupported, writable, may disappear/change in the future
* For replies, sums _stored_ status-line, headers, and <CRLF>.
* Also used to report parsed header size if parse() is successful */
int hdr_sz;
int64_t content_length;
HttpMsgParseState pstate; /* the current parsing state */
BodyPipe::Pointer body_pipe; // optional pipeline to receive message body
// 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(MemBuf *buf, bool eol, Http::StatusCode *error);
=== modified file 'src/HttpReply.cc'
--- src/HttpReply.cc 2014-09-13 13:59:43 +0000
+++ src/HttpReply.cc 2014-12-06 18:20:56 +0000
@@ -136,102 +136,102 @@
return mb;
}
HttpReply *
HttpReply::make304() const
{
static const http_hdr_type ImsEntries[] = {HDR_DATE, HDR_CONTENT_TYPE, HDR_EXPIRES, HDR_LAST_MODIFIED, /* eof */ HDR_OTHER};
HttpReply *rv = new HttpReply;
int t;
HttpHeaderEntry *e;
/* rv->content_length; */
rv->date = date;
rv->last_modified = last_modified;
rv->expires = expires;
rv->content_type = content_type;
/* rv->cache_control */
/* rv->content_range */
/* rv->keep_alive */
- rv->sline.set(Http::ProtocolVersion(1,1), Http::scNotModified, NULL);
+ rv->sline.set(Http::ProtocolVersion(), Http::scNotModified, NULL);
for (t = 0; ImsEntries[t] != HDR_OTHER; ++t)
if ((e = header.findEntry(ImsEntries[t])))
rv->header.addEntry(e->clone());
/* rv->body */
return rv;
}
MemBuf *
HttpReply::packed304Reply()
{
/* Not as efficient as skipping the header duplication,
* but easier to maintain
*/
HttpReply *temp = make304();
MemBuf *rv = temp->pack();
delete temp;
return rv;
}
void
HttpReply::setHeaders(Http::StatusCode status, const char *reason,
const char *ctype, int64_t clen, time_t lmt, time_t expiresTime)
{
HttpHeader *hdr;
- sline.set(Http::ProtocolVersion(1,1), status, reason);
+ sline.set(Http::ProtocolVersion(), status, reason);
hdr = &header;
hdr->putStr(HDR_SERVER, visible_appname_string);
hdr->putStr(HDR_MIME_VERSION, "1.0");
hdr->putTime(HDR_DATE, squid_curtime);
if (ctype) {
hdr->putStr(HDR_CONTENT_TYPE, ctype);
content_type = ctype;
} else
content_type = String();
if (clen >= 0)
hdr->putInt64(HDR_CONTENT_LENGTH, clen);
if (expiresTime >= 0)
hdr->putTime(HDR_EXPIRES, expiresTime);
if (lmt > 0) /* this used to be lmt != 0 @?@ */
hdr->putTime(HDR_LAST_MODIFIED, lmt);
date = squid_curtime;
content_length = clen;
expires = expiresTime;
last_modified = lmt;
}
void
HttpReply::redirect(Http::StatusCode status, const char *loc)
{
HttpHeader *hdr;
- sline.set(Http::ProtocolVersion(1,1), status, NULL);
+ sline.set(Http::ProtocolVersion(), status, NULL);
hdr = &header;
hdr->putStr(HDR_SERVER, APP_FULLNAME);
hdr->putTime(HDR_DATE, squid_curtime);
hdr->putInt64(HDR_CONTENT_LENGTH, 0);
hdr->putStr(HDR_LOCATION, loc);
date = squid_curtime;
content_length = 0;
}
/* compare the validators of two replies.
* 1 = they match
* 0 = they do not match
*/
int
HttpReply::validatorsMatch(HttpReply const * otherRep) const
{
String one,two;
assert (otherRep);
/* Numbers first - easiest to check */
/* Content-Length */
@@ -460,41 +460,41 @@
debugs(58, 3, "HttpReply::sanityCheckStartLine: missing or invalid status number in '" << buf->content() << "'");
*error = Http::scInvalidHeader;
return false;
}
return true;
}
bool
HttpReply::parseFirstLine(const char *blk_start, const char *blk_end)
{
return sline.parse(protoPrefix, blk_start, blk_end);
}
/* handy: resets and returns -1 */
int
HttpReply::httpMsgParseError()
{
int result(HttpMsg::httpMsgParseError());
/* indicate an error in the status line */
- sline.set(Http::ProtocolVersion(1,1), Http::scInvalidHeader);
+ sline.set(Http::ProtocolVersion(), Http::scInvalidHeader);
return result;
}
/*
* Indicate whether or not we would usually expect an entity-body
* along with this response
*/
bool
HttpReply::expectingBody(const HttpRequestMethod& req_method, int64_t& theSize) const
{
bool expectBody = true;
if (req_method == Http::METHOD_HEAD)
expectBody = false;
else if (sline.status() == Http::scNoContent)
expectBody = false;
else if (sline.status() == Http::scNotModified)
expectBody = false;
else if (sline.status() < Http::scOkay)
expectBody = false;
=== modified file 'src/client_side_reply.cc'
--- src/client_side_reply.cc 2014-09-13 13:59:43 +0000
+++ src/client_side_reply.cc 2014-12-06 18:21:46 +0000
@@ -1452,41 +1452,41 @@
*/
authenticateFixHeader(reply, request->auth_user_request, request, 0, 1);
} else if (request->auth_user_request != NULL)
authenticateFixHeader(reply, request->auth_user_request, request, http->flags.accel, 0);
#endif
/* Append X-Cache */
httpHeaderPutStrf(hdr, HDR_X_CACHE, "%s from %s",
is_hit ? "HIT" : "MISS", getMyHostname());
#if USE_CACHE_DIGESTS
/* Append X-Cache-Lookup: -- temporary hack, to be removed @?@ @?@ */
httpHeaderPutStrf(hdr, HDR_X_CACHE_LOOKUP, "%s from %s:%d",
lookup_type ? lookup_type : "NONE",
getMyHostname(), getMyPort());
#endif
const bool maySendChunkedReply = !request->multipartRangeRequest() &&
reply->sline.protocol == AnyP::PROTO_HTTP && // response is HTTP
- (request->http_ver >= Http::ProtocolVersion(1, 1));
+ (request->http_ver >= Http::ProtocolVersion(1,1));
/* Check whether we should send keep-alive */
if (!Config.onoff.error_pconns && reply->sline.status() >= 400 && !request->flags.mustKeepalive) {
debugs(33, 3, "clientBuildReplyHeader: Error, don't keep-alive");
request->flags.proxyKeepalive = false;
} else if (!Config.onoff.client_pconns && !request->flags.mustKeepalive) {
debugs(33, 2, "clientBuildReplyHeader: Connection Keep-Alive not requested by admin or client");
request->flags.proxyKeepalive = false;
} else if (request->flags.proxyKeepalive && shutting_down) {
debugs(88, 3, "clientBuildReplyHeader: Shutting down, don't keep-alive.");
request->flags.proxyKeepalive = false;
} else if (request->flags.connectionAuth && !reply->keep_alive) {
debugs(33, 2, "clientBuildReplyHeader: Connection oriented auth but server side non-persistent");
request->flags.proxyKeepalive = false;
} else if (reply->bodySize(request->method) < 0 && !maySendChunkedReply) {
debugs(88, 3, "clientBuildReplyHeader: can't keep-alive, unknown body size" );
request->flags.proxyKeepalive = false;
} else if (fdUsageHigh()&& !request->flags.mustKeepalive) {
debugs(88, 3, "clientBuildReplyHeader: Not many unused FDs, can't keep-alive");
request->flags.proxyKeepalive = false;
@@ -1544,42 +1544,42 @@
/* Surrogate-Control requires Surrogate-Capability from upstream to pass on */
if ( hdr->has(HDR_SURROGATE_CONTROL) ) {
if (!request->header.has(HDR_SURROGATE_CAPABILITY)) {
hdr->delById(HDR_SURROGATE_CONTROL);
}
/* TODO: else case: drop any controls intended specifically for our surrogate ID */
}
httpHdrMangleList(hdr, request, ROR_REPLY);
}
void
clientReplyContext::cloneReply()
{
assert(reply == NULL);
reply = http->storeEntry()->getReply()->clone();
HTTPMSGLOCK(reply);
if (reply->sline.protocol == AnyP::PROTO_HTTP) {
- /* RFC 2616 requires us to advertise our 1.1 version (but only on real HTTP traffic) */
- reply->sline.version = Http::ProtocolVersion(1,1);
+ /* RFC 2616 requires us to advertise our version (but only on real HTTP traffic) */
+ reply->sline.version = Http::ProtocolVersion();
}
/* do header conversions */
buildReplyHeader();
}
/// Safely disposes of an entry pointing to a cache hit that we do not want.
/// We cannot just ignore the entry because it may be locking or otherwise
/// holding an associated cache resource of some sort.
void
clientReplyContext::forgetHit()
{
StoreEntry *e = http->storeEntry();
assert(e); // or we are not dealing with a hit
// We probably have not locked the entry earlier, unfortunately. We lock it
// now so that we can unlock two lines later (and trigger cleanup).
// Ideally, ClientHttpRequest::storeEntry() should lock/unlock, but it is
// used so inconsistently that simply adding locking there leads to bugs.
e->lock("clientReplyContext::forgetHit");
http->storeEntry(NULL);
=== modified file 'src/client_side_request.cc'
--- src/client_side_request.cc 2014-12-04 16:01:10 +0000
+++ src/client_side_request.cc 2014-12-06 18:23:29 +0000
@@ -349,42 +349,41 @@
* request, not subject to acceleration
* target overrides */
/*
* FIXME? Do we want to detect and handle internal requests of internal
* objects ?
*/
/* Internally created requests cannot have bodies today */
request->content_length = 0;
request->client_addr.setNoAddr();
#if FOLLOW_X_FORWARDED_FOR
request->indirect_client_addr.setNoAddr();
#endif /* FOLLOW_X_FORWARDED_FOR */
request->my_addr.setNoAddr(); /* undefined for internal requests */
request->my_addr.port(0);
- /* Our version is HTTP/1.1 */
- request->http_ver = Http::ProtocolVersion(1,1);
+ request->http_ver = Http::ProtocolVersion();
http->request = request;
HTTPMSGLOCK(http->request);
/* optional - skip the access check ? */
http->calloutContext = new ClientRequestContext(http);
http->calloutContext->http_access_done = false;
http->calloutContext->redirect_done = true;
http->calloutContext->no_cache_done = true;
http->doCallouts();
return 0;
}
bool
ClientRequestContext::httpStateIsValid()
=== modified file 'src/ftp/Elements.cc'
--- src/ftp/Elements.cc 2014-09-13 13:59:43 +0000
+++ src/ftp/Elements.cc 2014-12-06 16:51:25 +0000
@@ -14,41 +14,41 @@
#include "HttpReply.h"
#include "SBuf.h"
// FTP does not have a notion of a "protocol version" but we need something for
// compatibility with the current HttpMsg wrapping layer. We use version 1.1:
// * some ICAP services probably expect /1.0 or /1.1 when parsing HTTP headers;
// * FTP commands are sent on a "persistent by default" connection, just like
// HTTP/1.1. Using 1.1 leads to fewer exceptions in current code shared by
// HTTP and FTP.
AnyP::ProtocolVersion
Ftp::ProtocolVersion()
{
return AnyP::ProtocolVersion(AnyP::PROTO_FTP, 1, 1);
}
HttpReply *
Ftp::HttpReplyWrapper(const int ftpStatus, const char *ftpReason, const Http::StatusCode httpStatus, const int64_t clen)
{
HttpReply *const reply = new HttpReply;
- Http::ProtocolVersion httpVersion = Http::ProtocolVersion(
+ AnyP::ProtocolVersion httpVersion = Http::ProtocolVersion(
Ftp::ProtocolVersion().major, Ftp::ProtocolVersion().minor);
reply->sline.set(httpVersion, httpStatus);
HttpHeader &header = reply->header;
header.putTime(HDR_DATE, squid_curtime);
{
HttpHdrCc cc;
cc.Private(String());
header.putCc(&cc);
}
if (ftpStatus > 0)
header.putInt(HDR_FTP_STATUS, ftpStatus);
if (ftpReason)
header.putStr(HDR_FTP_REASON, ftpReason);
if (clen >= 0)
header.putInt64(HDR_CONTENT_LENGTH, clen);
reply->hdrCacheInit();
return reply;
}
=== modified file 'src/http.cc'
--- src/http.cc 2014-12-03 15:13:08 +0000
+++ src/http.cc 2014-12-06 18:20:14 +0000
@@ -705,41 +705,41 @@
Http::StatusCode error = Http::scNone;
HttpReply *newrep = new HttpReply;
const bool parsed = newrep->parse(readBuf, eof, &error);
if (!parsed && readBuf->contentSize() > 5 && strncmp(readBuf->content(), "HTTP/", 5) != 0 && strncmp(readBuf->content(), "ICY", 3) != 0) {
MemBuf *mb;
HttpReply *tmprep = new HttpReply;
tmprep->setHeaders(Http::scOkay, "Gatewaying", NULL, -1, -1, -1);
tmprep->header.putExt("X-Transformed-From", "HTTP/0.9");
mb = tmprep->pack();
newrep->parse(mb, eof, &error);
delete mb;
delete tmprep;
} else {
if (!parsed && error > 0) { // unrecoverable parsing error
debugs(11, 3, "processReplyHeader: Non-HTTP-compliant header: '" << readBuf->content() << "'");
flags.headers_parsed = true;
// XXX: when sanityCheck is gone and Http::StatusLine is used to parse,
// the sline should be already set the appropriate values during that parser stage
- newrep->sline.set(Http::ProtocolVersion(1,1), error);
+ newrep->sline.set(Http::ProtocolVersion(), error);
HttpReply *vrep = setVirginReply(newrep);
entry->replaceHttpReply(vrep);
ctx_exit(ctx);
return;
}
if (!parsed) { // need more data
assert(!error);
assert(!eof);
delete newrep;
ctx_exit(ctx);
return;
}
debugs(11, 2, "HTTP Server " << serverConnection);
debugs(11, 2, "HTTP Server REPLY:\n---------\n" << readBuf->content() << "\n----------");
header_bytes_read = headersEnd(readBuf->content(), readBuf->contentSize());
readBuf->consume(header_bytes_read);
}
@@ -1244,41 +1244,41 @@
}
if (!flags.headers_parsed && !eof) {
debugs(11, 9, HERE << "needs more at " << readBuf->contentSize());
flags.do_next_read = true;
/** \retval false If we have not finished parsing the headers and may get more data.
* Schedules more reads to retrieve the missing data.
*/
maybeReadVirginBody(); // schedules all kinds of reads; TODO: rename
return false;
}
/** If we are done with parsing, check for errors */
err_type error = ERR_NONE;
if (flags.headers_parsed) { // parsed headers, possibly with errors
// check for header parsing errors
if (HttpReply *vrep = virginReply()) {
const Http::StatusCode s = vrep->sline.status();
- const Http::ProtocolVersion &v = vrep->sline.version;
+ const AnyP::ProtocolVersion &v = vrep->sline.version;
if (s == Http::scInvalidHeader && v != Http::ProtocolVersion(0,9)) {
debugs(11, DBG_IMPORTANT, "WARNING: HTTP: Invalid Response: Bad header encountered from " << entry->url() << " AKA " << request->GetHost() << request->urlpath.termedBuf() );
error = ERR_INVALID_RESP;
} else if (s == Http::scHeaderTooLarge) {
fwd->dontRetry(true);
error = ERR_TOO_BIG;
} else {
return true; // done parsing, got reply, and no error
}
} else {
// parsed headers but got no reply
debugs(11, DBG_IMPORTANT, "WARNING: HTTP: Invalid Response: No reply at all for " << entry->url() << " AKA " << request->GetHost() << request->urlpath.termedBuf() );
error = ERR_INVALID_RESP;
}
} else {
assert(eof);
if (readBuf->hasContent()) {
error = ERR_INVALID_RESP;
debugs(11, DBG_IMPORTANT, "WARNING: HTTP: Invalid Response: Headers did not parse at all for " << entry->url() << " AKA " << request->GetHost() << request->urlpath.termedBuf() );
} else {
@@ -2065,47 +2065,47 @@
int64_t roffLimit = request->getRangeOffsetLimit();
if (NULL == request->range || !request->flags.cachable
|| request->range->offsetLimitExceeded(roffLimit) || request->flags.connectionAuth)
result = false;
debugs(11, 8, "decideIfWeDoRanges: range specs: " <<
request->range << ", cachable: " <<
request->flags.cachable << "; we_do_ranges: " << result);
return result;
}
/* build request prefix and append it to a given MemBuf;
* return the length of the prefix */
mb_size_t
HttpStateData::buildRequestPrefix(MemBuf * mb)
{
const int offset = mb->size;
- /* Uses a local httpver variable to print the HTTP/1.1 label
+ /* Uses a local httpver variable to print the HTTP label
* since the HttpRequest may have an older version label.
* XXX: This could create protocol bugs as the headers sent and
* flow control should all be based on the HttpRequest version
* not the one we are sending. Needs checking.
*/
- Http::ProtocolVersion httpver(1,1);
+ const AnyP::ProtocolVersion httpver = Http::ProtocolVersion();
const char * url;
if (_peer && !_peer->options.originserver)
url = urlCanonical(request);
else
url = request->urlpath.termedBuf();
mb->Printf(SQUIDSBUFPH " %s %s/%d.%d\r\n",
SQUIDSBUFPRINT(request->method.image()),
url && *url ? url : "/",
AnyP::ProtocolType_str[httpver.protocol],
httpver.major,httpver.minor);
/* build and pack headers */
{
HttpHeader hdr(hoRequest);
Packer p;
httpBuildRequestHeader(request, entry, fwd->al, &hdr, flags);
if (request->flags.pinned && request->flags.connectionAuth)
request->flags.authSent = true;
else if (hdr.has(HDR_AUTHORIZATION))
request->flags.authSent = true;
=== modified file 'src/http/ProtocolVersion.h'
--- src/http/ProtocolVersion.h 2014-09-13 13:59:43 +0000
+++ src/http/ProtocolVersion.h 2014-12-06 16:44:42 +0000
@@ -1,34 +1,39 @@
/*
* Copyright (C) 1996-2014 The Squid Software Foundation and contributors
*
* Squid software is distributed under GPLv2+ license and includes
* contributions from numerous individuals and organizations.
* Please see the COPYING and CONTRIBUTORS files for details.
*/
#ifndef SQUID_HTTP_PROTOCOLVERSION_H
#define SQUID_HTTP_PROTOCOLVERSION_H
#include "anyp/ProtocolVersion.h"
namespace Http
{
+/// HTTP version label information
+inline AnyP::ProtocolVersion
+ProtocolVersion(unsigned int aMajor, unsigned int aMinor)
+{
+ return AnyP::ProtocolVersion(AnyP::PROTO_HTTP,aMajor,aMinor);
+}
+
/**
- * Stores HTTP version label information.
+ * HTTP version label information.
*
* Squid being conditionally compliant with RFC 2616
* on both client and server connections the default
* value is HTTP/1.1.
*/
-class ProtocolVersion : public AnyP::ProtocolVersion
+inline AnyP::ProtocolVersion
+ProtocolVersion()
{
-public:
- ProtocolVersion() : AnyP::ProtocolVersion(AnyP::PROTO_HTTP,1,1) {}
-
- ProtocolVersion(unsigned int aMajor, unsigned int aMinor) : AnyP::ProtocolVersion(AnyP::PROTO_HTTP,aMajor,aMinor) {}
-};
+ return AnyP::ProtocolVersion(AnyP::PROTO_HTTP,1,1);
+}
}; // namespace Http
#endif /* SQUID_HTTP_PROTOCOLVERSION_H */
=== modified file 'src/http/StatusLine.cc'
--- src/http/StatusLine.cc 2014-09-13 13:59:43 +0000
+++ src/http/StatusLine.cc 2014-12-06 18:07:58 +0000
@@ -10,41 +10,41 @@
#include "squid.h"
#include "Debug.h"
#include "http/StatusLine.h"
#include "Packer.h"
void
Http::StatusLine::init()
{
set(Http::ProtocolVersion(), Http::scNone, NULL);
}
void
Http::StatusLine::clean()
{
set(Http::ProtocolVersion(), Http::scInternalServerError, NULL);
}
/* set values */
void
-Http::StatusLine::set(const Http::ProtocolVersion &newVersion, const Http::StatusCode newStatus, const char *newReason)
+Http::StatusLine::set(const AnyP::ProtocolVersion &newVersion, const Http::StatusCode newStatus, const char *newReason)
{
protocol = AnyP::PROTO_HTTP;
version = newVersion;
status_ = newStatus;
/* Note: no xstrdup for 'reason', assumes constant 'reasons' */
reason_ = newReason;
}
const char *
Http::StatusLine::reason() const
{
return reason_ ? reason_ : Http::StatusCodeString(status());
}
void
Http::StatusLine::packInto(Packer * p) const
{
assert(p);
/* local constants */
=== modified file 'src/http/StatusLine.h'
--- src/http/StatusLine.h 2014-09-13 13:59:43 +0000
+++ src/http/StatusLine.h 2014-12-06 16:47:44 +0000
@@ -18,61 +18,61 @@
namespace Http
{
/**
* Holds the values parsed from an HTTP reply status line.
*
* For example: HTTP/1.1 200 OK
*/
class StatusLine
{
public:
/// reset this status-line back to empty state
void init();
/// reset this status-line back to Internal Server Error state
void clean();
/// set this status-line to the given values
/// when reason is NULL the default message text for this StatusCode will be used
- void set(const Http::ProtocolVersion &newVersion, Http::StatusCode newStatus, const char *newReason = NULL);
+ void set(const AnyP::ProtocolVersion &newVersion, Http::StatusCode newStatus, const char *newReason = NULL);
/// retrieve the status code for this status line
Http::StatusCode status() const { return status_; }
/// retrieve the reason string for this status line
const char *reason() const;
/// pack fields using Packer
void packInto(Packer * p) const;
/**
* Parse a buffer and fill internal structures;
* \return true on success, false otherwise
*/
bool parse(const String &protoPrefix, const char *start, const char *end);
public:
/* public, read only */
/**
* By rights protocol name should be a constant "HTTP", with no need for this field to exist.
* However there are protocols which violate HTTP by sending their own custom formats
* back with other protocol names (ICY streaming format being the current major problem).
*/
- // XXX: protocol is part of Http::ProtocolVersion. We should be able to use version.protocol instead now.
+ // XXX: protocol is part of AnyP::ProtocolVersion. We should be able to use version.protocol instead now.
AnyP::ProtocolType protocol;
- Http::ProtocolVersion version; ///< breakdown of protocol version label: (HTTP/ICY) and (0.9/1.0/1.1)
+ AnyP::ProtocolVersion version; ///< breakdown of protocol version label: (HTTP/ICY) and (0.9/1.0/1.1)
private:
/// status code. ie 100 ... 200 ... 404 ... 599
Http::StatusCode status_;
/// points to a _constant_ string (default or supplied), never free()d
const char *reason_;
};
} // namespace Http
#endif /* SQUID_HTTP_STATUSLINE_H */
=== modified file 'src/icmp/net_db.cc'
--- src/icmp/net_db.cc 2014-12-01 04:05:48 +0000
+++ src/icmp/net_db.cc 2014-12-06 18:21:55 +0000
@@ -1276,41 +1276,41 @@
#if USE_ICMP
CachePeer *p = (CachePeer *)data;
char *uri;
netdbExchangeState *ex;
StoreIOBuffer tempBuffer;
CBDATA_INIT_TYPE(netdbExchangeState);
ex = cbdataAlloc(netdbExchangeState);
ex->p = cbdataReference(p);
uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb");
debugs(38, 3, "netdbExchangeStart: Requesting '" << uri << "'");
assert(NULL != uri);
ex->r = HttpRequest::CreateFromUrl(uri);
if (NULL == ex->r) {
debugs(38, DBG_IMPORTANT, "netdbExchangeStart: Bad URI " << uri);
return;
}
HTTPMSGLOCK(ex->r);
assert(NULL != ex->r);
- ex->r->http_ver = Http::ProtocolVersion(1,1);
+ ex->r->http_ver = Http::ProtocolVersion();
ex->connstate = STATE_HEADER;
ex->e = storeCreateEntry(uri, uri, RequestFlags(), Http::METHOD_GET);
ex->buf_sz = NETDB_REQBUF_SZ;
assert(NULL != ex->e);
ex->sc = storeClientListAdd(ex->e, ex);
tempBuffer.offset = 0;
tempBuffer.length = ex->buf_sz;
tempBuffer.data = ex->buf;
storeClientCopy(ex->sc, ex->e, tempBuffer,
netdbExchangeHandleReply, ex);
ex->r->flags.loopDetected = true; /* cheat! -- force direct */
// XXX: send as Proxy-Authenticate instead
if (p->login)
ex->r->url.userInfo(SBuf(p->login));
urlCanonical(ex->r);
FwdState::fwdStart(Comm::ConnectionPointer(), ex->e, ex->r);
=== modified file 'src/servers/HttpServer.cc'
--- src/servers/HttpServer.cc 2014-11-10 12:11:20 +0000
+++ src/servers/HttpServer.cc 2014-12-06 18:24:57 +0000
@@ -240,41 +240,41 @@
{
debugs(33, 5, "Body Continuation written");
clientProcessRequest(this, parser_, context.getRaw());
}
void
Http::Server::processParsedRequest(ClientSocketContext *context)
{
if (!buildHttpRequest(context))
return;
if (Config.accessList.forceRequestBodyContinuation) {
ClientHttpRequest *http = context->http;
HttpRequest *request = http->request;
ACLFilledChecklist bodyContinuationCheck(Config.accessList.forceRequestBodyContinuation, request, NULL);
if (bodyContinuationCheck.fastCheck() == ACCESS_ALLOWED) {
debugs(33, 5, "Body Continuation forced");
request->forcedBodyContinuation = true;
//sendControlMsg
HttpReply::Pointer rep = new HttpReply;
- rep->sline.set(Http::ProtocolVersion(1,1), Http::scContinue);
+ rep->sline.set(Http::ProtocolVersion(), Http::scContinue);
typedef UnaryMemFunT<Http::Server, ClientSocketContext::Pointer> CbDialer;
const AsyncCall::Pointer cb = asyncCall(11, 3, "Http::Server::proceedAfterBodyContinuation", CbDialer(this, &Http::Server::proceedAfterBodyContinuation, ClientSocketContext::Pointer(context)));
sendControlMsg(HttpControlMsg(rep, cb));
return;
}
}
clientProcessRequest(this, parser_, context);
}
void
Http::Server::noteBodyConsumerAborted(BodyPipe::Pointer ptr)
{
ConnStateData::noteBodyConsumerAborted(ptr);
stopReceiving("virgin request body consumer aborted"); // closes ASAP
}
void
Http::Server::handleReply(HttpReply *rep, StoreIOBuffer receivedData)
{
-------------- next part --------------
A non-text attachment was scrubbed...
Name: HttpProtocolVersion_update_mk1.patch.sig
Type: application/octet-stream
Size: 287 bytes
Desc: not available
URL: <http://lists.squid-cache.org/pipermail/squid-dev/attachments/20141207/f7a4f1a3/attachment-0001.obj>
More information about the squid-dev
mailing list