1 /*
2  * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
3  *
4  * Squid software is distributed under GPLv2+ license and includes
5  * contributions from numerous individuals and organizations.
6  * Please see the COPYING and CONTRIBUTORS files for details.
7  */
8 
9 #ifndef SQUID_HTTPREQUESTMETHOD_H
10 #define SQUID_HTTPREQUESTMETHOD_H
11 
12 #include "http/forward.h"
13 #include "http/MethodType.h"
14 #include "sbuf/SBuf.h"
15 
16 class SquidConfig;
17 
18 #include <iosfwd>
19 
20 /**
21  * This class represents an HTTP Request METHOD
22  * - i.e. PUT, POST, GET etc.
23  * It has a runtime extension facility to allow it to
24  * efficiently support new methods
25  */
26 class HttpRequestMethod : public RefCountable
27 {
28 public:
HttpRequestMethod()29     HttpRequestMethod() : theMethod(Http::METHOD_NONE), theImage() {}
HttpRequestMethod(Http::MethodType const aMethod)30     HttpRequestMethod(Http::MethodType const aMethod) : theMethod(aMethod), theImage() {}
31     explicit HttpRequestMethod(const SBuf &);
32 
33     void HttpRequestMethodXXX(char const *); // deprecated old c-string to SBuf converter.
34 
35     HttpRequestMethod & operator = (const HttpRequestMethod& aMethod) {
36         theMethod = aMethod.theMethod;
37         theImage = aMethod.theImage;
38         return *this;
39     }
40 
41     HttpRequestMethod & operator = (Http::MethodType const aMethod) {
42         theMethod = aMethod;
43         theImage.clear();
44         return *this;
45     }
46 
47     bool operator == (Http::MethodType const & aMethod) const { return theMethod == aMethod; }
48     bool operator == (HttpRequestMethod const & aMethod) const {
49         return theMethod == aMethod.theMethod &&
50                (theMethod != Http::METHOD_OTHER || theImage == aMethod.theImage);
51     }
52 
53     bool operator != (Http::MethodType const & aMethod) const { return theMethod != aMethod; }
54     bool operator != (HttpRequestMethod const & aMethod) const {
55         return !operator==(aMethod);
56     }
57 
58     /** Iterate through all HTTP method IDs. */
59     HttpRequestMethod& operator++() {
60         // TODO: when this operator is used in more than one place,
61         // replace it with HttpRequestMethods::Iterator API
62         // XXX: this interface can create Http::METHOD_OTHER without an image
63         assert(theMethod < Http::METHOD_ENUM_END);
64         theMethod = (Http::MethodType)(1 + (int)theMethod);
65         return *this;
66     }
67 
68     /** Get an ID representation of the method.
69      * \retval Http::METHOD_NONE   the method is unset
70      * \retval Http::METHOD_OTHER  the method is not recognized and has no unique ID
71      * \retval *                   the method is on of the recognized HTTP methods.
72      */
id()73     Http::MethodType id() const { return theMethod; }
74 
75     /** Get a string representation of the method. */
76     const SBuf &image() const;
77 
78     /// Whether this method is defined as a "safe" in HTTP/1.1
79     /// see RFC 2616 section 9.1.1
80     bool isHttpSafe() const;
81 
82     /// Whether this method is defined as "idempotent" in HTTP/1.1
83     /// see RFC 2616 section 9.1.2
84     bool isIdempotent() const;
85 
86     /** Whether responses to this method MAY be cached.
87      * \retval false  Not cacheable.
88      * \retval true   Possibly cacheable. Other details will determine.
89      */
90     bool respMaybeCacheable() const;
91 
92     /** Whether this method SHOULD (or MUST) invalidate existing cached entries.
93      * Invalidation is always determined by the response
94      *
95      * RFC 2616 defines invalidate as either immediate purge
96      * or delayed explicit revalidate all stored copies on next use.
97      *
98      * \retval true   SHOULD invalidate. Response details can raise this to a MUST.
99      * \retval false  Other details will determine. Method is not a factor.
100      */
101     bool shouldInvalidate() const;
102 
103     /* Whether this method invalidates existing cached entries.
104      * Kept for backward-compatibility. This is the old 2.x-3.2 invalidation behaviour.
105      *
106      * NOTE:
107      *    purgesOthers differs from shouldInvalidate() in that purgesOthers() returns
108      *    true on any methods the MAY invalidate (Squid opts to do so).
109      *    shouldInvalidate() only returns true on methods which SHOULD invalidate.
110      */
111     bool purgesOthers() const;
112 
113 private:
114     Http::MethodType theMethod; ///< Method type
115     SBuf theImage;     ///< Used for storing the Http::METHOD_OTHER only. A copy of the parsed method text.
116 };
117 
118 inline std::ostream &
119 operator << (std::ostream &os, HttpRequestMethod const &method)
120 {
121     os << method.image();
122     return os;
123 }
124 
125 #endif /* SQUID_HTTPREQUESTMETHOD_H */
126 
127