+/*
+ * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
+ *
+ * Squid software is distributed under GPLv2+ license and includes
+ * contributions from numerous individuals and organizations.
+ * Please see the COPYING and CONTRIBUTORS files for details.
+ */
+
#ifndef SQUID_HTTPHEADERTOOLS_H
#define SQUID_HTTPHEADERTOOLS_H
+#include "acl/forward.h"
#include "format/Format.h"
#include "HttpHeader.h"
-#include "typedefs.h"
+#include "sbuf/forward.h"
-#if HAVE_LIST
+#include <functional>
#include <list>
-#endif
-#if HAVE_MAP
#include <map>
-#endif
-#if HAVE_STRING
#include <string>
+#if HAVE_STRINGS_H
+#include <strings.h>
#endif
class HeaderWithAcl;
+class HttpHeader;
+class HttpRequest;
+class StoreEntry;
+
typedef std::list<HeaderWithAcl> HeaderWithAclList;
-class acl_access;
-struct _header_mangler {
+/* Distinguish between Request and Reply (for header mangling) */
+typedef enum {
+ ROR_REQUEST,
+ ROR_REPLY
+} req_or_rep_t;
+
+// Currently a POD
+class headerMangler
+{
+public:
acl_access *access_list;
char *replacement;
};
-typedef struct _header_mangler header_mangler;
-
-class StoreEntry;
-/// A collection of header_mangler objects for a given message kind.
+/// A collection of headerMangler objects for a given message kind.
class HeaderManglers
{
public:
~HeaderManglers();
/// returns a header mangler for field e or nil if none was specified
- const header_mangler *find(const HttpHeaderEntry &e) const;
+ const headerMangler *find(const HttpHeaderEntry &e) const;
/// returns a mangler for the named header (known or custom)
- header_mangler *track(const char *name);
+ headerMangler *track(const char *name);
/// updates mangler for the named header with a replacement value
void setReplacement(const char *name, const char *replacementValue);
void dumpReplacement(StoreEntry *entry, const char *optionName) const;
private:
+ /// Case-insensitive std::string "less than" comparison functor.
+ /// Fast version recommended by Meyers' "Effective STL" for ASCII c-strings.
+ class NoCaseLessThan: public std::binary_function<std::string, std::string, bool>
+ {
+ public:
+ bool operator()(const std::string &lhs, const std::string &rhs) const {
+ return strcasecmp(lhs.c_str(), rhs.c_str()) < 0;
+ }
+ };
+
/// a name:mangler map; optimize: use unordered map or some such
- typedef std::map<std::string, header_mangler> ManglersByName;
+ typedef std::map<std::string, headerMangler, NoCaseLessThan> ManglersByName;
/// one mangler for each known header
- header_mangler known[HDR_ENUM_END];
+ headerMangler known[static_cast<int>(Http::HdrType::enumEnd_)];
/// one mangler for each custom header
ManglersByName custom;
/// configured if some mangling ACL applies to all header names
- header_mangler all;
+ headerMangler all;
private:
/* not implemented */
HeaderManglers &operator =(const HeaderManglers &);
};
-class ACLList;
class HeaderWithAcl
{
public:
- HeaderWithAcl() : aclList(NULL), fieldId (HDR_BAD_HDR), quoted(false) {}
+ HeaderWithAcl() : aclList(NULL), valueFormat(NULL), fieldId(Http::HdrType::BAD_HDR), quoted(false) {}
/// HTTP header field name
std::string fieldName;
Format::Format *valueFormat;
/// internal ID for "known" headers or HDR_OTHER
- http_hdr_type fieldId;
+ Http::HdrType fieldId;
/// whether fieldValue may contain macros
bool quoted;
};
-extern int httpHeaderParseOffset(const char *start, int64_t * off);
+/// A strtoll(10) wrapper that checks for strtoll() failures and other problems.
+/// XXX: This function is not fully compatible with some HTTP syntax rules.
+/// Just like strtoll(), allows whitespace prefix, a sign, and _any_ suffix.
+/// Requires at least one digit to be present.
+/// Sets "off" and "end" arguments if and only if no problems were found.
+/// \return true if and only if no problems were found.
+bool httpHeaderParseOffset(const char *start, int64_t *offPtr, char **endPtr = nullptr);
-class HttpHeaderFieldInfo;
-class String;
-class HttpHeader;
-class HttpRequest;
+bool httpHeaderHasConnDir(const HttpHeader * hdr, const SBuf &directive);
+int httpHeaderParseInt(const char *start, int *val);
+void httpHeaderPutStrf(HttpHeader * hdr, Http::HdrType id, const char *fmt,...) PRINTF_FORMAT_ARG3;
-extern HttpHeaderFieldInfo *httpHeaderBuildFieldsInfo(const HttpHeaderFieldAttrs * attrs, int count);
-extern void httpHeaderDestroyFieldsInfo(HttpHeaderFieldInfo * info, int count);
-extern http_hdr_type httpHeaderIdByName(const char *name, size_t name_len, const HttpHeaderFieldInfo * attrs, int end);
-extern http_hdr_type httpHeaderIdByNameDef(const char *name, int name_len);
-extern const char *httpHeaderNameById(int id);
-extern int httpHeaderHasConnDir(const HttpHeader * hdr, const char *directive);
-extern int httpHeaderParseInt(const char *start, int *val);
-extern void httpHeaderPutStrf(HttpHeader * hdr, http_hdr_type id, const char *fmt,...) PRINTF_FORMAT_ARG3;
+const char *getStringPrefix(const char *str, size_t len);
-extern const char *getStringPrefix(const char *str, const char *end);
-
-extern void httpHdrMangleList(HttpHeader *, HttpRequest *, int req_or_rep);
+void httpHdrMangleList(HttpHeader *, HttpRequest *, const AccessLogEntryPointer &al, req_or_rep_t req_or_rep);
#endif
+