]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
SourceLayout: shuffle HttpStatusLine into http/libsquid-http.la
authorAmos Jeffries <squid3@treenet.co.nz>
Mon, 18 Mar 2013 04:55:51 +0000 (22:55 -0600)
committerAmos Jeffries <squid3@treenet.co.nz>
Mon, 18 Mar 2013 04:55:51 +0000 (22:55 -0600)
* moves HttpStatusLine.* to http/StatusLine.*

* renames HttpStatusLine to Http::StatusLine

* renames httpStatusLine*() functions as members of Http::StatusLine

* shuffles StatusCode string conversion function into http/StatusCode

* makes reason parameter of StatusLine::set() function optional.
  There is no logic change involved but callers now no longer need to
  set it to the status code string explicitly, nor need to set it to NULL
  explicitly unless intending to replace an existing status string.

* adds const-correctness and documentation to StatusLine symbols.

35 files changed:
src/HttpReply.cc
src/HttpReply.h
src/HttpStatusLine.cc [deleted file]
src/Makefile.am
src/Server.cc
src/acl/Asn.cc
src/acl/HttpStatus.cc
src/adaptation/ecap/MessageRep.cc
src/adaptation/icap/Launcher.cc
src/adaptation/icap/ModXact.cc
src/adaptation/icap/Options.cc
src/adaptation/icap/Xaction.cc
src/auth/UserRequest.cc
src/auth/digest/UserRequest.cc
src/auth/negotiate/UserRequest.cc
src/cache_manager.cc
src/client_side.cc
src/client_side_reply.cc
src/esi/Esi.cc
src/esi/Include.cc
src/forward.cc
src/http.cc
src/http/Makefile.am
src/http/StatusCode.cc [new file with mode: 0644]
src/http/StatusCode.h
src/http/StatusLine.cc [new file with mode: 0644]
src/http/StatusLine.h [moved from src/HttpStatusLine.h with 59% similarity]
src/icmp/net_db.cc
src/log/access_log.cc
src/peer_digest.cc
src/store.cc
src/store_client.cc
src/store_log.cc
src/tests/stub_HttpReply.cc
src/urn.cc

index 7965ce5728cb4af993fda7bd19706547ad583537..1a646a8e6544a392d1879cb623298520ecf00b55 100644 (file)
@@ -98,7 +98,7 @@ void
 HttpReply::init()
 {
     hdrCacheInit();
-    httpStatusLineInit(&sline);
+    sline.init();
     pstate = psReadyToParseStartLine;
     do_clean = true;
 }
@@ -126,14 +126,14 @@ HttpReply::clean()
     body.clear();
     hdrCacheClean();
     header.clean();
-    httpStatusLineClean(&sline);
+    sline.clean();
     bodySizeMax = -2; // hack: make calculatedBodySizeMax() false
 }
 
 void
 HttpReply::packHeadersInto(Packer * p) const
 {
-    httpStatusLinePackInto(&sline, p);
+    sline.packInto(p);
     header.packInto(p);
     packerAppend(p, "\r\n", 2);
 }
@@ -188,7 +188,7 @@ HttpReply::make304() const
     /* rv->cache_control */
     /* rv->content_range */
     /* rv->keep_alive */
-    httpStatusLineSet(&rv->sline, Http::ProtocolVersion(1,1), Http::scNotModified, NULL);
+    rv->sline.set(Http::ProtocolVersion(1,1), Http::scNotModified, NULL);
 
     for (t = 0; ImsEntries[t] != HDR_OTHER; ++t)
         if ((e = header.findEntry(ImsEntries[t])))
@@ -215,7 +215,7 @@ HttpReply::setHeaders(Http::StatusCode status, const char *reason,
                       const char *ctype, int64_t clen, time_t lmt, time_t expiresTime)
 {
     HttpHeader *hdr;
-    httpStatusLineSet(&sline, Http::ProtocolVersion(1,1), status, reason);
+    sline.set(Http::ProtocolVersion(1,1), status, reason);
     hdr = &header;
     hdr->putStr(HDR_SERVER, visible_appname_string);
     hdr->putStr(HDR_MIME_VERSION, "1.0");
@@ -249,7 +249,7 @@ void
 HttpReply::redirect(Http::StatusCode status, const char *loc)
 {
     HttpHeader *hdr;
-    httpStatusLineSet(&sline, Http::ProtocolVersion(1,1), status, httpStatusString(status));
+    sline.set(Http::ProtocolVersion(1,1), status, NULL);
     hdr = &header;
     hdr->putStr(HDR_SERVER, APP_FULLNAME);
     hdr->putTime(HDR_DATE, squid_curtime);
@@ -427,13 +427,13 @@ HttpReply::bodySize(const HttpRequestMethod& method) const
         return -1;
     else if (method.id() == Http::METHOD_HEAD)
         return 0;
-    else if (sline.status == Http::scOkay)
+    else if (sline.status() == Http::scOkay)
         (void) 0;              /* common case, continue */
-    else if (sline.status == Http::scNoContent)
+    else if (sline.status() == Http::scNoContent)
         return 0;
-    else if (sline.status == Http::scNotModified)
+    else if (sline.status() == Http::scNotModified)
         return 0;
-    else if (sline.status < Http::scOkay)
+    else if (sline.status() < Http::scOkay)
         return 0;
 
     return content_length;
@@ -500,14 +500,10 @@ HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusC
     return true;
 }
 
-void HttpReply::packFirstLineInto(Packer *p, bool unused) const
-{
-    httpStatusLinePackInto(&sline, p);
-}
-
-bool HttpReply::parseFirstLine(const char *blk_start, const char *blk_end)
+bool
+HttpReply::parseFirstLine(const char *blk_start, const char *blk_end)
 {
-    return httpStatusLineParse(&sline, protoPrefix, blk_start, blk_end);
+    return sline.parse(protoPrefix, blk_start, blk_end);
 }
 
 /* handy: resets and returns -1 */
@@ -516,7 +512,7 @@ HttpReply::httpMsgParseError()
 {
     int result(HttpMsg::httpMsgParseError());
     /* indicate an error in the status line */
-    sline.status = Http::scInvalidHeader;
+    sline.set(Http::ProtocolVersion(1,1), Http::scInvalidHeader);
     return result;
 }
 
@@ -531,11 +527,11 @@ HttpReply::expectingBody(const HttpRequestMethod& req_method, int64_t& theSize)
 
     if (req_method == Http::METHOD_HEAD)
         expectBody = false;
-    else if (sline.status == Http::scNoContent)
+    else if (sline.status() == Http::scNoContent)
         expectBody = false;
-    else if (sline.status == Http::scNotModified)
+    else if (sline.status() == Http::scNotModified)
         expectBody = false;
-    else if (sline.status < Http::scOkay)
+    else if (sline.status() < Http::scOkay)
         expectBody = false;
     else
         expectBody = true;
index 3718a0eaf81443e9625c3cbda54e9a75a262a95b..04e95d70ed7c7aeeaeb5c8240638e15d5dbbf569 100644 (file)
@@ -33,7 +33,7 @@
 #include "HttpBody.h"
 #include "HttpMsg.h"
 #include "HttpRequest.h"
-#include "HttpStatusLine.h"
+#include "http/StatusLine.h"
 
 void httpReplyInitModule(void);
 
@@ -83,7 +83,7 @@ public:
     short int keep_alive;
 
     /** \par public, writable, but use httpReply* interfaces when possible */
-    HttpStatusLine sline;
+    Http::StatusLine sline;
 
     HttpBody body;             /**< for small constant memory-resident text bodies only */
 
@@ -163,7 +163,7 @@ private:
     mutable int64_t bodySizeMax; /**< cached result of calcMaxBodySize */
 
 protected:
-    virtual void packFirstLineInto(Packer * p, bool) const;
+    virtual void packFirstLineInto(Packer * p, bool) const { sline.packInto(p); }
 
     virtual bool parseFirstLine(const char *start, const char *end);
 
diff --git a/src/HttpStatusLine.cc b/src/HttpStatusLine.cc
deleted file mode 100644 (file)
index f3835fb..0000000
+++ /dev/null
@@ -1,345 +0,0 @@
-
-/*
- * DEBUG: section 57    HTTP Status-line
- * AUTHOR: Alex Rousskov
- *
- * 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.
- *
- */
-
-#include "squid.h"
-#include "Debug.h"
-#include "HttpStatusLine.h"
-#include "Packer.h"
-
-/* local constants */
-/* AYJ: see bug 2469 - RFC2616 confirms stating 'SP characters' plural! */
-const char *HttpStatusLineFormat = "HTTP/%d.%d %3d %s\r\n";
-const char *IcyStatusLineFormat = "ICY %3d %s\r\n";
-
-void
-httpStatusLineInit(HttpStatusLine * sline)
-{
-    httpStatusLineSet(sline, Http::ProtocolVersion(), Http::scNone, NULL);
-}
-
-void
-httpStatusLineClean(HttpStatusLine * sline)
-{
-    httpStatusLineSet(sline, Http::ProtocolVersion(), Http::scInternalServerError, NULL);
-}
-
-/* set values */
-void
-httpStatusLineSet(HttpStatusLine * sline, Http::ProtocolVersion version, Http::StatusCode status, const char *reason)
-{
-    assert(sline);
-    sline->protocol = AnyP::PROTO_HTTP;
-    sline->version = version;
-    sline->status = status;
-    /* Note: no xstrdup for 'reason', assumes constant 'reasons' */
-    sline->reason = reason;
-}
-
-/**
- * Write HTTP version and status structures into a Packer buffer for output as HTTP status line.
- * Special exemption made for ICY response status lines.
- */
-void
-httpStatusLinePackInto(const HttpStatusLine * sline, Packer * p)
-{
-    assert(sline && p);
-
-    /* handle ICY protocol status line specially. Pass on the bad format. */
-    if (sline->protocol == AnyP::PROTO_ICY) {
-        debugs(57, 9, "packing sline " << sline << " using " << p << ":");
-        debugs(57, 9, "FORMAT=" << IcyStatusLineFormat );
-        debugs(57, 9, "ICY " << sline->status << " " << (sline->reason ? sline->reason : httpStatusString(sline->status)) );
-        packerPrintf(p, IcyStatusLineFormat, sline->status, httpStatusLineReason(sline));
-        return;
-    }
-
-    debugs(57, 9, "packing sline " << sline << " using " << p << ":");
-    debugs(57, 9, "FORMAT=" << HttpStatusLineFormat );
-    debugs(57, 9, "HTTP/" << sline->version.major << "." << sline->version.minor <<
-           " " << sline->status << " " << (sline->reason ? sline->reason : httpStatusString(sline->status)) );
-    packerPrintf(p, HttpStatusLineFormat, sline->version.major,
-                 sline->version.minor, sline->status, httpStatusLineReason(sline));
-}
-
-/*
- * Parse character string into 'sline'.  Note 'end' currently unused,
- * so NULL-termination assumed.
- */
-int
-httpStatusLineParse(HttpStatusLine * sline, const String &protoPrefix, const char *start, const char *end)
-{
-    assert(sline);
-    sline->status = Http::scInvalidHeader;     /* Squid header parsing error */
-
-    // XXX: HttpMsg::parse() has a similar check but is using
-    // casesensitive comparison (which is required by HTTP errata?)
-
-    if (protoPrefix.cmp("ICY", 3) == 0) {
-        debugs(57, 3, "httpStatusLineParse: Invalid HTTP identifier. Detected ICY protocol istead.");
-        sline->protocol = AnyP::PROTO_ICY;
-        start += protoPrefix.size();
-    } else if (protoPrefix.caseCmp(start, protoPrefix.size()) == 0) {
-
-        start += protoPrefix.size();
-
-        if (!xisdigit(*start))
-            return 0;
-
-        if (sscanf(start, "%d.%d", &sline->version.major, &sline->version.minor) != 2) {
-            debugs(57, 7, "httpStatusLineParse: Invalid HTTP identifier.");
-        }
-    } else
-        return 0;
-
-    if (!(start = strchr(start, ' ')))
-        return 0;
-
-    sline->status = static_cast<Http::StatusCode>(atoi(++start));
-
-    /* we ignore 'reason-phrase' */
-    /* Should assert start < end ? */
-    return 1;                  /* success */
-}
-
-const char *
-httpStatusLineReason(const HttpStatusLine * sline)
-{
-    assert(sline);
-    return sline->reason ? sline->reason : httpStatusString(sline->status);
-}
-
-const char *
-httpStatusString(Http::StatusCode status)
-{
-    /* why not to return matching string instead of using "p" ? @?@ */
-    const char *p = NULL;
-
-    switch (status) {
-
-    case 0:
-        p = "Init";            /* we init .status with code 0 */
-        break;
-
-    case Http::scContinue:
-        p = "Continue";
-        break;
-
-    case Http::scSwitchingProtocols:
-        p = "Switching Protocols";
-        break;
-
-    case Http::scOkay:
-        p = "OK";
-        break;
-
-    case Http::scCreated:
-        p = "Created";
-        break;
-
-    case Http::scAccepted:
-        p = "Accepted";
-        break;
-
-    case Http::scNonAuthoritativeInformation:
-        p = "Non-Authoritative Information";
-        break;
-
-    case Http::scNoContent:
-        p = "No Content";
-        break;
-
-    case Http::scResetContent:
-        p = "Reset Content";
-        break;
-
-    case Http::scPartialContent:
-        p = "Partial Content";
-        break;
-
-    case Http::scMultiStatus:
-        p = "Multi-Status";
-        break;
-
-    case Http::scMultipleChoices:
-        p = "Multiple Choices";
-        break;
-
-    case Http::scMovedPermanently:
-        p = "Moved Permanently";
-        break;
-
-    case Http::scMovedTemporarily:
-        p = "Moved Temporarily";
-        break;
-
-    case Http::scSeeOther:
-        p = "See Other";
-        break;
-
-    case Http::scNotModified:
-        p = "Not Modified";
-        break;
-
-    case Http::scUseProxy:
-        p = "Use Proxy";
-        break;
-
-    case Http::scTemporaryRedirect:
-        p = "Temporary Redirect";
-        break;
-
-    case Http::scPermanentRedirect:
-        p = "Permanent Redirect";
-        break;
-
-    case Http::scBadRequest:
-        p = "Bad Request";
-        break;
-
-    case Http::scUnauthorized:
-        p = "Unauthorized";
-        break;
-
-    case Http::scPaymentRequired:
-        p = "Payment Required";
-        break;
-
-    case Http::scForbidden:
-        p = "Forbidden";
-        break;
-
-    case Http::scNotFound:
-        p = "Not Found";
-        break;
-
-    case Http::scMethodNotAllowed:
-        p = "Method Not Allowed";
-        break;
-
-    case Http::scNotAcceptable:
-        p = "Not Acceptable";
-        break;
-
-    case Http::scProxyAuthenticationRequired:
-        p = "Proxy Authentication Required";
-        break;
-
-    case Http::scRequestTimeout:
-        p = "Request Time-out";
-        break;
-
-    case Http::scConflict:
-        p = "Conflict";
-        break;
-
-    case Http::scGone:
-        p = "Gone";
-        break;
-
-    case Http::scLengthRequired:
-        p = "Length Required";
-        break;
-
-    case Http::scPreconditionFailed:
-        p = "Precondition Failed";
-        break;
-
-    case Http::scRequestEntityTooLarge:
-        p = "Request Entity Too Large";
-        break;
-
-    case Http::scRequestUriTooLarge:
-        p = "Request-URI Too Large";
-        break;
-
-    case Http::scUnsupportedMediaType:
-        p = "Unsupported Media Type";
-        break;
-
-    case Http::scRequestedRangeNotSatisfied:
-        p = "Requested Range Not Satisfiable";
-        break;
-
-    case Http::scExpectationFailed:
-        p = "Expectation Failed";
-        break;
-
-    case Http::scInternalServerError:
-        p = "Internal Server Error";
-        break;
-
-    case Http::scNotImplemented:
-        p = "Not Implemented";
-        break;
-
-    case Http::scBadGateway:
-        p = "Bad Gateway";
-        break;
-
-    case Http::scServiceUnavailable:
-        p = "Service Unavailable";
-        break;
-
-    case Http::scGateway_Timeout:
-        p = "Gateway Time-out";
-        break;
-
-    case Http::scHttpVersionNotSupported:
-        p = "HTTP Version not supported";
-        break;
-
-        // RFC 6585
-    case Http::scPreconditionRequired: // 428
-        p = "Precondition Required";
-        break;
-
-    case Http::scTooManyFields: // 429
-        p = "Too Many Requests";
-        break;
-
-    case Http::scRequestHeaderFieldsTooLarge: // 431
-        p = "Request Header Fields Too Large";
-        break;
-
-    case Http::scNetworkAuthenticationRequired: // 511
-        p = "Network Authentication Required";
-        break;
-
-    default:
-        p = "Unknown";
-        debugs(57, 3, "Unknown HTTP status code: " << status);
-        break;
-    }
-
-    return p;
-}
index 050176fdba3059600e964b5d2e691b92febe9d25..8cab7437f9969ac10d176178bf91f0c656d30fa2 100644 (file)
@@ -371,9 +371,6 @@ squid_SOURCES = \
        HttpStateFlags.h \
        http.cc \
        http.h \
-       http/StatusCode.h \
-       HttpStatusLine.cc \
-       HttpStatusLine.h \
        HttpHeaderFieldStat.h \
        HttpHdrCc.h \
        HttpHdrCc.cc \
@@ -1153,9 +1150,6 @@ tests_testHttpReply_SOURCES=\
        HttpMsg.h \
        HttpReply.cc \
        HttpReply.h \
-       http/StatusCode.h \
-       HttpStatusLine.cc \
-       HttpStatusLine.h \
        Mem.h \
        mem.cc \
        RegexList.h \
@@ -1203,6 +1197,7 @@ nodist_tests_testHttpReply_SOURCES=\
        $(TESTSOURCES)
 tests_testHttpReply_LDFLAGS = $(LIBADD_DL)
 tests_testHttpReply_LDADD=\
+       http/libsquid-http.la \
        acl/libacls.la \
        acl/libapi.la \
        acl/libstate.la \
@@ -1479,7 +1474,6 @@ tests_testCacheManager_SOURCES = \
        HttpHdrScTarget.cc \
        HttpMsg.cc \
        HttpReply.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        $(IPC_SOURCE) \
@@ -1665,7 +1659,6 @@ tests_testDiskIO_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        int.h \
        int.cc \
        SquidList.h \
@@ -1895,7 +1888,6 @@ tests_testEvent_SOURCES = \
        RequestFlags.cc \
        HttpRequest.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        $(IPC_SOURCE) \
@@ -2142,7 +2134,6 @@ tests_testEventLoop_SOURCES = \
        RequestFlags.cc \
        HttpRequest.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        $(IPC_SOURCE) \
@@ -2386,7 +2377,6 @@ tests_test_http_range_SOURCES = \
        RequestFlags.cc \
        HttpRequest.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        int.h \
@@ -2674,7 +2664,6 @@ tests_testHttpRequest_SOURCES = \
        HttpHdrScTarget.cc \
        HttpMsg.cc \
        HttpReply.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        $(IPC_SOURCE) \
@@ -3077,7 +3066,6 @@ tests_testUfs_SOURCES = \
        HttpBody.h \
        HttpBody.cc \
        HttpReply.cc \
-       HttpStatusLine.cc \
        int.h \
        int.cc \
        RequestFlags.h \
@@ -3267,7 +3255,6 @@ tests_testRock_SOURCES = \
        HttpMsg.cc \
        HttpReply.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        int.h \
        int.cc \
        SquidList.h \
@@ -3419,7 +3406,6 @@ tests_testCoss_SOURCES = \
        HttpBody.h \
        HttpBody.cc \
        HttpReply.cc \
-       HttpStatusLine.cc \
        int.h \
        int.cc \
        SquidList.h \
@@ -3646,7 +3632,6 @@ tests_testURL_SOURCES = \
        RequestFlags.cc \
        HttpRequest.cc \
        HttpRequestMethod.cc \
-       HttpStatusLine.cc \
        icp_v2.cc \
        icp_v3.cc \
        $(IPC_SOURCE) \
index 8bfb6a3ac662d2b1b7cb0918cf4d624cc8469eae..41d4a36c32bc8f9013c86148e282efcf19a90918 100644 (file)
@@ -508,7 +508,7 @@ ServerStateData::maybePurgeOthers()
         return;
 
     // and probably only if the response was successful
-    if (theFinalReply->sline.status >= 400)
+    if (theFinalReply->sline.status() >= 400)
         return;
 
     // XXX: should we use originalRequest() here?
index d2a9b941b9b39d68159d8cfbcaf448a5afb77fc3..43fe185973c94158cd8ff22f5846b7462819223e 100644 (file)
@@ -296,7 +296,7 @@ asHandleReply(void *data, StoreIOBuffer result)
         debugs(53, DBG_IMPORTANT, "asHandleReply: Called with Error set and size=" << (unsigned int) result.length);
         asStateFree(asState);
         return;
-    } else if (Http::scOkay != e->getReply()->sline.status) {
+    } else if (e->getReply()->sline.status() != Http::scOkay) {
         debugs(53, DBG_IMPORTANT, "WARNING: AS " << asState->as_number << " whois request failed");
         asStateFree(asState);
         return;
index c5582b999a501c1a1c5d75f96b62bda35c26e7f7..a20120cfa926168f37ad35b81973ea5c50316381 100644 (file)
@@ -156,11 +156,11 @@ aclParseHTTPStatusList(SplayNode<acl_httpstatus_data *> **curlist)
 int
 ACLHTTPStatus::match(ACLChecklist *checklist)
 {
-    return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status);
+    return aclMatchHTTPStatus(&data, Filled(checklist)->reply->sline.status());
 }
 
 int
-aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, Http::StatusCode status)
+aclMatchHTTPStatus(SplayNode<acl_httpstatus_data*> **dataptr, const Http::StatusCode status)
 {
 
     acl_httpstatus_data X(status);
index ecdea7d70358aff448aa0fabf4ce28c72eeebcec..cb97ac106415b2ace4e0a289ad3eeb9f5fc7ca38 100644 (file)
@@ -292,29 +292,26 @@ Adaptation::Ecap::StatusLineRep::StatusLineRep(HttpReply &aMessage):
 void
 Adaptation::Ecap::StatusLineRep::statusCode(int code)
 {
-    // TODO: why is .status a enum? Do we not support unknown statuses?
-    theMessage.sline.status = static_cast<Http::StatusCode>(code);
+    theMessage.sline.set(theMessage.sline.version, static_cast<Http::StatusCode>(code), theMessage.sline.reason());
 }
 
 int
 Adaptation::Ecap::StatusLineRep::statusCode() const
 {
-    // TODO: see statusCode(code) TODO above
-    return static_cast<int>(theMessage.sline.status);
+    // TODO: remove cast when possible
+    return static_cast<int>(theMessage.sline.status());
 }
 
 void
-Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area &)
+Adaptation::Ecap::StatusLineRep::reasonPhrase(const Area &str)
 {
-    // Squid does not support custom reason phrases
-    theMessage.sline.reason = NULL;
+    theMessage.sline.set(theMessage.sline.version, theMessage.sline.status(), str.c_str());
 }
 
 Adaptation::Ecap::StatusLineRep::Area
 Adaptation::Ecap::StatusLineRep::reasonPhrase() const
 {
-    return theMessage.sline.reason ?
-           Area::FromTempString(std::string(theMessage.sline.reason)) : Area();
+    return Area::FromTempString(std::string(theMessage.sline.reason()));
 }
 
 libecap::Version
index a4c1f621422fa273ed37f517efc40873ed85af8b..1355a9cca08e7f6f67750ac0aa0d006fb1e321ea 100644 (file)
@@ -130,8 +130,10 @@ bool Adaptation::Icap::Launcher::canRepeat(Adaptation::Icap::XactAbortInfo &info
     if (!info.icapReply) // did not get to read an ICAP reply; a timeout?
         return true;
 
-    debugs(93,9, HERE << info.icapReply->sline.status);
-    if (!info.icapReply->sline.status) // failed to parse the reply; I/O err
+    debugs(93,9, info.icapReply->sline.status());
+    // XXX: Http::scNone is not the only sign of parse error
+    // XXX: if there is a specific HTTP error code describing the problem, that may be set
+    if (info.icapReply->sline.status() == Http::scNone) // failed to parse the reply; I/O err
         return true;
 
     ACLFilledChecklist *cl =
index 3d19e2063240a467ed68e6367a59b2c0dc25013f..dde83bc645677b467de54f7c6eec35bbac011435 100644 (file)
@@ -779,14 +779,14 @@ void Adaptation::Icap::ModXact::parseIcapHead()
         reuseConnection = false;
     }
 
-    switch (icapReply->sline.status) {
+    switch (icapReply->sline.status()) {
 
-    case 100:
+    case Http::scContinue:
         handle100Continue();
         break;
 
-    case 200:
-    case 201: // Symantec Scan Engine 5.0 and later when modifying HTTP msg
+    case Http::scOkay:
+    case Http::scCreated: // Symantec Scan Engine 5.0 and later when modifying HTTP msg
 
         if (!validate200Ok()) {
             throw TexcHere("Invalid ICAP Response");
@@ -796,16 +796,16 @@ void Adaptation::Icap::ModXact::parseIcapHead()
 
         break;
 
-    case 204:
+    case Http::scNoContent:
         handle204NoContent();
         break;
 
-    case 206:
+    case Http::scPartialContent:
         handle206PartialContent();
         break;
 
     default:
-        debugs(93, 5, HERE << "ICAP status " << icapReply->sline.status);
+        debugs(93, 5, "ICAP status " << icapReply->sline.status());
         handleUnknownScode();
         break;
     }
@@ -1294,7 +1294,7 @@ void Adaptation::Icap::ModXact::finalizeLogInfo()
     }
 
     if (reply_) {
-        al.http.code = reply_->sline.status;
+        al.http.code = reply_->sline.status();
         al.http.content_type = reply_->content_type.termedBuf();
         if (replyHttpBodySize >= 0) {
             al.cache.replySize = replyHttpBodySize + reply_->hdr_sz;
index 219589c1de21a976c3c79cf88e31b2c06a4315c8..e219a3751ca5081b14ab17d17a6fd3524915cdf4 100644 (file)
@@ -75,7 +75,7 @@ void Adaptation::Icap::Options::configure(const HttpReply *reply)
 
     const HttpHeader *h = &reply->header;
 
-    if (reply->sline.status != 200)
+    if (reply->sline.status() != Http::scOkay)
         error = "unsupported status code of OPTIONS response";
 
     // Methods
index a7a80e76a5be5406162a57f9bd20ed0955686c1b..9fcc83bcb1b5758caaba81050dd5dee3c3245539 100644 (file)
@@ -577,7 +577,7 @@ void Adaptation::Icap::Xaction::finalizeLogInfo()
     if (icapReply != NULL) {
         al.icap.reply = icapReply.getRaw();
         HTTPMSGLOCK(al.icap.reply);
-        al.icap.resStatus = icapReply->sline.status;
+        al.icap.resStatus = icapReply->sline.status();
     }
 }
 
index ff38b8780c0f2c540982c8921852a8e5cb312508..899e381964c8b78c5875d0eb965a95caa8eca49b 100644 (file)
@@ -479,7 +479,7 @@ Auth::UserRequest::addReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointe
 {
     http_hdr_type type;
 
-    switch (rep->sline.status) {
+    switch (rep->sline.status()) {
 
     case Http::scProxyAuthenticationRequired:
         /* Proxy authorisation needed */
@@ -500,8 +500,8 @@ Auth::UserRequest::addReplyAuthHeader(HttpReply * rep, Auth::UserRequest::Pointe
 
     debugs(29, 9, HERE << "headertype:" << type << " authuser:" << auth_user_request);
 
-    if (((rep->sline.status == Http::scProxyAuthenticationRequired)
-            || (rep->sline.status == Http::scUnauthorized)) && internal)
+    if (((rep->sline.status() == Http::scProxyAuthenticationRequired)
+            || (rep->sline.status() == Http::scUnauthorized)) && internal)
         /* this is a authenticate-needed response */
     {
 
index 98f97d5529e8fa4465de55282d281ccec9dd01c0..3074d10c84f1562fc5bc19c4629803966670cfe6 100644 (file)
@@ -200,8 +200,8 @@ Auth::Digest::UserRequest::addAuthenticationInfoHeader(HttpReply * rep, int acce
     http_hdr_type type;
 
     /* don't add to authentication error pages */
-    if ((!accel && rep->sline.status == Http::scProxyAuthenticationRequired)
-            || (accel && rep->sline.status == Http::scUnauthorized))
+    if ((!accel && rep->sline.status() == Http::scProxyAuthenticationRequired)
+            || (accel && rep->sline.status() == Http::scUnauthorized))
         return;
 
     type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;
@@ -233,8 +233,8 @@ Auth::Digest::UserRequest::addAuthenticationInfoTrailer(HttpReply * rep, int acc
         return;
 
     /* don't add to authentication error pages */
-    if ((!accel && rep->sline.status == Http::scProxyAuthenticationRequired)
-            || (accel && rep->sline.status == Http::scUnauthorized))
+    if ((!accel && rep->sline.status() == Http::scProxyAuthenticationRequired)
+            || (accel && rep->sline.status() == Http::scUnauthorized))
         return;
 
     type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;
index c24fe9cd568320dc838e9ee5e4b9f56a120b7f53..d4f08a7f362a40a614bb80f801dee2b209ef5823 100644 (file)
@@ -385,8 +385,8 @@ Auth::Negotiate::UserRequest::addAuthenticationInfoHeader(HttpReply * rep, int a
         return;
 
     /* don't add to authentication error pages */
-    if ((!accel && rep->sline.status == Http::scProxyAuthenticationRequired)
-            || (accel && rep->sline.status == Http::scUnauthorized))
+    if ((!accel && rep->sline.status() == Http::scProxyAuthenticationRequired)
+            || (accel && rep->sline.status() == Http::scUnauthorized))
         return;
 
     type = accel ? HDR_AUTHENTICATION_INFO : HDR_PROXY_AUTHENTICATION_INFO;
index 4f2f8a11d2e1edb7ba095254103a3634397e73f1..9d881b5cf463989aa7a5029f3b95e7ec59334735 100644 (file)
@@ -411,7 +411,7 @@ CacheManager::Start(const Comm::ConnectionPointer &client, HttpRequest * request
         err.url = xstrdup(entry->url());
         HttpReply *rep = err.BuildHttpReply();
         if (strncmp(rep->body.content(),"Internal Error:", 15) == 0)
-            rep->sline.status = Http::scNotFound;
+            rep->sline.set(Http::ProtocolVersion(1,1), Http::scNotFound);
         // Allow cachemgr and other XHR scripts access to our version string
         if (request->header.has(HDR_ORIGIN)) {
             rep->header.putExt("Access-Control-Allow-Origin",request->header.getStr(HDR_ORIGIN));
index b2422fd574f46441c35aebb720b8325186a50465..626018be25837a2f638cb54e3d9649859e9e652b 100644 (file)
@@ -649,10 +649,10 @@ ClientHttpRequest::logRequest()
     debugs(33, 9, "clientLogRequest: al.url='" << al->url << "'");
 
     if (al->reply) {
-        al->http.code = al->reply->sline.status;
+        al->http.code = al->reply->sline.status();
         al->http.content_type = al->reply->content_type.termedBuf();
     } else if (loggingEntry() && loggingEntry()->mem_obj) {
-        al->http.code = loggingEntry()->mem_obj->getReply()->sline.status;
+        al->http.code = loggingEntry()->mem_obj->getReply()->sline.status();
         al->http.content_type = loggingEntry()->mem_obj->getReply()->content_type.termedBuf();
     }
 
@@ -1278,7 +1278,7 @@ ClientSocketContext::buildRangeHeader(HttpReply * rep)
 
     if (!rep)
         range_err = "no [parse-able] reply";
-    else if ((rep->sline.status != Http::scOkay) && (rep->sline.status != Http::scPartialContent))
+    else if ((rep->sline.status() != Http::scOkay) && (rep->sline.status() != Http::scPartialContent))
         range_err = "wrong status code";
     else if (hdr->has(HDR_CONTENT_RANGE))
         range_err = "origin server does ranges";
@@ -1310,8 +1310,8 @@ ClientSocketContext::buildRangeHeader(HttpReply * rep)
         delete http->request->range;
         http->request->range = NULL;
     } else {
-        /* XXX: TODO: Review, this unconditional set may be wrong. - TODO: review. */
-        httpStatusLineSet(&rep->sline, rep->sline.version, Http::scPartialContent, NULL);
+        /* XXX: TODO: Review, this unconditional set may be wrong. */
+        rep->sline.set(rep->sline.version, Http::scPartialContent);
         // web server responded with a valid, but unexpected range.
         // will (try-to) forward as-is.
         //TODO: we should cope with multirange request/responses
index e78b2132bc05acc84301596b2e1bf735c9f54f5c..f5b16aefa5725f30dfeb1dc339c6638c8ce617d0 100644 (file)
@@ -376,7 +376,7 @@ clientReplyContext::handleIMSReply(StoreIOBuffer result)
     /* update size of the request */
     reqsize = result.length + reqofs;
 
-    const Http::StatusCode status = http->storeEntry()->getReply()->sline.status;
+    const Http::StatusCode status = http->storeEntry()->getReply()->sline.status();
 
     // request to origin was aborted
     if (EBIT_TEST(http->storeEntry()->flags, ENTRY_ABORTED)) {
@@ -405,7 +405,7 @@ clientReplyContext::handleIMSReply(StoreIOBuffer result)
         } else {
             // send existing entry, it's still valid
             debugs(88, 3, "handleIMSReply: origin replied 304, revalidating existing entry and sending " <<
-                   old_rep->sline.status << " to client");
+                   old_rep->sline.status() << " to client");
             sendClientOldEntry();
         }
     }
@@ -428,7 +428,7 @@ clientReplyContext::handleIMSReply(StoreIOBuffer result)
         // ignore and let client have old entry
         http->logType = LOG_TCP_REFRESH_FAIL_OLD;
         debugs(88, 3, "handleIMSReply: origin replied with error " <<
-               status << ", sending old entry (" << old_rep->sline.status << ") to client");
+               status << ", sending old entry (" << old_rep->sline.status() << ") to client");
         sendClientOldEntry();
     }
 }
@@ -714,9 +714,9 @@ clientReplyContext::processConditional(StoreIOBuffer &result)
 {
     StoreEntry *const e = http->storeEntry();
 
-    if (e->getReply()->sline.status != Http::scOkay) {
+    if (e->getReply()->sline.status() != Http::scOkay) {
         debugs(88, 4, "clientReplyContext::processConditional: Reply code " <<
-               e->getReply()->sline.status << " != 200");
+               e->getReply()->sline.status() << " != 200");
         http->logType = LOG_TCP_MISS;
         processMiss();
         return;
@@ -1430,8 +1430,8 @@ clientReplyContext::buildReplyHeader()
 #if USE_AUTH
     /* Handle authentication headers */
     if (http->logType == LOG_TCP_DENIED &&
-            ( reply->sline.status == Http::scProxyAuthenticationRequired ||
-              reply->sline.status == Http::scUnauthorized)
+            ( reply->sline.status() == Http::scProxyAuthenticationRequired ||
+              reply->sline.status() == Http::scUnauthorized)
        ) {
         /* Add authentication header */
         /*! \todo alter errorstate to be accel on|off aware. The 0 on the next line
@@ -1461,7 +1461,7 @@ clientReplyContext::buildReplyHeader()
                                      (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) {
+    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) {
@@ -1936,7 +1936,7 @@ clientReplyContext::processReplyAccess ()
     /** Don't block our own responses or HTTP status messages */
     if (http->logType == LOG_TCP_DENIED ||
             http->logType == LOG_TCP_DENIED_REPLY ||
-            alwaysAllowResponse(reply->sline.status)) {
+            alwaysAllowResponse(reply->sline.status())) {
         headers_sz = reply->hdr_sz;
         processReplyAccessResult(ACCESS_ALLOWED);
         return;
@@ -2018,8 +2018,8 @@ clientReplyContext::processReplyAccessResult(const allow_t &accessAllowed)
 
 #if USE_SQUID_ESI
 
-    if (http->flags.accel && reply->sline.status != Http::scForbidden &&
-            !alwaysAllowResponse(reply->sline.status) &&
+    if (http->flags.accel && reply->sline.status() != Http::scForbidden &&
+            !alwaysAllowResponse(reply->sline.status()) &&
             esiEnableProcessing(reply)) {
         debugs(88, 2, "Enabling ESI processing for " << http->uri);
         clientStreamInsertHead(&http->client_stream, esiStreamRead,
index af2b7f793c3957ea720cdd3fbaeb5f9735047730..939ee507dc2814fff7afe29085d50f9bbe6e196f 100644 (file)
@@ -888,7 +888,7 @@ ESIContextNew (HttpReply *rep, clientStreamNode *thisNode, ClientHttpRequest *ht
     rv->rep = rep;
     rv->cbdataLocker = rv;
 
-    if (esiAlwaysPassthrough(rep->sline.status)) {
+    if (esiAlwaysPassthrough(rep->sline.status())) {
         rv->flags.passthrough = 1;
     } else {
         /* remove specific headers for ESI to prevent
index 837056e06891cbc529a0473c604608cd19e6d35b..2bb907f71f3a60a43cb20b1d73973b58e2834eaf 100644 (file)
@@ -114,7 +114,7 @@ esiBufferRecipient (clientStreamNode *node, ClientHttpRequest *http, HttpReply *
         assert(rep == NULL);
     } else {
         if (rep) {
-            if (rep->sline.status != Http::scOkay) {
+            if (rep->sline.status() != Http::scOkay) {
                 rep = NULL;
                 esiStream->include->includeFail (esiStream);
                 esiStream->finished = 1;
index 18a357de02b5d0cbdf469cf550ff03f9de6713d7..5d594e0197a91a0a3ecd2362d31f745d81b3ed35 100644 (file)
@@ -399,7 +399,7 @@ FwdState::startConnectionOrFail()
 void
 FwdState::fail(ErrorState * errorState)
 {
-    debugs(17, 3, HERE << err_type_str[errorState->type] << " \"" << httpStatusString(errorState->httpStatus) << "\"\n\t" << entry->url()  );
+    debugs(17, 3, err_type_str[errorState->type] << " \"" << Http::StatusCodeString(errorState->httpStatus) << "\"\n\t" << entry->url());
 
     delete err;
     err = errorState;
@@ -455,16 +455,16 @@ FwdState::unregister(int fd)
 void
 FwdState::complete()
 {
-    debugs(17, 3, HERE << entry->url() << "\n\tstatus " << entry->getReply()->sline.status  );
+    debugs(17, 3, HERE << entry->url() << "\n\tstatus " << entry->getReply()->sline.status());
 #if URL_CHECKSUM_DEBUG
 
     entry->mem_obj->checkUrlChecksum();
 #endif
 
-    logReplyStatus(n_tries, entry->getReply()->sline.status);
+    logReplyStatus(n_tries, entry->getReply()->sline.status());
 
     if (reforward()) {
-        debugs(17, 3, HERE << "re-forwarding " << entry->getReply()->sline.status << " " << entry->url());
+        debugs(17, 3, HERE << "re-forwarding " << entry->getReply()->sline.status() << " " << entry->url());
 
         if (Comm::IsConnOpen(serverConn))
             unregister(serverConn);
@@ -477,9 +477,9 @@ FwdState::complete()
 
     } else {
         if (Comm::IsConnOpen(serverConn))
-            debugs(17, 3, HERE << "server FD " << serverConnection()->fd << " not re-forwarding status " << entry->getReply()->sline.status);
+            debugs(17, 3, HERE << "server FD " << serverConnection()->fd << " not re-forwarding status " << entry->getReply()->sline.status());
         else
-            debugs(17, 3, HERE << "server (FD closed) not re-forwarding status " << entry->getReply()->sline.status);
+            debugs(17, 3, HERE << "server (FD closed) not re-forwarding status " << entry->getReply()->sline.status());
         EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
         entry->complete();
 
@@ -1380,7 +1380,7 @@ FwdState::reforward()
         return 0;
     }
 
-    const Http::StatusCode s = e->getReply()->sline.status;
+    const Http::StatusCode s = e->getReply()->sline.status();
     debugs(17, 3, HERE << "status " << s);
     return reforwardableStatus(s);
 }
index 7dc88aa28e3e7c24d4db841362338a9acd3823ce..685204132fc7b76aa4fc2ef5b3382ce5177edeff 100644 (file)
@@ -442,7 +442,7 @@ HttpStateData::cacheableReply()
             return 0;
         }
 
-    switch (rep->sline.status) {
+    switch (rep->sline.status()) {
         /* Responses that are cacheable */
 
     case Http::scOkay:
@@ -464,7 +464,7 @@ HttpStateData::cacheableReply()
             debugs(22, 3, "NO because refreshIsCachable() returned non-cacheable..");
             return 0;
         } else {
-            debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status);
+            debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status());
             return 1;
         }
         /* NOTREACHED */
@@ -475,14 +475,14 @@ HttpStateData::cacheableReply()
     case Http::scMovedTemporarily:
     case Http::scTemporaryRedirect:
         if (rep->date <= 0) {
-            debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status << " and Date missing/invalid");
+            debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Date missing/invalid");
             return 0;
         }
         if (rep->expires > rep->date) {
-            debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status << " and Expires > Date");
+            debugs(22, 3, HERE << "YES because HTTP status " << rep->sline.status() << " and Expires > Date");
             return 1;
         } else {
-            debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status << " and Expires <= Date");
+            debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status() << " and Expires <= Date");
             return 0;
         }
         /* NOTREACHED */
@@ -513,7 +513,7 @@ HttpStateData::cacheableReply()
     case Http::scServiceUnavailable:
 
     case Http::scGateway_Timeout:
-        debugs(22, 3, HERE << "MAYBE because HTTP status " << rep->sline.status);
+        debugs(22, 3, HERE << "MAYBE because HTTP status " << rep->sline.status());
         return -1;
 
         /* NOTREACHED */
@@ -550,12 +550,12 @@ HttpStateData::cacheableReply()
     case Http::scRequestedRangeNotSatisfied:
     case Http::scExpectationFailed:
 
-        debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status);
+        debugs(22, 3, HERE << "NO because HTTP status " << rep->sline.status());
         return 0;
 
     default:
         /* RFC 2616 section 6.1.1: an unrecognized response MUST NOT be cached. */
-        debugs (11, 3, HERE << "NO because unknown HTTP status code " << rep->sline.status);
+        debugs (11, 3, HERE << "NO because unknown HTTP status code " << rep->sline.status());
         return 0;
 
         /* NOTREACHED */
@@ -714,8 +714,9 @@ HttpStateData::processReplyHeader()
         if (!parsed && error > 0) { // unrecoverable parsing error
             debugs(11, 3, "processReplyHeader: Non-HTTP-compliant header: '" <<  readBuf->content() << "'");
             flags.headers_parsed = true;
-            newrep->sline.version = Http::ProtocolVersion(1,1);
-            newrep->sline.status = error;
+            // 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);
             HttpReply *vrep = setVirginReply(newrep);
             entry->replaceHttpReply(vrep);
             ctx_exit(ctx);
@@ -739,7 +740,7 @@ HttpStateData::processReplyHeader()
 
     newrep->removeStaleWarnings();
 
-    if (newrep->sline.protocol == AnyP::PROTO_HTTP && newrep->sline.status >= 100 && newrep->sline.status < 200) {
+    if (newrep->sline.protocol == AnyP::PROTO_HTTP && newrep->sline.status() >= 100 && newrep->sline.status() < 200) {
         handle1xx(newrep);
         ctx_exit(ctx);
         return;
@@ -763,7 +764,7 @@ HttpStateData::processReplyHeader()
 
     processSurrogateControl (vrep);
 
-    request->hier.peer_reply_status = newrep->sline.status;
+    request->hier.peer_reply_status = newrep->sline.status();
 
     ctx_exit(ctx);
 }
@@ -848,7 +849,7 @@ bool HttpStateData::peerSupportsConnectionPinning() const
     /*The peer supports connection pinning and the http reply status
       is not unauthorized, so the related connection can be pinned
      */
-    if (rep->sline.status != Http::scUnauthorized)
+    if (rep->sline.status() != Http::scUnauthorized)
         return true;
 
     /*The server respond with Http::scUnauthorized and the peer configured
@@ -897,17 +898,16 @@ HttpStateData::haveParsedReplyHeaders()
     Ctx ctx = ctx_enter(entry->mem_obj->url);
     HttpReply *rep = finalReply();
 
-    if (rep->sline.status == Http::scPartialContent &&
-            rep->content_range)
+    if (rep->sline.status() == Http::scPartialContent && rep->content_range)
         currentOffset = rep->content_range->spec.offset;
 
     entry->timestampsSet();
 
     /* Check if object is cacheable or not based on reply code */
-    debugs(11, 3, "haveParsedReplyHeaders: HTTP CODE: " << rep->sline.status);
+    debugs(11, 3, "HTTP CODE: " << rep->sline.status());
 
     if (neighbors_do_private_keys)
-        httpMaybeRemovePublic(entry, rep->sline.status);
+        httpMaybeRemovePublic(entry, rep->sline.status());
 
     if (rep->header.has(HDR_VARY)
 #if X_ACCELERATOR_VARY
@@ -918,7 +918,7 @@ HttpStateData::haveParsedReplyHeaders()
 
         if (!vary) {
             entry->makePrivate();
-            if (!fwd->reforwardableStatus(rep->sline.status))
+            if (!fwd->reforwardableStatus(rep->sline.status()))
                 EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
             goto no_cache;
         }
@@ -930,7 +930,7 @@ HttpStateData::haveParsedReplyHeaders()
      * If its not a reply that we will re-forward, then
      * allow the client to get it.
      */
-    if (!fwd->reforwardableStatus(rep->sline.status))
+    if (!fwd->reforwardableStatus(rep->sline.status()))
         EBIT_CLR(entry->flags, ENTRY_FWD_HDR_WAIT);
 
     switch (cacheableReply()) {
@@ -1260,7 +1260,7 @@ HttpStateData::continueAfterParsingHeader()
     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::StatusCode s = vrep->sline.status();
             const Http::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() );
@@ -2322,7 +2322,7 @@ HttpStateData::handleMoreRequestBodyAvailable()
             flags.abuse_detected = true;
             debugs(11, DBG_IMPORTANT, "http handleMoreRequestBodyAvailable: Likely proxy abuse detected '" << request->client_addr << "' -> '" << entry->url() << "'" );
 
-            if (virginReply()->sline.status == Http::scInvalidHeader) {
+            if (virginReply()->sline.status() == Http::scInvalidHeader) {
                 serverConnection->close();
                 return;
             }
index a887316ff67ac5f786aea9e7fa2b00c4ae4fd787..7c7530bd1a55d000c06162d2ccf40da13e3242be 100644 (file)
@@ -7,7 +7,10 @@ libsquid_http_la_SOURCES = \
        MethodType.cc \
        MethodType.h \
        ProtocolVersion.h \
-       StatusCode.h
+       StatusCode.cc \
+       StatusCode.h \
+       StatusLine.cc \
+       StatusLine.h
 
 MethodType.cc: MethodType.h $(top_srcdir)/src/mk-string-arrays.awk
        ($(AWK) -f $(top_srcdir)/src/mk-string-arrays.awk < $(srcdir)/MethodType.h | \
diff --git a/src/http/StatusCode.cc b/src/http/StatusCode.cc
new file mode 100644 (file)
index 0000000..f9e2aa8
--- /dev/null
@@ -0,0 +1,203 @@
+#include "squid.h"
+#include "Debug.h"
+#include "http/StatusCode.h"
+
+const char *
+Http::StatusCodeString(const Http::StatusCode status)
+{
+    switch (status) {
+
+    case Http::scNone:
+        return "Init";         /* we init .status with code 0 */
+        break;
+
+    case Http::scContinue:
+        return "Continue";
+        break;
+
+    case Http::scSwitchingProtocols:
+        return "Switching Protocols";
+        break;
+
+    case Http::scOkay:
+        return "OK";
+        break;
+
+    case Http::scCreated:
+        return "Created";
+        break;
+
+    case Http::scAccepted:
+        return "Accepted";
+        break;
+
+    case Http::scNonAuthoritativeInformation:
+        return "Non-Authoritative Information";
+        break;
+
+    case Http::scNoContent:
+        return "No Content";
+        break;
+
+    case Http::scResetContent:
+        return "Reset Content";
+        break;
+
+    case Http::scPartialContent:
+        return "Partial Content";
+        break;
+
+    case Http::scMultiStatus:
+        return "Multi-Status";
+        break;
+
+    case Http::scMultipleChoices:
+        return "Multiple Choices";
+        break;
+
+    case Http::scMovedPermanently:
+        return "Moved Permanently";
+        break;
+
+    case Http::scMovedTemporarily:
+        return "Moved Temporarily";
+        break;
+
+    case Http::scSeeOther:
+        return "See Other";
+        break;
+
+    case Http::scNotModified:
+        return "Not Modified";
+        break;
+
+    case Http::scUseProxy:
+        return "Use Proxy";
+        break;
+
+    case Http::scTemporaryRedirect:
+        return "Temporary Redirect";
+        break;
+
+    case Http::scPermanentRedirect:
+        return "Permanent Redirect";
+        break;
+
+    case Http::scBadRequest:
+        return "Bad Request";
+        break;
+
+    case Http::scUnauthorized:
+        return "Unauthorized";
+        break;
+
+    case Http::scPaymentRequired:
+        return "Payment Required";
+        break;
+
+    case Http::scForbidden:
+        return "Forbidden";
+        break;
+
+    case Http::scNotFound:
+        return "Not Found";
+        break;
+
+    case Http::scMethodNotAllowed:
+        return "Method Not Allowed";
+        break;
+
+    case Http::scNotAcceptable:
+        return "Not Acceptable";
+        break;
+
+    case Http::scProxyAuthenticationRequired:
+        return "Proxy Authentication Required";
+        break;
+
+    case Http::scRequestTimeout:
+        return "Request Time-out";
+        break;
+
+    case Http::scConflict:
+        return "Conflict";
+        break;
+
+    case Http::scGone:
+        return "Gone";
+        break;
+
+    case Http::scLengthRequired:
+        return "Length Required";
+        break;
+
+    case Http::scPreconditionFailed:
+        return "Precondition Failed";
+        break;
+
+    case Http::scRequestEntityTooLarge:
+        return "Request Entity Too Large";
+        break;
+
+    case Http::scRequestUriTooLarge:
+        return "Request-URI Too Large";
+        break;
+
+    case Http::scUnsupportedMediaType:
+        return "Unsupported Media Type";
+        break;
+
+    case Http::scRequestedRangeNotSatisfied:
+        return "Requested Range Not Satisfiable";
+        break;
+
+    case Http::scExpectationFailed:
+        return "Expectation Failed";
+        break;
+
+    case Http::scInternalServerError:
+        return "Internal Server Error";
+        break;
+
+    case Http::scNotImplemented:
+        return "Not Implemented";
+        break;
+
+    case Http::scBadGateway:
+        return "Bad Gateway";
+        break;
+
+    case Http::scServiceUnavailable:
+        return "Service Unavailable";
+        break;
+
+    case Http::scGateway_Timeout:
+        return "Gateway Time-out";
+        break;
+
+    case Http::scHttpVersionNotSupported:
+        return "HTTP Version not supported";
+        break;
+
+        // RFC 6585
+    case Http::scPreconditionRequired: // 428
+        return "Precondition Required";
+        break;
+
+    case Http::scTooManyFields: // 429
+        return "Too Many Requests";
+        break;
+
+    case Http::scRequestHeaderFieldsTooLarge: // 431
+        return "Request Header Fields Too Large";
+        break;
+
+    case Http::scNetworkAuthenticationRequired: // 511
+        return "Network Authentication Required";
+        break;
+
+    default:
+        debugs(57, 3, "Unknown HTTP status code: " << status);
+        return "Unknown";
+    }
+}
index d95b0092dadff570efa2f2e458d9286c04e9e0dc..6d73844a0d159d6da47d918607834ae24de9c227 100644 (file)
@@ -68,6 +68,8 @@ typedef enum {
     scHeaderTooLarge = 601         /* Header too large to process */
 } StatusCode;
 
+const char *StatusCodeString(const Http::StatusCode status);
+
 } // namespace Http
 
 #endif /* _SQUID_SRC_HTTP_STATUSCODE_H */
diff --git a/src/http/StatusLine.cc b/src/http/StatusLine.cc
new file mode 100644 (file)
index 0000000..d6443e0
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ * DEBUG: section 57    HTTP Status-line
+ * AUTHOR: Alex Rousskov
+ *
+ * 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.
+ *
+ */
+
+#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)
+{
+    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 */
+    /* AYJ: see bug 2469 - RFC2616 confirms stating 'SP characters' plural! */
+    static const char *Http1StatusLineFormat = "HTTP/%d.%d %3d %s\r\n";
+    static const char *IcyStatusLineFormat = "ICY %3d %s\r\n";
+
+    /* handle ICY protocol status line specially. Pass on the bad format. */
+    if (protocol == AnyP::PROTO_ICY) {
+        debugs(57, 9, "packing sline " << this << " using " << p << ":");
+        debugs(57, 9, "FORMAT=" << IcyStatusLineFormat );
+        debugs(57, 9, "ICY " << status() << " " << reason());
+        packerPrintf(p, IcyStatusLineFormat, status(), reason());
+        return;
+    }
+
+    debugs(57, 9, "packing sline " << this << " using " << p << ":");
+    debugs(57, 9, "FORMAT=" << Http1StatusLineFormat );
+    debugs(57, 9, "HTTP/" << version.major << "." << version.minor << " " << status() << " " << reason());
+    packerPrintf(p, Http1StatusLineFormat, version.major, version.minor, status(), reason());
+}
+
+/*
+ * Parse character string.
+ * XXX: Note 'end' currently unused, so NULL-termination assumed.
+ */
+bool
+Http::StatusLine::parse(const String &protoPrefix, const char *start, const char *end)
+{
+    status_ = Http::scInvalidHeader;   /* Squid header parsing error */
+
+    // XXX: HttpMsg::parse() has a similar check but is using
+    // casesensitive comparison (which is required by HTTP errata?)
+
+    if (protoPrefix.cmp("ICY", 3) == 0) {
+        debugs(57, 3, "Invalid HTTP identifier. Detected ICY protocol istead.");
+        protocol = AnyP::PROTO_ICY;
+        start += protoPrefix.size();
+    } else if (protoPrefix.caseCmp(start, protoPrefix.size()) == 0) {
+
+        start += protoPrefix.size();
+
+        if (!xisdigit(*start))
+            return false;
+
+        // XXX: HTTPbis have defined this to be single-digit version numbers. no need to sscanf()
+        // XXX: furthermore, only HTTP/1 will be using ASCII format digits
+
+        if (sscanf(start, "%d.%d", &version.major, &version.minor) != 2) {
+            debugs(57, 7, "Invalid HTTP identifier.");
+            return false;
+        }
+    } else
+        return false;
+
+    if (!(start = strchr(start, ' ')))
+        return false;
+
+    // XXX: should we be using xstrtoui() or xatoui() ?
+    status_ = static_cast<Http::StatusCode>(atoi(++start));
+
+    // XXX check if the given 'reason' is the default status string, if not save to reason_
+
+    /* we ignore 'reason-phrase' */
+    /* Should assert start < end ? */
+    return true;                       /* success */
+}
similarity index 59%
rename from src/HttpStatusLine.h
rename to src/http/StatusLine.h
index f98586c771083e754cd28dc862f7126bfe7a7e4b..1cad667d9735be77e1b8d1c0ce41681cff3d3c56 100644 (file)
@@ -28,8 +28,8 @@
  *
  * Copyright (c) 2003, Robert Collins <robertc@squid-cache.org>
  */
-#ifndef SQUID_HTTPSTATUSLINE_H
-#define SQUID_HTTPSTATUSLINE_H
+#ifndef SQUID_HTTP_STATUSLINE_H
+#define SQUID_HTTP_STATUSLINE_H
 
 #include "http/ProtocolVersion.h"
 #include "http/StatusCode.h"
 class Packer;
 class String;
 
+namespace Http
+{
+
 /**
  * Holds the values parsed from an HTTP reply status line.
  *
- * For example: HTTP/1.1 200 Okay
+ * For example: HTTP/1.1 200 OK
  */
-class HttpStatusLine
+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);
+
+    /// retrieve the status code for this status line
+    const 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 */
 
@@ -53,27 +82,19 @@ public:
      * 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.
     AnyP::ProtocolType protocol;
 
-    Http::ProtocolVersion version;     ///< breakdown of protocol version labels: 0.9 1.0 1.1
-    Http::StatusCode status; ///< status code. ie 200 404
-    const char *reason;             ///< points to a _constant_ string (default or supplied), never free()d */
+    Http::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_;
 };
 
-/* init/clean */
-void httpStatusLineInit(HttpStatusLine * sline);
-void httpStatusLineClean(HttpStatusLine * sline);
-/* set/get values */
-void httpStatusLineSet(HttpStatusLine * sline, Http::ProtocolVersion version,
-                       Http::StatusCode status, const char *reason);
-const char *httpStatusLineReason(const HttpStatusLine * sline);
-/* parse/pack */
-/* parse a 0-terminating buffer and fill internal structires; returns true on success */
-int httpStatusLineParse(HttpStatusLine * sline, const String &protoPrefix,
-                        const char *start, const char *end);
-/* pack fields using Packer */
-void httpStatusLinePackInto(const HttpStatusLine * sline, Packer * p);
-
-const char *httpStatusString(Http::StatusCode status);
-
-#endif /* SQUID_HTTPSTATUSLINE_H */
+} // namespace Http
+
+#endif /* SQUID_HTTP_STATUSLINE_H */
index 1361437fb06ecf5896b2fbf29ecfa987b62f3dbf..504e5b023c909858d42090a3a046c791d2128841 100644 (file)
@@ -742,10 +742,10 @@ netdbExchangeHandleReply(void *data, StoreIOBuffer receivedData)
         if ((hdr_sz = headersEnd(p, ex->buf_ofs))) {
             debugs(38, 5, "netdbExchangeHandleReply: hdr_sz = " << hdr_sz);
             rep = ex->e->getReply();
-            assert (0 != rep->sline.status);
-            debugs(38, 3, "netdbExchangeHandleReply: reply status " << rep->sline.status);
+            assert(rep->sline.status() != Http::scNone);
+            debugs(38, 3, "netdbExchangeHandleReply: reply status " << rep->sline.status());
 
-            if (Http::scOkay != rep->sline.status) {
+            if (rep->sline.status() != Http::scOkay) {
                 netdbExchangeDone(ex);
                 return;
             }
index b4775bf9ca7a366ebfc9eba3a442b2b4a3fe939f..7ab4cb9c05633c821208c6f4336ad0e4892a274b 100644 (file)
@@ -531,7 +531,6 @@ headersLog(int cs, int pq, const HttpRequestMethod& method, void *data)
     HttpRequest *req;
     unsigned short magic = 0;
     unsigned char M = (unsigned char) m;
-    unsigned short S;
     char *hmask;
     int ccmask = 0;
 
@@ -566,10 +565,9 @@ headersLog(int cs, int pq, const HttpRequestMethod& method, void *data)
     magic = htons(magic);
     ccmask = htonl(ccmask);
 
+    unsigned short S = 0;
     if (0 == pq)
-        S = (unsigned short) rep->sline.status;
-    else
-        S = (unsigned short) Http::scNone;
+        S = static_cast<unsigned short>(rep->sline.status());
 
     logfileWrite(headerslog, &magic, sizeof(magic));
     logfileWrite(headerslog, &M, sizeof(M));
index 749bff28c82621cda0df8885b11547f789bb366f..a00e26f3ac2f803d7f1ccad6e4d99d0f0cdf5ad2 100644 (file)
@@ -546,11 +546,10 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size)
         return -1;
 
     if ((hdr_size = headersEnd(buf, size))) {
-        Http::StatusCode status;
         HttpReply const *reply = fetch->entry->getReply();
         assert(reply);
-        assert (reply->sline.status != 0);
-        status = reply->sline.status;
+        assert(reply->sline.status() != Http::scNone);
+        const Http::StatusCode status = reply->sline.status();
         debugs(72, 3, "peerDigestFetchReply: " << pd->host << " status: " << status <<
                ", expires: " << (long int) reply->expires << " (" << std::showpos <<
                (int) (reply->expires - squid_curtime) << ")");
@@ -598,7 +597,7 @@ peerDigestFetchReply(void *data, char *buf, ssize_t size)
             }
         } else {
             /* some kind of a bug */
-            peerDigestFetchAbort(fetch, buf, httpStatusLineReason(&reply->sline));
+            peerDigestFetchAbort(fetch, buf, reply->sline.reason());
             return -1;         /* XXX -1 will abort stuff in ReadReply! */
         }
 
@@ -638,11 +637,11 @@ peerDigestSwapInHeaders(void *data, char *buf, ssize_t size)
 
     if ((hdr_size = headersEnd(buf, size))) {
         assert(fetch->entry->getReply());
-        assert (fetch->entry->getReply()->sline.status != 0);
+        assert(fetch->entry->getReply()->sline.status() != Http::scNone);
 
-        if (fetch->entry->getReply()->sline.status != Http::scOkay) {
+        if (fetch->entry->getReply()->sline.status() != Http::scOkay) {
             debugs(72, DBG_IMPORTANT, "peerDigestSwapInHeaders: " << fetch->pd->host <<
-                   " status " << fetch->entry->getReply()->sline.status <<
+                   " status " << fetch->entry->getReply()->sline.status() <<
                    " got cached!");
 
             peerDigestFetchAbort(fetch, buf, "internal status error");
index 2df2322480dd2317e6ffe06485094081609103fa..bed4525af8cd5fae5b66e8c3f403ed1b89ed997c 100644 (file)
@@ -1402,10 +1402,10 @@ StoreEntry::validLength() const
         return 1;
     }
 
-    if (reply->sline.status == Http::scNotModified)
+    if (reply->sline.status() == Http::scNotModified)
         return 1;
 
-    if (reply->sline.status == Http::scNoContent)
+    if (reply->sline.status() == Http::scNoContent)
         return 1;
 
     diff = reply->hdr_sz + reply->content_length - objectLen();
index 56ce3c6d45140333212de2494841752de7bf94a3..3c6c4186f1500ff0539e1a810af699e635a40da7 100644 (file)
@@ -495,7 +495,7 @@ store_client::readBody(const char *buf, ssize_t len)
     assert(_callback.pending());
     debugs(90, 3, "storeClientReadBody: len " << len << "");
 
-    if (copyInto.offset == 0 && len > 0 && entry->getReply()->sline.status == 0) {
+    if (copyInto.offset == 0 && len > 0 && entry->getReply()->sline.status() == Http::scNone) {
         /* Our structure ! */
         HttpReply *rep = (HttpReply *) entry->getReply(); // bypass const
 
index 9464857f32fb808e9a7a32e2fdf8969eef76a9b8..c4b32217ae076c57836509fdef0213d547865bab 100644 (file)
@@ -93,7 +93,7 @@ storeLog(int tag, const StoreEntry * e)
                       e->swap_dirn,
                       e->swap_filen,
                       e->getMD5Text(),
-                      reply->sline.status,
+                      reply->sline.status(),
                       (int) reply->date,
                       (int) reply->last_modified,
                       (int) reply->expires,
index 21eff0fd7e0f6c5a36a2878744678b31149121b2..a361b8d64e8a93fb2041acc3f8eb9cedf54684b3 100644 (file)
@@ -16,7 +16,6 @@ HttpReply::HttpReply() : HttpMsg(hoReply), date (0), last_modified (0),
         bool HttpReply::sanityCheckStartLine(MemBuf *buf, const size_t hdr_len, Http::StatusCode *error) STUB_RETVAL(false)
         int HttpReply::httpMsgParseError() STUB_RETVAL(0)
         bool HttpReply::expectingBody(const HttpRequestMethod&, int64_t&) const STUB_RETVAL(false)
-        void HttpReply::packFirstLineInto(Packer * p, bool) const STUB
         bool HttpReply::parseFirstLine(const char *start, const char *end) STUB_RETVAL(false)
         void HttpReply::hdrCacheInit() STUB
         HttpReply * HttpReply::clone() const STUB_RETVAL(NULL)
index a85ccb8a7c04f053f7813ba2d9a0bef7925f741d..28dfa1e5a33f68ba090a6e4a6630565a1dcb5504 100644 (file)
@@ -372,9 +372,9 @@ urnHandleReply(void *data, StoreIOBuffer result)
     assert(urlres_e->getReply());
     rep = new HttpReply;
     rep->parseCharBuf(buf, k);
-    debugs(52, 3, "reply exists, code=" << rep->sline.status << ".");
+    debugs(52, 3, "reply exists, code=" << rep->sline.status() << ".");
 
-    if (rep->sline.status != Http::scOkay) {
+    if (rep->sline.status() != Http::scOkay) {
         debugs(52, 3, "urnHandleReply: failed.");
         err = new ErrorState(ERR_URN_RESOLVE, Http::scNotFound, urnState->request);
         err->url = xstrdup(e->url());