]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/HttpHeader.h
Docs: Copyright updates for 2018 (#114)
[thirdparty/squid.git] / src / HttpHeader.h
index 5ac12e3e7fd27fdbf6f2a1bc5e94ae74175a516a..64b0651c5ff6e31e13f80380c937f9d2bcc76e08 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2018 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -9,10 +9,13 @@
 #ifndef SQUID_HTTPHEADER_H
 #define SQUID_HTTPHEADER_H
 
+#include "anyp/ProtocolVersion.h"
+#include "base/LookupTable.h"
 #include "http/RegisteredHeaders.h"
 /* because we pass a spec by value */
 #include "HttpHeaderMask.h"
 #include "mem/forward.h"
+#include "sbuf/forward.h"
 #include "SquidString.h"
 
 #include <vector>
@@ -23,8 +26,6 @@ class HttpHdrContRange;
 class HttpHdrRange;
 class HttpHdrSc;
 class Packable;
-class StoreEntry;
-class SBuf;
 
 /** Possible owners of http header */
 typedef enum {
@@ -40,23 +41,6 @@ typedef enum {
     hoEnd
 } http_hdr_owner_type;
 
-class HttpHeaderFieldAttrs
-{
-public:
-    HttpHeaderFieldAttrs() : name(NULL), id(HDR_BAD_HDR), type(field_type::ftInvalid) {}
-    HttpHeaderFieldAttrs(const char *aName, http_hdr_type anId, field_type aType = field_type::ftInvalid) : name(aName), id(anId), type(aType) {}
-#if __cplusplus >= 201103L
-    HttpHeaderFieldAttrs(const HttpHeaderFieldAttrs &) = default;
-    HttpHeaderFieldAttrs(HttpHeaderFieldAttrs &&) = default;
-#endif
-    // nothing to do as name is a pointer to global const string
-    ~HttpHeaderFieldAttrs() {}
-
-    const char *name;
-    http_hdr_type id;
-    field_type type;
-};
-
 /** Iteration for headers; use HttpHeaderPos as opaque type, do not interpret */
 typedef ssize_t HttpHeaderPos;
 
@@ -68,7 +52,7 @@ class HttpHeaderEntry
     MEMPROXY_CLASS(HttpHeaderEntry);
 
 public:
-    HttpHeaderEntry(http_hdr_type id, const char *name, const char *value);
+    HttpHeaderEntry(Http::HdrType id, const SBuf &name, const char *value);
     ~HttpHeaderEntry();
     static HttpHeaderEntry *parse(const char *field_start, const char *field_end);
     HttpHeaderEntry *clone() const;
@@ -76,8 +60,8 @@ public:
     int getInt() const;
     int64_t getInt64() const;
 
-    http_hdr_type id;
-    String name;
+    Http::HdrType id;
+    SBuf name;
     String value;
 };
 
@@ -98,33 +82,52 @@ public:
     /* Interface functions */
     void clean();
     void append(const HttpHeader * src);
-    void update (HttpHeader const *fresh, HttpHeaderMask const *denied_mask);
+    bool update(HttpHeader const *fresh);
     void compact();
-    int reset();
     int parse(const char *header_start, size_t len);
+    /// Parses headers stored in a buffer.
+    /// \returns 1 and sets hdr_sz on success
+    /// \returns 0 when needs more data
+    /// \returns -1 on error
+    int parse(const char *buf, size_t buf_len, bool atEnd, size_t &hdr_sz);
     void packInto(Packable * p, bool mask_sensitive_info=false) const;
     HttpHeaderEntry *getEntry(HttpHeaderPos * pos) const;
-    HttpHeaderEntry *findEntry(http_hdr_type id) const;
-    int delByName(const char *name);
-    int delById(http_hdr_type id);
+    HttpHeaderEntry *findEntry(Http::HdrType id) const;
+    /// deletes all fields with a given name, if any.
+    /// \return #fields deleted
+    int delByName(const SBuf &name);
+    /// \deprecated use SBuf method instead. performance regression: reallocates
+    int delByName(const char *name) { return delByName(SBuf(name)); }
+    int delById(Http::HdrType id);
     void delAt(HttpHeaderPos pos, int &headers_deleted);
     void refreshMask();
     void addEntry(HttpHeaderEntry * e);
     void insertEntry(HttpHeaderEntry * e);
-    String getList(http_hdr_type id) const;
-    bool getList(http_hdr_type id, String *s) const;
-    String getStrOrList(http_hdr_type id) const;
+    String getList(Http::HdrType id) const;
+    bool getList(Http::HdrType id, String *s) const;
+    bool conflictingContentLength() const { return conflictingContentLength_; }
+    String getStrOrList(Http::HdrType id) const;
+    String getByName(const SBuf &name) const;
     String getByName(const char *name) const;
-    /// sets value and returns true iff a [possibly empty] named field is there
-    bool getByNameIfPresent(const char *name, String &value) const;
+    String getById(Http::HdrType id) const;
+    /// returns true iff a [possibly empty] field identified by id is there
+    /// when returning true, also sets the `result` parameter (if it is not nil)
+    bool getByIdIfPresent(Http::HdrType id, String *result) const;
+    /// returns true iff a [possibly empty] named field is there
+    /// when returning true, also sets the `value` parameter (if it is not nil)
+    bool hasNamed(const SBuf &s, String *value = 0) const;
+    /// \deprecated use SBuf method instead.
+    bool hasNamed(const char *name, unsigned int namelen, String *value = 0) const;
     String getByNameListMember(const char *name, const char *member, const char separator) const;
-    String getListMember(http_hdr_type id, const char *member, const char separator) const;
-    int has(http_hdr_type id) const;
-    void putInt(http_hdr_type id, int number);
-    void putInt64(http_hdr_type id, int64_t number);
-    void putTime(http_hdr_type id, time_t htime);
-    void insertTime(http_hdr_type id, time_t htime);
-    void putStr(http_hdr_type id, const char *str);
+    String getListMember(Http::HdrType id, const char *member, const char separator) const;
+    int has(Http::HdrType id) const;
+    /// Appends "this cache" information to VIA header field.
+    /// Takes the initial VIA value from "from" parameter, if provided.
+    void addVia(const AnyP::ProtocolVersion &ver, const HttpHeader *from = 0);
+    void putInt(Http::HdrType id, int number);
+    void putInt64(Http::HdrType id, int64_t number);
+    void putTime(Http::HdrType id, time_t htime);
+    void putStr(Http::HdrType id, const char *str);
     void putAuth(const char *auth_scheme, const char *realm);
     void putCc(const HttpHdrCc * cc);
     void putContRange(const HttpHdrContRange * cr);
@@ -132,19 +135,19 @@ public:
     void putSc(HttpHdrSc *sc);
     void putWarning(const int code, const char *const text); ///< add a Warning header
     void putExt(const char *name, const char *value);
-    int getInt(http_hdr_type id) const;
-    int64_t getInt64(http_hdr_type id) const;
-    time_t getTime(http_hdr_type id) const;
-    const char *getStr(http_hdr_type id) const;
-    const char *getLastStr(http_hdr_type id) const;
+    int getInt(Http::HdrType id) const;
+    int64_t getInt64(Http::HdrType id) const;
+    time_t getTime(Http::HdrType id) const;
+    const char *getStr(Http::HdrType id) const;
+    const char *getLastStr(Http::HdrType id) const;
     HttpHdrCc *getCc() const;
     HttpHdrRange *getRange() const;
     HttpHdrSc *getSc() const;
     HttpHdrContRange *getContRange() const;
-    const char *getAuth(http_hdr_type id, const char *auth_scheme) const;
-    ETag getETag(http_hdr_type id) const;
-    TimeOrTag getTimeOrTag(http_hdr_type id) const;
-    int hasListMember(http_hdr_type id, const char *member, const char separator) const;
+    const char *getAuth(Http::HdrType id, const char *auth_scheme) const;
+    ETag getETag(Http::HdrType id) const;
+    TimeOrTag getTimeOrTag(Http::HdrType id) const;
+    int hasListMember(Http::HdrType id, const char *member, const char separator) const;
     int hasByNameListMember(const char *name, const char *member, const char separator) const;
     void removeHopByHopEntries();
     inline bool chunked() const; ///< whether message uses chunked Transfer-Encoding
@@ -158,9 +161,20 @@ public:
 protected:
     /** \deprecated Public access replaced by removeHopByHopEntries() */
     void removeConnectionHeaderEntries();
+    /// either finds the end of headers or returns false
+    /// If the end was found:
+    /// *parse_start points to the first character after the header delimiter
+    /// *blk_start points to the first header character (i.e. old parse_start value)
+    /// *blk_end points to the first header delimiter character (CR or LF in CR?LF).
+    /// If block starts where it ends, then there are no fields in the header.
+    static bool Isolate(const char **parse_start, size_t l, const char **blk_start, const char **blk_end);
+    bool needUpdate(const HttpHeader *fresh) const;
+    bool skipUpdateHeader(const Http::HdrType id) const;
+    void updateWarnings();
 
 private:
-    HttpHeaderEntry *findLastEntry(http_hdr_type id) const;
+    HttpHeaderEntry *findLastEntry(Http::HdrType id) const;
+    bool conflictingContentLength_; ///< found different Content-Length fields
 };
 
 int httpHeaderParseQuotedString(const char *start, const int len, String *val);
@@ -168,19 +182,16 @@ int httpHeaderParseQuotedString(const char *start, const int len, String *val);
 /// quotes string using RFC 7230 quoted-string rules
 SBuf httpHeaderQuoteString(const char *raw);
 
-int httpHeaderHasByNameListMember(const HttpHeader * hdr, const char *name, const char *member, const char separator);
-void httpHeaderUpdate(HttpHeader * old, const HttpHeader * fresh, const HttpHeaderMask * denied_mask);
-void httpHeaderCalcMask(HttpHeaderMask * mask, http_hdr_type http_hdr_type_enums[], size_t count);
+void httpHeaderCalcMask(HttpHeaderMask * mask, Http::HdrType http_hdr_type_enums[], size_t count);
 
 inline bool
 HttpHeader::chunked() const
 {
-    return has(HDR_TRANSFER_ENCODING) &&
-           hasListMember(HDR_TRANSFER_ENCODING, "chunked", ',');
+    return has(Http::HdrType::TRANSFER_ENCODING) &&
+           hasListMember(Http::HdrType::TRANSFER_ENCODING, "chunked", ',');
 }
 
 void httpHeaderInitModule(void);
-void httpHeaderCleanModule(void);
 
 #endif /* SQUID_HTTPHEADER_H */