src/esi/Makefile \
src/eui/Makefile \
src/format/Makefile \
+ src/http/Makefile \
src/icmp/Makefile \
src/ident/Makefile \
src/ip/Makefile \
{
public:
- HttpDetails() : method(METHOD_NONE), code(0), content_type(NULL),
+ HttpDetails() : method(Http::METHOD_NONE), code(0), content_type(NULL),
timedout(false), aborted(false) {}
HttpRequestMethod method;
{
if (sline.version.major < 1)
return -1;
- else if (method.id() == METHOD_HEAD)
+ else if (method.id() == Http::METHOD_HEAD)
return 0;
else if (sline.status == HTTP_OK)
(void) 0; /* common case, continue */
{
bool expectBody = true;
- if (req_method == METHOD_HEAD)
+ if (req_method == Http::METHOD_HEAD)
expectBody = false;
else if (sline.status == HTTP_NO_CONTENT)
expectBody = false;
void
HttpRequest::init()
{
- method = METHOD_NONE;
+ method = Http::METHOD_NONE;
protocol = AnyP::PROTO_NONE;
urlpath = NULL;
login[0] = '\0';
}
/* See if the request buffer starts with a known HTTP request method. */
- if (HttpRequestMethod(buf->content(),NULL) == METHOD_NONE) {
+ if (HttpRequestMethod(buf->content(),NULL) == Http::METHOD_NONE) {
debugs(73, 3, "HttpRequest::sanityCheckStartLine: did not find HTTP request method");
*error = HTTP_INVALID_HEADER;
return false;
const char *t = start + strcspn(start, w_space);
method = HttpRequestMethod(start, t);
- if (method == METHOD_NONE)
+ if (method == Http::METHOD_NONE)
return false;
start = t + strspn(t, w_space);
HttpRequest *
HttpRequest::CreateFromUrl(char * url)
{
- return urlParse(METHOD_GET, url, NULL);
+ return urlParse(Http::METHOD_GET, url, NULL);
}
-/*
+/**
* Are responses to this request possible cacheable ?
* If false then no matter what the response must not be cached.
*/
bool
-HttpRequest::cacheable() const
+HttpRequest::maybeCacheable()
{
// Intercepted request with Host: header which cannot be trusted.
// Because it failed verification, or someone bypassed the security tests
if (!flags.hostVerified && (flags.intercepted || flags.spoofClientIp))
return false;
- if (protocol == AnyP::PROTO_HTTP)
- return httpCachable(method);
-
- /*
- * The below looks questionable: what non HTTP protocols use connect,
- * trace, put and post? RC
- */
+ switch(protocol)
+ {
+ case AnyP::PROTO_HTTP:
+ if (!method.respMaybeCacheable())
+ return false;
- if (!method.isCacheble())
- return false;
+ // XXX: this would seem the correct place to detect request cache-controls
+ // no-store, private and related which block cacheability
+ break;
- /*
- * XXX POST may be cached sometimes.. ignored
- * for now
- */
- if (protocol == AnyP::PROTO_GOPHER)
- return gopherCachable(this);
+ case AnyP::PROTO_GOPHER:
+ if (!gopherCachable(this))
+ return false;
+ break;
- if (protocol == AnyP::PROTO_CACHE_OBJECT)
+ case AnyP::PROTO_CACHE_OBJECT:
return false;
+ //case AnyP::PROTO_FTP:
+ default:
+ break;
+ }
+
return true;
}
virtual HttpRequest *clone() const;
- /* are responses to this request potentially cachable */
- bool cacheable() const;
+ /// Whether response to this request is potentially cachable
+ /// \retval false Not cacheable.
+ /// \retval true Possibly cacheable. Response factors will determine.
+ bool maybeCacheable();
bool conditional() const; ///< has at least one recognized If-* header
-
/*
* DEBUG: section 73 HTTP Request
- * AUTHOR: Duane Wessels
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
*/
#include "squid.h"
#include "HttpRequestMethod.h"
#include "wordlist.h"
-const char* HttpRequestMethod::RequestMethodStr[] = {
- "NONE",
- "GET",
- "POST",
- "PUT",
- "HEAD",
- "CONNECT",
- "TRACE",
- "PURGE",
- "OPTIONS",
- "DELETE",
- "PROPFIND",
- "PROPPATCH",
- "MKCOL",
- "COPY",
- "MOVE",
- "LOCK",
- "UNLOCK",
- "BMOVE",
- "BDELETE",
- "BPROPFIND",
- "BPROPPATCH",
- "BCOPY",
- "SEARCH",
- "SUBSCRIBE",
- "UNSUBSCRIBE",
- "POLL",
- "REPORT",
- "MKACTIVITY",
- "CHECKOUT",
- "MERGE",
- "ERROR"
-};
-
-static
-_method_t &operator++ (_method_t &aMethod)
+static Http::MethodType &
+operator++ (Http::MethodType &aMethod)
{
int tmp = (int)aMethod;
- aMethod = (_method_t)(++tmp);
+ aMethod = (Http::MethodType)(++tmp);
return aMethod;
}
-/*
+/**
* Construct a HttpRequestMethod from a NULL terminated string such as "GET"
* or from a range of chars, * such as "GET" from "GETFOOBARBAZ"
* (pass in pointer to G and pointer to F.)
*/
-HttpRequestMethod::HttpRequestMethod(char const *begin, char const *end) : theMethod (METHOD_NONE)
+HttpRequestMethod::HttpRequestMethod(char const *begin, char const *end) : theMethod (Http::METHOD_NONE)
{
if (begin == NULL)
return;
end = begin + strcspn(begin, w_space);
if (end == begin) {
- theMethod = METHOD_NONE;
+ theMethod = Http::METHOD_NONE;
return;
}
- for (++theMethod; theMethod < METHOD_ENUM_END; ++theMethod) {
- if (0 == strncasecmp(begin, RequestMethodStr[theMethod], end-begin)) {
+ for (++theMethod; theMethod < Http::METHOD_ENUM_END; ++theMethod) {
+ if (0 == strncasecmp(begin, Http::MethodType_str[theMethod], end-begin)) {
return;
}
}
// if method not found and method string is not null then it is other method
- theMethod = METHOD_OTHER;
+ theMethod = Http::METHOD_OTHER;
theImage.limitInit(begin,end-begin);
}
-/** \todo AYJ: this _should_ be obsolete. Since all such methods fit nicely into METHOD_OTHER now. */
-void
-HttpRequestMethod::AddExtension(const char *mstr)
+char const*
+HttpRequestMethod::image() const
{
-#if 0 /* obsolete now that we have METHOD_OTHER always enabled */
- _method_t method = METHOD_NONE;
-
- for (++method; method < METHOD_ENUM_END; ++method) {
- if (0 == strcmp(mstr, RequestMethodStr[method])) {
- debugs(23, 2, "Extension method '" << mstr << "' already exists");
- return;
+ if (Http::METHOD_OTHER != theMethod) {
+ return Http::MethodType_str[theMethod];
+ } else {
+ if (theImage.size()>0) {
+ return theImage.termedBuf();
+ } else {
+ return "METHOD_OTHER";
}
+ }
+}
- if (0 != strncmp("%EXT", RequestMethodStr[method], 4))
- continue;
+bool
+HttpRequestMethod::isHttpSafe() const
+{
+ // Only a few methods are defined as safe. All others are "unsafe"
- /* Don't free statically allocated "%EXTnn" string */
- RequestMethodStr[method] = xstrdup(mstr);
+ // NOTE:
+ // All known RFCs which register methods are listed in comments.
+ // if there is one not listed which defines methods, it needs
+ // checking and adding. If only to say it is known to define none.
- debugs(23, DBG_IMPORTANT, "Extension method '" << mstr << "' added, enum=" << method);
+ switch(theMethod)
+ {
+ // RFC 2068 - none
- return;
- }
+ // RFC 2616 section 9.1.1
+ case Http::METHOD_GET:
+ case Http::METHOD_HEAD:
+ case Http::METHOD_OPTIONS:
- debugs(23, DBG_IMPORTANT, "WARNING: Could not add new extension method '" << mstr << "' due to lack of array space");
-#endif
-}
+ // RFC 3253 section 3.6
+ case Http::METHOD_REPORT:
-void
-HttpRequestMethod::Configure(SquidConfig &cfg)
-{
-#if 0 /* extension methods obsolete now that we have METHOD_OTHER always enabled */
- wordlist *w = cfg.ext_methods;
+ // RFC 3648 - none
+ // RFC 3744 - none
+ // RFC 4437 - none
+ // RFC 4791 - none
- while (w) {
- char *s;
+ // RFC 4918 section 9.1
+ case Http::METHOD_PROPFIND:
- for (s = w->key; *s; ++s)
- *s = xtoupper(*s);
+ // RFC 5323 section 2
+ case Http::METHOD_SEARCH:
- AddExtension(w->key);
+ // RFC 5789 - none
+ // RFC 5842 - none
- w = w->next;
- }
-#endif
-}
+ return true;
-char const*
-HttpRequestMethod::image() const
-{
- if (METHOD_OTHER != theMethod) {
- return RequestMethodStr[theMethod];
- } else {
- if (theImage.size()>0) {
- return theImage.termedBuf();
- } else {
- return "METHOD_OTHER";
- }
+ default:
+ return false;
}
}
bool
-HttpRequestMethod::isCacheble() const
+HttpRequestMethod::isIdempotent() const
{
- // TODO: optimize the lookup with a precomputed flags array
- // XXX: the list seems wrong; e.g., Is METHOD_DELETE really cachable?
- // see also http.cc::httpCachable()
+ // Only a few methods are defined as idempotent.
+
+ // NOTE:
+ // All known RFCs which register methods are listed in comments.
+ // if there is one not listed which defines methods, it needs
+ // checking and adding. If only to say it is known to define none.
+
+ switch(theMethod)
+ {
+ // RFC 2068 - TODO check LINK/UNLINK definition
+
+ // RFC 2616 section 9.1.2
+ case Http::METHOD_GET:
+ case Http::METHOD_HEAD:
+ case Http::METHOD_PUT:
+ case Http::METHOD_DELETE:
+ case Http::METHOD_OPTIONS:
+ case Http::METHOD_TRACE:
+
+ // RFC 3253 - TODO check
+ // RFC 3648 - TODO check
+ // RFC 3744 - TODO check
+ // RFC 4437 - TODO check
+ // RFC 4791 - TODO check
+
+ // RFC 4918 section 9
+ case Http::METHOD_PROPFIND:
+ case Http::METHOD_PROPPATCH:
+ case Http::METHOD_MKCOL:
+ case Http::METHOD_COPY:
+ case Http::METHOD_MOVE:
+ case Http::METHOD_UNLOCK:
+
+ // RFC 5323 - TODO check
+ // RFC 5789 - TODO check
+ // RFC 5842 - TODO check
- if (theMethod == METHOD_CONNECT)
- return false;
+ return true;
- if (theMethod == METHOD_TRACE)
+ default:
return false;
+ }
+}
- if (theMethod == METHOD_PUT)
- return false;
+bool
+HttpRequestMethod::respMaybeCacheable() const
+{
+ // Only a few methods are defined as cacheable.
+ // All other methods from the below RFC are "MUST NOT cache"
+ switch(theMethod)
+ {
+ // RFC 2616 section 9
+ case Http::METHOD_GET:
+ case Http::METHOD_HEAD:
+ return true;
+#if WHEN_POST_CACHE_SUPPORTED
+ case Http::METHOD_POST: // Special case.
+ // RFC 2616 specifies POST as possibly cacheable
+ // However, Squid does not implement the required checks yet
+ return true;
+#endif
- if (theMethod == METHOD_POST)
- return false;
+ // RFC 4918 section 9
+#if WHEN_PROPFIND_CACHE_SUPPORTED
+ case Http::METHOD_PROPFIND: // Special case.
+ // RFC 4918 specifies PROPFIND as possibly cacheable
+ // However, Squid does not implement the required checks yet
+ return true;
+#endif
- if (theMethod == METHOD_OTHER)
- return false;
+ // RFC 5323 section 2 - defines no cacheable methods
+
+ // RFC 3253
+#if WHEN_CC_NOCACHE_DOES_REVALIDATES_IS_CONFIRMED
+ case Http::METHOD_CHECKOUT:
+ case Http::METHOD_CHECKIN:
+ case Http::METHOD_UNCHECKOUT:
+ case Http::METHOD_MKWORKSPACE:
+ case Http::METHOD_VERSION_CONTROL:
+ case Http::METHOD_UPDATE:
+ case Http::METHOD_LABEL:
+ case Http::METHOD_MERGE:
+ case Http::METHOD_BASELINE_CONTROL:
+ case Http::METHOD_MKACTIVITY:
+ // RFC 3253 defines these methods using "MUST include Cache-Control: no-cache".
+ //
+ // XXX: follow RFC 2616 definition of "no-cache" meaning "MAY cache, always revalidate"
+ // XXX: or treat as unregistered/undefined methods ??
+ // However, Squid may not implement the required revalidation checks yet
+ return ??;
+#endif
- return true;
+ // Special Squid method tokens are not cacheable.
+ // RFC 2616 defines all unregistered or unspecified methods as non-cacheable
+ // until such time as an RFC defines them cacheable.
+ default:
+ return false;
+ }
}
bool
-HttpRequestMethod::purgesOthers() const
+HttpRequestMethod::shouldInvalidate() const
{
- // TODO: optimize the lookup with a precomputed flags array
-
switch (theMethod) {
- /* common sense suggests purging is not required? */
- case METHOD_GET: // XXX: but we do purge HEAD on successful GET
- case METHOD_HEAD:
- case METHOD_NONE:
- case METHOD_CONNECT:
- case METHOD_TRACE:
- case METHOD_OPTIONS:
- case METHOD_PROPFIND:
- case METHOD_BPROPFIND:
- case METHOD_COPY:
- case METHOD_BCOPY:
- case METHOD_LOCK:
- case METHOD_UNLOCK:
- case METHOD_SEARCH:
- return false;
-
- /* purging mandated by RFC 2616 */
- case METHOD_POST:
- case METHOD_PUT:
- case METHOD_DELETE:
+ /* RFC 2616 section 13.10 - "MUST invalidate" */
+ case Http::METHOD_POST:
+ case Http::METHOD_PUT:
+ case Http::METHOD_DELETE:
return true;
- /* purging suggested by common sense */
- case METHOD_PURGE:
+ /* Squid extension to force invalidation */
+ case Http::METHOD_PURGE:
return true;
/*
* understand SHOULD invalidate any entities referred to by the
* Request-URI.
*/
- case METHOD_OTHER:
- default:
+ case Http::METHOD_OTHER:
return true;
+
+ default:
+ // Methods which are known but not required to invalidate.
+ return false;
}
+}
- return true; // not reached, but just in case
+bool
+HttpRequestMethod::purgesOthers() const
+{
+ if (shouldInvalidate())
+ return true;
+
+ switch (theMethod) {
+ /* common sense suggests purging is not required? */
+ case Http::METHOD_GET: // XXX: but we do purge HEAD on successful GET
+ case Http::METHOD_HEAD:
+ case Http::METHOD_NONE:
+ case Http::METHOD_CONNECT:
+ case Http::METHOD_TRACE:
+ case Http::METHOD_OPTIONS:
+ case Http::METHOD_PROPFIND:
+ case Http::METHOD_COPY:
+ case Http::METHOD_LOCK:
+ case Http::METHOD_UNLOCK:
+ case Http::METHOD_SEARCH:
+ return false;
+
+ default:
+ return true;
+ }
}
-/*
- *
- * SQUID Web Proxy Cache http://www.squid-cache.org/
- * ----------------------------------------------------------
- *
- * Squid is the result of efforts by numerous individuals from
- * the Internet community; see the CONTRIBUTORS file for full
- * details. Many organizations have provided support for Squid's
- * development; see the SPONSORS file for full details. Squid is
- * Copyrighted (C) 2001 by the Regents of the University of
- * California; see the COPYRIGHT file for full details. Squid
- * incorporates software developed and/or copyrighted by other
- * sources; see the CREDITS file for full details.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
- *
- */
-
#ifndef SQUID_HTTPREQUESTMETHOD_H
#define SQUID_HTTPREQUESTMETHOD_H
+#include "http/MethodType.h"
+#include "SquidString.h"
#include "SquidString.h"
class SquidConfig;
#include <iosfwd>
-enum _method_t {
- METHOD_NONE, /* 000 */
- METHOD_GET, /* 001 */
- METHOD_POST, /* 010 */
- METHOD_PUT, /* 011 */
- METHOD_HEAD, /* 100 */
- METHOD_CONNECT, /* 101 */
- METHOD_TRACE, /* 110 */
- METHOD_PURGE, /* 111 */
- METHOD_OPTIONS,
- METHOD_DELETE, /* RFC2616 section 9.7 */
- METHOD_PROPFIND,
- METHOD_PROPPATCH,
- METHOD_MKCOL,
- METHOD_COPY,
- METHOD_MOVE,
- METHOD_LOCK,
- METHOD_UNLOCK,
- METHOD_BMOVE,
- METHOD_BDELETE,
- METHOD_BPROPFIND,
- METHOD_BPROPPATCH,
- METHOD_BCOPY,
- METHOD_SEARCH,
- METHOD_SUBSCRIBE,
- METHOD_UNSUBSCRIBE,
- METHOD_POLL,
- METHOD_REPORT,
- METHOD_MKACTIVITY,
- METHOD_CHECKOUT,
- METHOD_MERGE,
- METHOD_OTHER,
- METHOD_ENUM_END // MUST be last, (yuck) this is used as an array-initialization index constant!
-};
-
/**
* This class represents an HTTP Request METHOD
* - i.e. PUT, POST, GET etc.
* It has a runtime extension facility to allow it to
* efficiently support new methods
- \ingroup POD
*/
class HttpRequestMethod
{
public:
- static void AddExtension(const char *methodString);
- static void Configure(SquidConfig &Config);
+// static void Configure(SquidConfig &Config);
- HttpRequestMethod() : theMethod(METHOD_NONE), theImage() {}
+ HttpRequestMethod() : theMethod(Http::METHOD_NONE), theImage() {}
- HttpRequestMethod(_method_t const aMethod) : theMethod(aMethod), theImage() {}
+ HttpRequestMethod(Http::MethodType const aMethod) : theMethod(aMethod), theImage() {}
/**
\param begin string to convert to request method.
return *this;
}
- HttpRequestMethod & operator = (_method_t const aMethod) {
+ HttpRequestMethod & operator = (Http::MethodType const aMethod) {
theMethod = aMethod;
theImage.clean();
return *this;
}
- bool operator == (_method_t const & aMethod) const { return theMethod == aMethod; }
+ bool operator == (Http::MethodType const & aMethod) const { return theMethod == aMethod; }
bool operator == (HttpRequestMethod const & aMethod) const {
return theMethod == aMethod.theMethod &&
- (theMethod != METHOD_OTHER || theImage == aMethod.theImage);
+ (theMethod != Http::METHOD_OTHER || theImage == aMethod.theImage);
}
- bool operator != (_method_t const & aMethod) const { return theMethod != aMethod; }
+ bool operator != (Http::MethodType const & aMethod) const { return theMethod != aMethod; }
bool operator != (HttpRequestMethod const & aMethod) const {
return !operator==(aMethod);
}
HttpRequestMethod& operator++() {
// TODO: when this operator is used in more than one place,
// replace it with HttpRequestMethods::Iterator API
- // XXX: this interface can create METHOD_OTHER without an image
- assert(theMethod < METHOD_ENUM_END);
- theMethod = (_method_t)(1 + (int)theMethod);
+ // XXX: this interface can create Http::METHOD_OTHER without an image
+ assert(theMethod < Http::METHOD_ENUM_END);
+ theMethod = (Http::MethodType)(1 + (int)theMethod);
return *this;
}
/** Get an ID representation of the method.
- \retval METHOD_NONE the method is unset
- \retval METHOD_OTHER the method is not recognized and has no unique ID
- \retval * the method is on of the recognized HTTP methods.
+ * \retval Http::METHOD_NONE the method is unset
+ * \retval Http::METHOD_OTHER the method is not recognized and has no unique ID
+ * \retval * the method is on of the recognized HTTP methods.
*/
- _method_t id() const { return theMethod; }
+ Http::MethodType id() const { return theMethod; }
/** Get a char string representation of the method. */
char const * image() const;
- bool isCacheble() const;
+ /// Whether this method is defined as a "safe" in HTTP/1.1
+ /// see RFC 2616 section 9.1.1
+ bool isHttpSafe() const;
+
+ /// Whether this method is defined as "idempotent" in HTTP/1.1
+ /// see RFC 2616 section 9.1.2
+ bool isIdempotent() const;
+
+ /** Whether responses to this method MAY be cached.
+ * \retval false Not cacheable.
+ * \retval true Possibly cacheable. Other details will determine.
+ */
+ bool respMaybeCacheable() const;
+
+ /** Whether this method SHOULD (or MUST) invalidate existing cached entries.
+ * Invalidation is always determined by the response
+ *
+ * RFC 2616 defines invalidate as either immediate purge
+ * or delayed explicit revalidate all stored copies on next use.
+ *
+ * \retval true SHOULD invalidate. Response details can raise this to a MUST.
+ * \retval false Other details will determine. Method is not a factor.
+ */
+ bool shouldInvalidate() const;
+
+ /* Whether this method invalidates existing cached entries.
+ * Kept for backward-compatibility. This is the old 2.x-3.2 invalidation behaviour.
+ *
+ * NOTE:
+ * purgesOthers differs from shouldInvalidate() in that purgesOthers() returns
+ * true on any methods the MAY invalidate (Squid opts to do so).
+ * shouldInvalidate() only returns true on methods which SHOULD invalidate.
+ */
bool purgesOthers() const;
private:
static const char *RequestMethodStr[];
- _method_t theMethod; ///< Method type
- String theImage; ///< Used for store METHOD_OTHER only
+ Http::MethodType theMethod; ///< Method type
+ String theImage; ///< Used for storing the Http::METHOD_OTHER only. A copy of the parsed method text.
};
inline std::ostream &
}
inline const char*
-RequestMethodStr(const _method_t m)
+RequestMethodStr(const Http::MethodType m)
{
return HttpRequestMethod(m).image();
}
endif
DIST_SUBDIRS += auth
-SUBDIRS += ip icmp ident log ipc mgr
-DIST_SUBDIRS += ip icmp ident log ipc mgr
+SUBDIRS += http ip icmp ident log ipc mgr
+DIST_SUBDIRS += http ip icmp ident log ipc mgr
if ENABLE_SSL
SUBDIRS += ssl
anyp/libanyp.la \
comm/libcomm.la \
eui/libeui.la \
+ http/libsquid-http.la \
icmp/libicmp.la icmp/libicmp-core.la \
log/liblog.la \
format/libformat.la \
nodist_tests_testACLMaxUserIP_SOURCES= \
$(TESTSOURCES)
tests_testACLMaxUserIP_LDADD= \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
$(DISKIO_GEN_SOURCE)
# comm.cc only requires comm/libcomm.la until fdc_table is dead.
tests_testCacheManager_LDADD = \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
SquidMath.h \
swap_log_op.cc
tests_testDiskIO_LDADD = \
+ http/libsquid-http.la \
SquidConfig.o \
CommCalls.o \
DnsLookupDetails.o \
$(BUILT_SOURCES) \
$(DISKIO_GEN_SOURCE)
tests_testEvent_LDADD = \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
$(BUILT_SOURCES) \
$(DISKIO_GEN_SOURCE)
tests_testEventLoop_LDADD = \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
$(BUILT_SOURCES) \
$(DISKIO_GEN_SOURCE)
tests_test_http_range_LDADD = \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
nodist_tests_testHttpParser_SOURCES = \
$(TESTSOURCES)
tests_testHttpParser_LDADD= \
+ http/libsquid-http.la \
SquidConfig.o \
base/libbase.la \
ip/libip.la \
comm/libcomm.la \
log/liblog.la \
format/libformat.la \
+ http/libsquid-http.la \
$(REPL_OBJS) \
$(ADAPTATION_LIBS) \
$(ESI_LIBS) \
swap_log_op.cc
tests_testStore_LDADD= \
+ http/libsquid-http.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
acl/libacls.la \
SquidMath.h \
swap_log_op.cc
tests_testUfs_LDADD = \
+ http/libsquid-http.la \
CommCalls.o \
DnsLookupDetails.o \
$(AUTH_ACL_LIBS) \
SquidMath.h \
$(TESTSOURCES)
tests_testRock_LDADD = \
+ http/libsquid-http.la \
libsquid.la \
comm/libcomm.la \
anyp/libanyp.la \
nodist_tests_testURL_SOURCES = \
$(BUILT_SOURCES)
tests_testURL_LDADD = \
+ http/libsquid-http.la \
anyp/libanyp.la \
$(AUTH_ACL_LIBS) \
ident/libident.la \
assert(NULL != req);
asState->request = HTTPMSGLOCK(req);
- if ((e = storeGetPublic(asres, METHOD_GET)) == NULL) {
- e = storeCreateEntry(asres, asres, RequestFlags(), METHOD_GET);
+ if ((e = storeGetPublic(asres, Http::METHOD_GET)) == NULL) {
+ e = storeCreateEntry(asres, asres, RequestFlags(), Http::METHOD_GET);
asState->sc = storeClientListAdd(e, asState);
FwdState::fwdStart(Comm::ConnectionPointer(), e, asState->request);
} else {
const int id = aMethod.hostId();
Must(METHOD_NONE < id && id < METHOD_ENUM_END);
Must(id != METHOD_OTHER);
- theMessage.method = HttpRequestMethod(static_cast<_method_t>(id));
+ theMessage.method = HttpRequestMethod(static_cast<Http::MethodType>(id));
} else {
const std::string &image = aMethod.image();
theMessage.method = HttpRequestMethod(image.data(),
else if (HttpRequest *req = dynamic_cast<HttpRequest*>(msg))
method = req->method;
else
- method = METHOD_NONE;
+ method = Http::METHOD_NONE;
int64_t size;
// expectingBody returns true for zero-sized bodies, but we will not
// get a pipe for that body, so we treat the message as bodyless
- if (method != METHOD_NONE && msg->expectingBody(method, size) && size) {
+ if (method != Http::METHOD_NONE && msg->expectingBody(method, size) && size) {
debugs(93, 6, HERE << "expects virgin body from " <<
virgin.body_pipe << "; size: " << size);
return;
}
- if (static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->PostWorkaround && request->method != METHOD_GET) {
+ if (static_cast<Auth::Digest::Config*>(Auth::Config::Find("digest"))->PostWorkaround && request->method != Http::METHOD_GET) {
/* Ugly workaround for certain very broken browsers using the
* wrong method to calculate the request-digest on POST request.
* This should be deleted once Digest authentication becomes more
*/
DigestCalcResponse(SESSIONKEY, authenticateDigestNonceNonceb64(digest_request->nonce),
digest_request->nc, digest_request->cnonce, digest_request->qop,
- RequestMethodStr(METHOD_GET), digest_request->uri, HA2, Response);
+ RequestMethodStr(Http::METHOD_GET), digest_request->uri, HA2, Response);
if (strcasecmp(digest_request->response, Response)) {
auth_user->credentials(Auth::Failed);
Config2.effectiveGroupID = grp->gr_gid;
}
- HttpRequestMethod::Configure(Config);
#if USE_SSL
debugs(3, DBG_IMPORTANT, "Initializing https proxy context");
{
switch (r->method.id()) {
- case METHOD_GET:
+ case Http::METHOD_GET:
- case METHOD_HEAD:
+ case Http::METHOD_HEAD:
/* We do not want to see a request entity on GET/HEAD requests */
return (r->content_length <= 0 || Config.onoff.request_entities);
int r;
/* pre-set these values to make aborting simpler */
- *method_p = METHOD_NONE;
+ *method_p = Http::METHOD_NONE;
/* NP: don't be tempted to move this down or remove again.
* It's the only DDoS protection old-String has against long URL */
*method_p = HttpRequestMethod(&hp->buf[hp->req.m_start], &hp->buf[hp->req.m_end]+1);
/* deny CONNECT via accelerated ports */
- if (*method_p == METHOD_CONNECT && csd && csd->port && csd->port->accel) {
+ if (*method_p == Http::METHOD_CONNECT && csd && csd->port && csd->port->accel) {
debugs(33, DBG_IMPORTANT, "WARNING: CONNECT method received on " << csd->port->protocol << " Accelerator port " << csd->port->s.GetPort() );
/* XXX need a way to say "this many character length string" */
debugs(33, DBG_IMPORTANT, "WARNING: for request: " << hp->buf);
return parseHttpRequestAbort(csd, "error:method-not-allowed");
}
- if (*method_p == METHOD_NONE) {
+ if (*method_p == Http::METHOD_NONE) {
/* XXX need a way to say "this many character length string" */
debugs(33, DBG_IMPORTANT, "clientParseRequestMethod: Unsupported method in request '" << hp->buf << "'");
hp->request_parse_status = HTTP_METHOD_NOT_ALLOWED;
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
repContext->setReplyToError(ERR_TOO_BIG,
- HTTP_BAD_REQUEST, METHOD_NONE, NULL,
+ HTTP_BAD_REQUEST, Http::METHOD_NONE, NULL,
clientConnection->remote, NULL, NULL, NULL);
context->registerWithConn();
context->pullData();
unsupportedTe = te.size() && te != "identity";
} // else implied identity coding
- mustReplyToOptions = (method == METHOD_OPTIONS) &&
+ mustReplyToOptions = (method == Http::METHOD_OPTIONS) &&
(request->header.getInt64(HDR_MAX_FORWARDS) == 0);
if (!urlCheckRequest(request) || mustReplyToOptions || unsupportedTe) {
clientStreamNode *node = context->getClientReplyContext();
clientSetKeepaliveFlag(http);
// Let tunneling code be fully responsible for CONNECT requests
- if (http->request->method == METHOD_CONNECT) {
+ if (http->request->method == Http::METHOD_CONNECT) {
context->mayUseConnection(true);
conn->flags.readMore = false;
}
assert (repContext);
conn->quitAfterError(request);
repContext->setReplyToError(ERR_TOO_BIG,
- HTTP_REQUEST_ENTITY_TOO_LARGE, METHOD_NONE, NULL,
+ HTTP_REQUEST_ENTITY_TOO_LARGE, Http::METHOD_NONE, NULL,
conn->clientConnection->remote, http->request, NULL, NULL);
assert(context->http->out.offset == 0);
context->pullData();
clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
assert (repContext);
repContext->setReplyToError(ERR_LIFETIME_EXP,
- HTTP_REQUEST_TIMEOUT, METHOD_NONE, "N/A", &CachePeer.sin_addr,
+ HTTP_REQUEST_TIMEOUT, Http::METHOD_NONE, "N/A", &CachePeer.sin_addr,
NULL, NULL, NULL);
/* No requests can be outstanded */
assert(chr == NULL);
return;
}
- if (r->method == METHOD_PURGE) {
+ if (r->method == Http::METHOD_PURGE) {
removeClientStoreReference(&sc, http);
e = NULL;
purgeRequest();
}
/** Check if its a PURGE request to be actioned. */
- if (r->method == METHOD_PURGE) {
+ if (r->method == Http::METHOD_PURGE) {
purgeRequest();
return;
}
/** Check if its an 'OTHER' request. Purge all cached entries if so and continue. */
- if (r->method == METHOD_OTHER) {
+ if (r->method == Http::METHOD_OTHER) {
purgeAllCached();
}
// TODO: can we use purgeAllCached() here instead of doing the
// getPublicByRequestMethod() dance?
- StoreEntry::getPublicByRequestMethod(this, http->request, METHOD_GET);
+ StoreEntry::getPublicByRequestMethod(this, http->request, Http::METHOD_GET);
}
// Purges all entries with a given url
bool get_or_head_sent = false;
#endif
- for (HttpRequestMethod m(METHOD_NONE); m != METHOD_ENUM_END; ++m) {
- if (m.isCacheble()) {
+ for (HttpRequestMethod m(Http::METHOD_NONE); m != Http::METHOD_ENUM_END; ++m) {
+ if (m.respMaybeCacheable()) {
if (StoreEntry *entry = storeGetPublic(url, m)) {
debugs(88, 5, "purging " << RequestMethodStr(m) << ' ' << url);
#if USE_HTCP
neighborsHtcpClear(entry, url, req, m, HTCP_CLR_INVALIDATION);
- if (m == METHOD_GET || m == METHOD_HEAD) {
+ if (m == Http::METHOD_GET || m == Http::METHOD_HEAD) {
get_or_head_sent = true;
}
#endif
#if USE_HTCP
if (!get_or_head_sent) {
- neighborsHtcpClear(NULL, url, req, HttpRequestMethod(METHOD_GET), HTCP_CLR_INVALIDATION);
+ neighborsHtcpClear(NULL, url, req, HttpRequestMethod(Http::METHOD_GET), HTCP_CLR_INVALIDATION);
}
#endif
}
{
if (newEntry->isNull()) {
lookingforstore = 2;
- StoreEntry::getPublicByRequestMethod(this, http->request, METHOD_HEAD);
+ StoreEntry::getPublicByRequestMethod(this, http->request, Http::METHOD_HEAD);
} else
purgeFoundObject (newEntry);
}
{
http->logType = LOG_TCP_MISS;
lookingforstore = 3;
- StoreEntry::getPublicByRequestMethod(this,http->request, METHOD_GET);
+ StoreEntry::getPublicByRequestMethod(this,http->request, Http::METHOD_GET);
}
void
/* Release the cached URI */
debugs(88, 4, "clientPurgeRequest: GET '" << newEntry->url() << "'" );
#if USE_HTCP
- neighborsHtcpClear(newEntry, NULL, http->request, HttpRequestMethod(METHOD_GET), HTCP_CLR_PURGE);
+ neighborsHtcpClear(newEntry, NULL, http->request, HttpRequestMethod(Http::METHOD_GET), HTCP_CLR_PURGE);
#endif
newEntry->release();
purgeStatus = HTTP_OK;
}
lookingforstore = 4;
- StoreEntry::getPublicByRequestMethod(this, http->request, METHOD_HEAD);
+ StoreEntry::getPublicByRequestMethod(this, http->request, Http::METHOD_HEAD);
}
void
if (newEntry && !newEntry->isNull()) {
debugs(88, 4, "clientPurgeRequest: HEAD '" << newEntry->url() << "'" );
#if USE_HTCP
- neighborsHtcpClear(newEntry, NULL, http->request, HttpRequestMethod(METHOD_HEAD), HTCP_CLR_PURGE);
+ neighborsHtcpClear(newEntry, NULL, http->request, HttpRequestMethod(Http::METHOD_HEAD), HTCP_CLR_PURGE);
#endif
newEntry->release();
purgeStatus = HTTP_OK;
if (http->request->vary_headers
&& !strstr(http->request->vary_headers, "=")) {
- StoreEntry *entry = storeGetPublic(urlCanonical(http->request), METHOD_GET);
+ StoreEntry *entry = storeGetPublic(urlCanonical(http->request), Http::METHOD_GET);
if (entry) {
debugs(88, 4, "clientPurgeRequest: Vary GET '" << entry->url() << "'" );
#if USE_HTCP
- neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(METHOD_GET), HTCP_CLR_PURGE);
+ neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(Http::METHOD_GET), HTCP_CLR_PURGE);
#endif
entry->release();
purgeStatus = HTTP_OK;
}
- entry = storeGetPublic(urlCanonical(http->request), METHOD_HEAD);
+ entry = storeGetPublic(urlCanonical(http->request), Http::METHOD_HEAD);
if (entry) {
debugs(88, 4, "clientPurgeRequest: Vary HEAD '" << entry->url() << "'" );
#if USE_HTCP
- neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(METHOD_HEAD), HTCP_CLR_PURGE);
+ neighborsHtcpClear(entry, NULL, http->request, HttpRequestMethod(Http::METHOD_HEAD), HTCP_CLR_PURGE);
#endif
entry->release();
purgeStatus = HTTP_OK;
return;
}
- if (context->http->request->method == METHOD_PURGE) {
+ if (context->http->request->method == Http::METHOD_PURGE) {
context->purgeRequest();
return;
}
// OPTIONS with Max-Forwards:0 handled in clientProcessRequest()
- if (context->http->request->method == METHOD_TRACE) {
+ if (context->http->request->method == Http::METHOD_TRACE) {
if (context->http->request->header.getInt64(HDR_MAX_FORWARDS) == 0) {
context->traceReply(aNode);
return;
void
clientReplyContext::sendNotModifiedOrPreconditionFailedError()
{
- if (http->request->method == METHOD_GET ||
- http->request->method == METHOD_HEAD)
+ if (http->request->method == Http::METHOD_GET ||
+ http->request->method == Http::METHOD_HEAD)
sendNotModified();
else
sendPreconditionFailedError();
#endif
- if (http->request->method == METHOD_HEAD) {
+ if (http->request->method == Http::METHOD_HEAD) {
/* do not forward body for HEAD replies */
body_size = 0;
http->flags.done_copying = 1;
{
// IP address validation for Host: failed. Admin wants to ignore them.
// NP: we do not yet handle CONNECT tunnels well, so ignore for them
- if (!Config.onoff.hostStrictVerify && http->request->method != METHOD_CONNECT) {
+ if (!Config.onoff.hostStrictVerify && http->request->method != Http::METHOD_CONNECT) {
debugs(85, 3, "SECURITY ALERT: Host header forgery detected on " << http->getConn()->clientConnection <<
" (" << A << " does not match " << B << ") on URL: " << urlCanonical(http->request));
// Verify forward-proxy requested URL domain matches the Host: header
debugs(85, 3, HERE << "FAIL on validate URL port " << http->request->port << " matches Host: port " << portStr);
hostHeaderVerifyFailed("URL port", portStr);
- } else if (!portStr && http->request->method != METHOD_CONNECT && http->request->port != urlDefaultPort(http->request->protocol)) {
+ } else if (!portStr && http->request->method != Http::METHOD_CONNECT && http->request->port != urlDefaultPort(http->request->protocol)) {
// Verify forward-proxy requested URL domain matches the Host: header
// Special case: we don't have a default-port to check for CONNECT. Assume URL is correct.
debugs(85, 3, HERE << "FAIL on validate URL port " << http->request->port << " matches Host: default port " << urlDefaultPort(http->request->protocol));
if (request->flags.auth)
return 0;
- if (method == METHOD_TRACE)
+ if (method == Http::METHOD_TRACE)
return 1;
- if (method != METHOD_GET)
+ if (method != Http::METHOD_GET)
return 0;
/* scan hierarchy_stoplist */
return 0;
if (request->protocol == AnyP::PROTO_HTTP)
- return httpCachable(method);
+ return method.respMaybeCacheable();
if (request->protocol == AnyP::PROTO_GOPHER)
return gopherCachable(request);
}
}
- if (request->method == METHOD_OTHER) {
+ if (request->method == Http::METHOD_OTHER) {
no_cache=true;
}
}
/* ignore range header in non-GETs or non-HEADs */
- if (request->method == METHOD_GET || request->method == METHOD_HEAD) {
+ if (request->method == Http::METHOD_GET || request->method == Http::METHOD_HEAD) {
// XXX: initialize if we got here without HttpRequest::parseHeader()
if (!request->range)
request->range = req_hdr->getRange();
#endif
- request->flags.cachable = http->request->cacheable();
+ request->flags.cachable = http->request->maybeCacheable();
if (clientHierarchical(http))
request->flags.hierarchical = 1;
// Bumping here can only start with a CONNECT request on a bumping port
// (bumping of intercepted SSL conns is decided before we get 1st request).
// We also do not bump redirected CONNECT requests.
- if (http->request->method != METHOD_CONNECT || http->redirect.status ||
+ if (http->request->method != Http::METHOD_CONNECT || http->redirect.status ||
!Config.accessList.ssl_bump || !http->getConn()->port->sslBump) {
http->al->ssl.bumpMode = Ssl::bumpEnd; // SslBump does not apply; log -
debugs(85, 5, HERE << "cannot SslBump this request");
{
debugs(85, 4, "clientProcessRequest: " << RequestMethodStr(request->method) << " '" << uri << "'");
- if (request->method == METHOD_CONNECT && !redirect.status) {
+ if (request->method == Http::METHOD_CONNECT && !redirect.status) {
#if USE_SSL
if (sslBumpNeeded()) {
sslBumpStart();
status = httpStatus;
else {
// Use 307 for HTTP/1.1 non-GET/HEAD requests.
- if (request->method != METHOD_GET && request->method != METHOD_HEAD && request->http_ver >= HttpVersion(1,1))
+ if (request->method != Http::METHOD_GET && request->method != Http::METHOD_HEAD && request->http_ver >= HttpVersion(1,1))
status = HTTP_TEMPORARY_REDIRECT;
}
/* tempUrl is eaten by the request */
char const *tempUrl = vars->extractChar ();
- debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl <<
- "'");
+ debugs(86, 5, "ESIIncludeStart: Starting subrequest with url '" << tempUrl << "'");
- if (clientBeginRequest(METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ)) {
+ if (clientBeginRequest(Http::METHOD_GET, tempUrl, esiBufferRecipient, esiBufferDetach, stream.getRaw(), &tempheaders, stream->localbuffer->buf, HTTP_REQBUF_SZ)) {
debugs(86, DBG_CRITICAL, "starting new ESI subrequest failed");
}
bool
FwdState::checkRetriable()
{
- /* RFC2616 9.1 Safe and Idempotent Methods */
- switch (request->method.id()) {
- /* 9.1.1 Safe Methods */
-
- case METHOD_GET:
-
- case METHOD_HEAD:
- /* 9.1.2 Idempotent Methods */
-
- case METHOD_PUT:
-
- case METHOD_DELETE:
-
- case METHOD_OPTIONS:
-
- case METHOD_TRACE:
- break;
-
- default:
+ // Optimize: A compliant proxy may retry PUTs, but Squid lacks the [rather
+ // complicated] code required to protect the PUT request body from being
+ // nibbled during the first try. Thus, Squid cannot retry some PUTs today.
+ if (request->body_pipe != NULL)
return false;
- }
- return true;
+ // RFC2616 9.1 Safe and Idempotent Methods
+ return (request->method.isHttpSafe() || request->method.isIdempotent());
}
void
AsyncCall::Pointer closer = JobCallback(9, 5, Dialer, this, FtpStateData::ctrlClosed);
ctrl.opened(conn, closer);
- if (request->method == METHOD_PUT)
+ if (request->method == Http::METHOD_PUT)
flags.put = 1;
}
{
debugs(9, 3, HERE << "FtpStateData::processReplyBody starting.");
- if (request->method == METHOD_HEAD && (flags.isdir || theSize != -1)) {
+ if (request->method == Http::METHOD_HEAD && (flags.isdir || theSize != -1)) {
serverComplete();
return;
}
/** \par
* Checks for 'HEAD' method request and passes off for special handling by FtpStateData::processHeadResponse(). */
- if (ftpState->request->method == METHOD_HEAD && (ftpState->flags.isdir || ftpState->theSize != -1)) {
+ if (ftpState->request->method == Http::METHOD_HEAD && (ftpState->flags.isdir || ftpState->theSize != -1)) {
ftpState->processHeadResponse(); // may call serverComplete
return;
}
*/
method = HttpRequestMethod(s->method, NULL);
- s->request = HttpRequest::CreateFromUrlAndMethod(s->uri, method == METHOD_NONE ? HttpRequestMethod(METHOD_GET) : method);
+ s->request = HttpRequest::CreateFromUrlAndMethod(s->uri, method == Http::METHOD_NONE ? HttpRequestMethod(Http::METHOD_GET) : method);
if (s->request)
HTTPMSGLOCK(s->request);
mustStop("HttpStateData::httpStateConnClosed");
}
-int
-httpCachable(const HttpRequestMethod& method)
-{
- /* GET and HEAD are cachable. Others are not. */
-
- // TODO: replase to HttpRequestMethod::isCachable() ?
- if (method != METHOD_GET && method != METHOD_HEAD)
- return 0;
-
- /* else cachable */
- return 1;
-}
-
void
HttpStateData::httpTimeout(const CommTimeoutCbParams ¶ms)
{
* changed.
*/
if (e->mem_obj->request)
- pe = storeGetPublicByRequestMethod(e->mem_obj->request, METHOD_HEAD);
+ pe = storeGetPublicByRequestMethod(e->mem_obj->request, Http::METHOD_HEAD);
else
- pe = storeGetPublic(e->mem_obj->url, METHOD_HEAD);
+ pe = storeGetPublic(e->mem_obj->url, Http::METHOD_HEAD);
if (pe != NULL) {
assert(e != pe);
#if USE_HTCP
- neighborsHtcpClear(e, NULL, e->mem_obj->request, HttpRequestMethod(METHOD_HEAD), HTCP_CLR_INVALIDATION);
+ neighborsHtcpClear(e, NULL, e->mem_obj->request, HttpRequestMethod(Http::METHOD_HEAD), HTCP_CLR_INVALIDATION);
#endif
pe->release();
}
case HDR_MAX_FORWARDS:
/** \par Max-Forwards:
* pass only on TRACE or OPTIONS requests */
- if (request->method == METHOD_TRACE || request->method == METHOD_OPTIONS) {
+ if (request->method == Http::METHOD_TRACE || request->method == Http::METHOD_OPTIONS) {
const int64_t hops = e->getInt64();
if (hops > 0)
--- /dev/null
+include $(top_srcdir)/src/Common.am
+include $(top_srcdir)/src/TestHeaders.am
+
+noinst_LTLIBRARIES = libsquid-http.la
+
+libsquid_http_la_SOURCES = \
+ MethodType.cc \
+ MethodType.h
+
+MethodType.cc: MethodType.h $(top_srcdir)/src/mk-string-arrays.awk
+ ($(AWK) -f $(top_srcdir)/src/mk-string-arrays.awk < $(srcdir)/MethodType.h | sed -e 's%METHOD_%%' | \
+ sed -e 's%_C%-C%' >$@) || ($(RM) -f $@ && exit 1)
+
+CLEANFILES += MethodType.cc
--- /dev/null
+#ifndef SQUID_SRC_HTTP_METHODTYPE_H
+#define SQUID_SRC_HTTP_METHODTYPE_H
+
+namespace Http
+{
+
+// see IANA registry:
+// also: https://datatracker.ietf.org/doc/draft-ietf-httpbis-method-registrations
+typedef enum _method_t {
+ METHOD_NONE = 0,
+
+#if NO_SPECIAL_HANDLING
+ // RFC 2068
+ METHOD_LINK,
+ METHOD_UNLINK,
+#endif
+
+ // RFC 2616 (HTTP)
+ METHOD_GET,
+ METHOD_POST,
+ METHOD_PUT,
+ METHOD_HEAD,
+ METHOD_CONNECT,
+ METHOD_TRACE,
+ METHOD_OPTIONS,
+ METHOD_DELETE,
+
+ // RFC 3253
+ METHOD_CHECKOUT,
+ METHOD_CHECKIN,
+ METHOD_UNCHECKOUT,
+ METHOD_MKWORKSPACE,
+ METHOD_VERSION_CONTROL,
+ METHOD_REPORT,
+ METHOD_UPDATE,
+ METHOD_LABEL,
+ METHOD_MERGE,
+ METHOD_BASELINE_CONTROL,
+ METHOD_MKACTIVITY,
+
+#if NO_SPECIAL_HANDLING
+ // RFC 3648
+ METHOD_ORDERPATCH,
+
+ // RFC 3744
+ METHOD_ACL,
+
+ // RFC 4437
+ METHOD_MKREDIRECTREF,
+ METHOD_UPDATEREDIRECTREF,
+
+ // RFC 4791
+ METHOD_MKCALENDAR,
+#endif
+
+ // RFC 4918 (WebDAV)
+ METHOD_PROPFIND,
+ METHOD_PROPPATCH,
+ METHOD_MKCOL,
+ METHOD_COPY,
+ METHOD_MOVE,
+ METHOD_LOCK,
+ METHOD_UNLOCK,
+
+ // RFC 5323
+ METHOD_SEARCH,
+
+#if NO_SPECIAL_HANDLING
+ // RFC 5789
+ METHOD_PATCH,
+
+ // RFC 5842
+ METHOD_BIND,
+ METHOD_REBIND,
+ METHOD_UNBIND,
+#endif
+
+ // Squid extension methods
+ METHOD_PURGE,
+ METHOD_OTHER,
+ METHOD_ENUM_END // MUST be last, (yuck) this is used as an array-initialization index constant!
+} MethodType;
+
+extern const char *MethodType_str[];
+
+inline const char*
+MethodStr(const MethodType m)
+{
+ return MethodType_str[m];
+}
+
+}; // namespace Http
+
+#endif /* SQUID_SRC_HTTP_METHODTYPE_H */
assert(NULL != ex->r);
ex->r->http_ver = HttpVersion(1,1);
ex->connstate = STATE_HEADER;
- ex->e = storeCreateEntry(uri, uri, RequestFlags(), METHOD_GET);
+ 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);
state->src_rtt = src_rtt;
- StoreEntry::getPublic (state, url, METHOD_GET);
+ StoreEntry::getPublic (state, url, Http::METHOD_GET);
HTTPMSGUNLOCK(icp_request);
}
if (neighbors_do_private_keys && reqnum)
return queried_keys[reqnum & N_QUERIED_KEYS_MASK];
- return storeKeyPublic(url, METHOD_GET);
+ return storeKeyPublic(url, Http::METHOD_GET);
}
state->url = xstrdup (url);
- StoreEntry::getPublic (state, url, METHOD_GET);
+ StoreEntry::getPublic (state, url, Http::METHOD_GET);
}
ICP3State::~ICP3State()
#include "ipc/TypedMsgHdr.h"
#include "mgr/ActionParams.h"
-Mgr::ActionParams::ActionParams(): httpMethod(METHOD_NONE)
+Mgr::ActionParams::ActionParams(): httpMethod(Http::METHOD_NONE)
{
}
msg.getString(httpUri);
const int m = msg.getInt();
- Must(METHOD_NONE <= m && m < METHOD_ENUM_END);
- httpMethod = static_cast<_method_t>(m);
+ Must(Http::METHOD_NONE <= m && m < Http::METHOD_ENUM_END);
+ String method;
+ msg.getString(method);
+ httpMethod = HttpRequestMethod(method.termedBuf(), NULL);
msg.getPod(httpFlags);
msg.getString(httpOrigin);
Mgr::ActionParams::pack(Ipc::TypedMsgHdr &msg) const
{
msg.putString(httpUri);
- msg.putInt(httpMethod);
+ String foo(httpMethod.image());
+ msg.putString(foo);
msg.putPod(httpFlags);
msg.putString(httpOrigin);
public:
/* details of the client HTTP request that caused the action */
String httpUri; ///< HTTP request URI
- _method_t httpMethod; ///< HTTP request method
+ HttpRequestMethod httpMethod; ///< HTTP request method
RequestFlags httpFlags; ///< HTTP request flags
String httpOrigin; ///< HTTP Origin: header (if any)
if (type == NULL)
fatal("Unknown icon format while reading mime.conf\n");
- StoreEntry::getPublic(this, url, METHOD_GET);
+ StoreEntry::getPublic(this, url, Http::METHOD_GET);
}
void
}
flags.cachable = 1;
- StoreEntry *e = storeCreateEntry(url,
- url,
- flags,
- METHOD_GET);
+ StoreEntry *e = storeCreateEntry(url,url,flags,Http::METHOD_GET);
assert(e != NULL);
EBIT_SET(e->flags, ENTRY_SPECIAL);
e->setPublicKey();
// CONNECT requests are proxy requests. Not to be forwarded to origin servers.
// Unless the destination port matches, in which case we MAY perform a 'DIRECT' to this CachePeer.
- if (p->options.originserver && request->method == METHOD_CONNECT && request->port != p->in_addr.GetPort())
+ if (p->options.originserver && request->method == Http::METHOD_CONNECT && request->port != p->in_addr.GetPort())
return false;
if (p->peer_domain == NULL && p->access == NULL)
snprintf(url, MAX_URL, "http://");
p->in_addr.ToURL(url+7, MAX_URL -8 );
strcat(url, "/");
- fake = storeCreateEntry(url, url, RequestFlags(), METHOD_GET);
+ fake = storeCreateEntry(url, url, RequestFlags(), Http::METHOD_GET);
HttpRequest *req = HttpRequest::CreateFromUrl(url);
psstate = new ps_state;
psstate->request = HTTPMSGLOCK(req);
{
StoreEntry *e = storeGetPublicByRequestMethod(req, req->method);
- if (e == NULL && req->method == METHOD_HEAD)
+ if (e == NULL && req->method == Http::METHOD_HEAD)
/* We can generate a HEAD reply from a cached GET object */
- e = storeGetPublicByRequestMethod(req, METHOD_GET);
+ e = storeGetPublicByRequestMethod(req, Http::METHOD_GET);
return e;
}
mem_obj->id = getKeyCounter();
newkey = storeKeyPrivate(mem_obj->url, mem_obj->method, mem_obj->id);
} else {
- newkey = storeKeyPrivate("JUNK", METHOD_NONE, getKeyCounter());
+ newkey = storeKeyPrivate("JUNK", Http::METHOD_NONE, getKeyCounter());
}
assert(hash_lookup(store_table, newkey) == NULL);
{
#if CACHE_ALL_METHODS
- if (mem_obj->method != METHOD_GET) {
+ if (mem_obj->method != Http::METHOD_GET) {
debugs(20, 2, "StoreEntry::checkCachable: NO: non-GET method");
++store_check_cachable_hist.no.non_get;
} else
return 1;
}
- if (mem_obj->method == METHOD_HEAD) {
+ if (mem_obj->method == Http::METHOD_HEAD) {
debugs(20, 5, "storeEntryValidLength: HEAD request: " << getMD5Text());
return 1;
}
const String reqETags = request.header.getList(HDR_IF_NONE_MATCH);
// weak comparison is allowed only for HEAD or full-body GET requests
const bool allowWeakMatch = !request.flags.isRanged &&
- (request.method == METHOD_GET || request.method == METHOD_HEAD);
+ (request.method == Http::METHOD_GET || request.method == Http::METHOD_HEAD);
return hasOneOfEtags(reqETags, allowWeakMatch);
}
/* make new store entry */
url = internalLocalUri("/squid-internal-periodic/", StoreDigestFileName);
flags.cachable = 1;
- e = storeCreateEntry(url, url, flags, METHOD_GET);
+ e = storeCreateEntry(url, url, flags, Http::METHOD_GET);
assert(e);
sd_state.rewrite_lock = e;
debugs(71, 3, "storeDigestRewrite: url: " << url << " key: " << e->getMD5Text());
/* vanilla url */
unsigned short expected_port;
char * url = xstrdup("http://foo:90/bar");
- HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+ HttpRequest *aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
expected_port = 90;
HttpRequest *nullRequest = NULL;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
/* vanilla url, different method */
url = xstrdup("http://foo/bar");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_PUT);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_PUT);
expected_port = 80;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_PUT);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_PUT);
CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
/* a connect url with non-CONNECT data */
url = xstrdup(":foo/bar");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_CONNECT);
xfree(url);
CPPUNIT_ASSERT_EQUAL(nullRequest, aRequest);
/* a CONNECT url with CONNECT data */
url = xstrdup("foo:45");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_CONNECT);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_CONNECT);
expected_port = 45;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_CONNECT);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_CONNECT);
CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String(""), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_NONE, aRequest->protocol);
HttpRequest *aRequest = HttpRequest::CreateFromUrl(url);
expected_port = 90;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
CPPUNIT_ASSERT_EQUAL(String("foo"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/bar"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
/* valid IPv6 address without port */
url = xstrdup("http://[2000:800::45]/foo");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
expected_port = 80;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
/* valid IPv6 address with port */
url = xstrdup("http://[2000:800::45]:90/foo");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
expected_port = 90;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
/* IPv6 address as invalid (bug trigger) */
url = xstrdup("http://2000:800::45/foo");
- aRequest = HttpRequest::CreateFromUrlAndMethod(url, METHOD_GET);
+ aRequest = HttpRequest::CreateFromUrlAndMethod(url, Http::METHOD_GET);
expected_port = 80;
CPPUNIT_ASSERT_EQUAL(expected_port, aRequest->port);
- CPPUNIT_ASSERT(aRequest->method == METHOD_GET);
+ CPPUNIT_ASSERT(aRequest->method == Http::METHOD_GET);
CPPUNIT_ASSERT_EQUAL(String("[2000:800::45]"), String(aRequest->GetHost()));
CPPUNIT_ASSERT_EQUAL(String("/foo"), aRequest->urlpath);
CPPUNIT_ASSERT_EQUAL(AnyP::PROTO_HTTP, aRequest->protocol);
void
testHttpRequestMethod::testConstructCharStart()
{
- /* parse an empty string -> METHOD_NONE */
- CPPUNIT_ASSERT(HttpRequestMethod(NULL,NULL) == METHOD_NONE);
+ /* parse an empty string -> Http::METHOD_NONE */
+ CPPUNIT_ASSERT(HttpRequestMethod(NULL,NULL) == Http::METHOD_NONE);
/* parsing a literal should work */
- CPPUNIT_ASSERT(HttpRequestMethod("GET", NULL) == METHOD_GET);
- CPPUNIT_ASSERT(HttpRequestMethod("QWERTY", NULL) == METHOD_OTHER);
+ CPPUNIT_ASSERT(HttpRequestMethod("GET", NULL) == Http::METHOD_GET);
+ CPPUNIT_ASSERT(HttpRequestMethod("QWERTY", NULL) == Http::METHOD_OTHER);
}
/*
testHttpRequestMethod::testConstructCharStartEnd()
{
char const * buffer;
- /* parse an empty string -> METHOD_NONE */
- CPPUNIT_ASSERT(HttpRequestMethod(NULL, NULL) == METHOD_NONE);
+ /* parse an empty string -> Http::METHOD_NONE */
+ CPPUNIT_ASSERT(HttpRequestMethod(NULL, NULL) == Http::METHOD_NONE);
/* parsing a literal should work */
- CPPUNIT_ASSERT(HttpRequestMethod("GET", NULL) == METHOD_GET);
+ CPPUNIT_ASSERT(HttpRequestMethod("GET", NULL) == Http::METHOD_GET);
/* parsing with an explicit end should work */
buffer = "POSTPLUS";
- CPPUNIT_ASSERT(HttpRequestMethod(buffer, buffer + 4) == METHOD_POST);
+ CPPUNIT_ASSERT(HttpRequestMethod(buffer, buffer + 4) == Http::METHOD_POST);
}
/*
- * we should be able to assign a method_t to a HttpRequestMethod
+ * we should be able to assign a Http::MethodType to a HttpRequestMethod
*/
void
testHttpRequestMethod::testAssignFrommethod_t()
{
HttpRequestMethod method;
- method = METHOD_NONE;
- CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(METHOD_NONE), method);
- method = METHOD_POST;
- CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(METHOD_POST), method);
+ method = Http::METHOD_NONE;
+ CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_NONE), method);
+ method = Http::METHOD_POST;
+ CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_POST), method);
}
/*
- * a default constructed HttpRequestMethod is == METHOD_NONE
+ * a default constructed HttpRequestMethod is == Http::METHOD_NONE
*/
void
testHttpRequestMethod::testDefaultConstructor()
{
HttpRequestMethod lhs;
- HttpRequestMethod rhs(METHOD_NONE);
+ HttpRequestMethod rhs(Http::METHOD_NONE);
CPPUNIT_ASSERT_EQUAL(lhs, rhs);
}
/*
- * we should be able to construct a HttpRequestMethod from a method_t
+ * we should be able to construct a HttpRequestMethod from a Http::MethodType
*/
void
testHttpRequestMethod::testConstructmethod_t()
{
- CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(METHOD_NONE), HttpRequestMethod(METHOD_NONE));
- CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(METHOD_POST), HttpRequestMethod(METHOD_POST));
- CPPUNIT_ASSERT(HttpRequestMethod(METHOD_NONE) != HttpRequestMethod(METHOD_POST));
+ CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_NONE), HttpRequestMethod(Http::METHOD_NONE));
+ CPPUNIT_ASSERT_EQUAL(HttpRequestMethod(Http::METHOD_POST), HttpRequestMethod(Http::METHOD_POST));
+ CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) != HttpRequestMethod(Http::METHOD_POST));
}
/*
}
/*
- * an HttpRequestMethod should be comparable to a method_t without false
+ * an HttpRequestMethod should be comparable to a Http::MethodType without false
* matches
*/
void
testHttpRequestMethod::testEqualmethod_t()
{
- CPPUNIT_ASSERT(HttpRequestMethod(METHOD_NONE) == METHOD_NONE);
- CPPUNIT_ASSERT(not (HttpRequestMethod(METHOD_POST) == METHOD_GET));
- CPPUNIT_ASSERT(HttpRequestMethod(METHOD_GET) == METHOD_GET);
- CPPUNIT_ASSERT(not (HttpRequestMethod(METHOD_TRACE) == METHOD_SEARCH));
+ CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) == Http::METHOD_NONE);
+ CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_POST) == Http::METHOD_GET));
+ CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_GET) == Http::METHOD_GET);
+ CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_TRACE) == Http::METHOD_SEARCH));
}
/*
void
testHttpRequestMethod::testNotEqualmethod_t()
{
- CPPUNIT_ASSERT(HttpRequestMethod(METHOD_NONE) != METHOD_GET);
- CPPUNIT_ASSERT(not (HttpRequestMethod(METHOD_POST) != METHOD_POST));
- CPPUNIT_ASSERT(HttpRequestMethod(METHOD_GET) != METHOD_NONE);
- CPPUNIT_ASSERT(not (HttpRequestMethod(METHOD_SEARCH) != METHOD_SEARCH));
+ CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_NONE) != Http::METHOD_GET);
+ CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_POST) != Http::METHOD_POST));
+ CPPUNIT_ASSERT(HttpRequestMethod(Http::METHOD_GET) != Http::METHOD_NONE);
+ CPPUNIT_ASSERT(not (HttpRequestMethod(Http::METHOD_SEARCH) != Http::METHOD_SEARCH));
}
/*
snprintf(url, sizeof(url), "dummy url %i", i);
url[sizeof(url) - 1] = '\0';
StoreEntry *const pe =
- storeCreateEntry(url, "dummy log url", flags, METHOD_GET);
+ storeCreateEntry(url, "dummy log url", flags, Http::METHOD_GET);
HttpReply *const rep = const_cast<HttpReply *>(pe->getReply());
rep->setHeaders(HTTP_OK, "dummy test object", "x-squid-internal/test",
-1, -1, squid_curtime + 100000);
/* Create "vary" base object */
RequestFlags flags;
flags.cachable = 1;
- StoreEntry *pe = storeCreateEntry("dummy url", "dummy log url", flags, METHOD_GET);
+ StoreEntry *pe = storeCreateEntry("dummy url", "dummy log url", flags, Http::METHOD_GET);
HttpReply *rep = (HttpReply *) pe->getReply(); // bypass const
rep->setHeaders(HTTP_OK, "dummy test object", "x-squid-internal/test", -1, -1, squid_curtime + 100000);
* This abuses HttpRequest as a way of representing the parsed url
* and its components.
* method is used to switch parsers and to init the HttpRequest.
- * If method is METHOD_CONNECT, then rather than a URL a hostname:port is
+ * If method is Http::METHOD_CONNECT, then rather than a URL a hostname:port is
* looked for.
* The url is non const so that if its too long we can NULL-terminate it in place.
*/
debugs(23, DBG_IMPORTANT, "urlParse: URL too large (" << l << " bytes)");
return NULL;
}
- if (method == METHOD_CONNECT) {
+ if (method == Http::METHOD_CONNECT) {
port = CONNECT_PORT;
if (sscanf(url, "[%[^]]]:%d", host, &port) < 1)
if (sscanf(url, "%[^:]:%d", host, &port) < 1)
return NULL;
- } else if ((method == METHOD_OPTIONS || method == METHOD_TRACE) &&
+ } else if ((method == Http::METHOD_OPTIONS || method == Http::METHOD_TRACE) &&
strcmp(url, "*") == 0) {
protocol = AnyP::PROTO_HTTP;
port = urlDefaultPort(protocol);
urlCanonical(HttpRequest * request)
{
LOCAL_ARRAY(char, portbuf, 32);
-/// \todo AYJ: Performance: making this a ptr and allocating when needed will be better than a write and future xstrdup().
LOCAL_ARRAY(char, urlbuf, MAX_URL);
if (request->canonical)
if (request->protocol == AnyP::PROTO_URN) {
snprintf(urlbuf, MAX_URL, "urn:" SQUIDSTRINGPH,
SQUIDSTRINGPRINT(request->urlpath));
+ } else if (request->method.id() == Http::METHOD_CONNECT) {
+ snprintf(urlbuf, MAX_URL, "%s:%d", request->GetHost(), request->port);
} else {
-/// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier.
- switch (request->method.id()) {
-
- case METHOD_CONNECT:
- snprintf(urlbuf, MAX_URL, "%s:%d", request->GetHost(), request->port);
- break;
-
- default:
- portbuf[0] = '\0';
-
- if (request->port != urlDefaultPort(request->protocol))
- snprintf(portbuf, 32, ":%d", request->port);
-
- const URLScheme sch = request->protocol; // temporary, until bug 1961 URL handling is fixed.
- snprintf(urlbuf, MAX_URL, "%s://%s%s%s%s" SQUIDSTRINGPH,
- sch.const_str(),
- request->login,
- *request->login ? "@" : null_string,
- request->GetHost(),
- portbuf,
- SQUIDSTRINGPRINT(request->urlpath));
-
- break;
- }
+ portbuf[0] = '\0';
+
+ if (request->port != urlDefaultPort(request->protocol))
+ snprintf(portbuf, 32, ":%d", request->port);
+
+ const URLScheme sch = request->protocol; // temporary, until bug 1961 URL handling is fixed.
+ snprintf(urlbuf, MAX_URL, "%s://%s%s%s%s" SQUIDSTRINGPH,
+ sch.const_str(),
+ request->login,
+ *request->login ? "@" : null_string,
+ request->GetHost(),
+ portbuf,
+ SQUIDSTRINGPRINT(request->urlpath));
}
return (request->canonical = xstrdup(urlbuf));
if (request->protocol == AnyP::PROTO_URN) {
snprintf(buf, MAX_URL, "urn:" SQUIDSTRINGPH,
SQUIDSTRINGPRINT(request->urlpath));
+ } else if (request->method.id() == Http::METHOD_CONNECT) {
+ snprintf(buf, MAX_URL, "%s:%d", request->GetHost(), request->port);
} else {
-/// \todo AYJ: this could use "if..else and method == METHOD_CONNECT" easier.
- switch (request->method.id()) {
+ portbuf[0] = '\0';
- case METHOD_CONNECT:
- snprintf(buf, MAX_URL, "%s:%d",
- request->GetHost(),
- request->port);
- break;
-
- default:
- portbuf[0] = '\0';
+ if (request->port != urlDefaultPort(request->protocol))
+ snprintf(portbuf, 32, ":%d", request->port);
- if (request->port != urlDefaultPort(request->protocol))
- snprintf(portbuf, 32, ":%d", request->port);
+ loginbuf[0] = '\0';
- loginbuf[0] = '\0';
+ if ((int) strlen(request->login) > 0) {
+ strcpy(loginbuf, request->login);
- if ((int) strlen(request->login) > 0) {
- strcpy(loginbuf, request->login);
+ if ((t = strchr(loginbuf, ':')))
+ *t = '\0';
- if ((t = strchr(loginbuf, ':')))
- *t = '\0';
-
- strcat(loginbuf, "@");
- }
-
- const URLScheme sch = request->protocol; // temporary, until bug 1961 URL handling is fixed.
- snprintf(buf, MAX_URL, "%s://%s%s%s" SQUIDSTRINGPH,
- sch.const_str(),
- loginbuf,
- request->GetHost(),
- portbuf,
- SQUIDSTRINGPRINT(request->urlpath));
- /*
- * strip arguments AFTER a question-mark
- */
+ strcat(loginbuf, "@");
+ }
- if (Config.onoff.strip_query_terms)
- if ((t = strchr(buf, '?'))) {
- ++t;
- *t = '\0';
- }
+ const URLScheme sch = request->protocol; // temporary, until bug 1961 URL handling is fixed.
+ snprintf(buf, MAX_URL, "%s://%s%s%s" SQUIDSTRINGPH,
+ sch.const_str(),
+ loginbuf,
+ request->GetHost(),
+ portbuf,
+ SQUIDSTRINGPRINT(request->urlpath));
+ /*
+ * strip arguments AFTER a question-mark
+ */
- break;
- }
+ if (Config.onoff.strip_query_terms)
+ if ((t = strchr(buf, '?')))
+ *(++t) = '\0';
}
if (stringHasCntl(buf))
/**
* Yet another alternative to urlCanonical.
- * This one addes the https:// parts to METHOD_CONNECT URL
+ * This one adds the https:// parts to Http::METHOD_CONNECT URL
* for use in error page outputs.
* Luckily we can leverage the others instead of duplicating.
*/
LOCAL_ARRAY(char, buf, MAX_URL);
// method CONNECT and port HTTPS
- if (request->method == METHOD_CONNECT && request->port == 443) {
+ if (request->method == Http::METHOD_CONNECT && request->port == 443) {
snprintf(buf, MAX_URL, "https://%s/*", request->GetHost());
return buf;
}
urlMakeAbsolute(const HttpRequest * req, const char *relUrl)
{
- if (req->method.id() == METHOD_CONNECT) {
+ if (req->method.id() == Http::METHOD_CONNECT) {
return (NULL);
}
* do not have a default protocol from the client side of HTTP.
*/
- if (r->method == METHOD_CONNECT)
+ if (r->method == Http::METHOD_CONNECT)
return 1;
// we support OPTIONS and TRACE directed at us (with a 501 reply, for now)
// we also support forwarding OPTIONS and TRACE, except for the *-URI ones
- if (r->method == METHOD_OPTIONS || r->method == METHOD_TRACE)
+ if (r->method == Http::METHOD_OPTIONS || r->method == Http::METHOD_TRACE)
return (r->header.getInt64(HDR_MAX_FORWARDS) == 0 || r->urlpath != "*");
- if (r->method == METHOD_PURGE)
+ if (r->method == Http::METHOD_PURGE)
return 1;
/* does method match the protocol? */
case AnyP::PROTO_FTP:
- if (r->method == METHOD_PUT)
+ if (r->method == Http::METHOD_PUT)
rc = 1;
case AnyP::PROTO_GOPHER:
case AnyP::PROTO_WAIS:
case AnyP::PROTO_WHOIS:
- if (r->method == METHOD_GET)
+ if (r->method == Http::METHOD_GET)
rc = 1;
- else if (r->method == METHOD_HEAD)
+ else if (r->method == Http::METHOD_HEAD)
rc = 1;
break;
if (urlres_r == NULL)
return;
- StoreEntry::getPublic (this, urlres, METHOD_GET);
+ StoreEntry::getPublic (this, urlres, Http::METHOD_GET);
}
void
urlres_e = newEntry;
if (urlres_e->isNull()) {
- urlres_e = storeCreateEntry(urlres, urlres, RequestFlags(), METHOD_GET);
+ urlres_e = storeCreateEntry(urlres, urlres, RequestFlags(), Http::METHOD_GET);
sc = storeClientListAdd(urlres_e, this);
FwdState::fwdStart(Comm::ConnectionPointer(), urlres_e, urlres_r);
} else {