]> git.ipfire.org Git - thirdparty/squid.git/blobdiff - src/mime.cc
transaction_initiator ACL for detecting various unusual transactions
[thirdparty/squid.git] / src / mime.cc
index eac260b5c0b3c130bfe2dfcc525d39b46088531b..063513dcbae89af4cf5be5b66ba74a3c667567dc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1996-2015 The Squid Software Foundation and contributors
+ * Copyright (C) 1996-2017 The Squid Software Foundation and contributors
  *
  * Squid software is distributed under GPLv2+ license and includes
  * contributions from numerous individuals and organizations.
@@ -9,9 +9,8 @@
 /* DEBUG: section 25    MIME Parsing and Internal Icons */
 
 #include "squid.h"
-#include "base/RegexPattern.h"
-#include "disk.h"
 #include "fde.h"
+#include "fs_io.h"
 #include "globals.h"
 #include "HttpHdrCc.h"
 #include "HttpReply.h"
@@ -25,6 +24,8 @@
 #include "Store.h"
 #include "StoreClient.h"
 
+#include <array>
+
 #if HAVE_SYS_STAT_H
 #include <sys/stat.h>
 #endif
@@ -57,16 +58,15 @@ class MimeEntry
     MEMPROXY_CLASS(MimeEntry);
 
 public:
-    MimeEntry(const char *aPattern, const decltype(RegexPattern::flags) &reFlags,
+    explicit MimeEntry(const char *aPattern, const regex_t &compiledPattern,
                        const char *aContentType,
                        const char *aContentEncoding, const char *aTransferMode,
                        bool optionViewEnable, bool optionDownloadEnable,
                        const char *anIconName);
-    MimeEntry(const MimeEntry &) = delete;
-    MimeEntry(const MimeEntry &&) = delete;
     ~MimeEntry();
 
-    RegexPattern pattern;
+    const char *pattern;
+    regex_t compiled_pattern;
     const char *content_type;
     const char *content_encoding;
     char transfer_mode;
@@ -90,7 +90,7 @@ mimeGetEntry(const char *fn, int skip_encodings)
         t = NULL;
 
         for (m = MimeTable; m; m = m->next) {
-            if (m->pattern.match(name))
+            if (regexec(&m->compiled_pattern, name, 0, 0, 0) == 0)
                 break;
         }
 
@@ -118,9 +118,9 @@ mimeGetEntry(const char *fn, int skip_encodings)
 }
 
 MimeIcon::MimeIcon(const char *aName) :
-    icon_(aName)
+    url_(nullptr)
 {
-    url_ = xstrdup(internalLocalUri("/squid-internal-static/icons/", icon_));
+    setName(aName);
 }
 
 MimeIcon::~MimeIcon()
@@ -233,6 +233,7 @@ mimeInit(char *filename)
     char buf[BUFSIZ];
     char chopbuf[BUFSIZ];
     char *t;
+    char *pattern;
     char *icon;
     char *type;
     char *encoding;
@@ -240,13 +241,16 @@ mimeInit(char *filename)
     char *option;
     int view_option;
     int download_option;
+    regex_t re;
     MimeEntry *m;
+    int re_flags = REG_EXTENDED | REG_NOSUB | REG_ICASE;
 
     if (filename == NULL)
         return;
 
     if ((fp = fopen(filename, "r")) == NULL) {
-        debugs(25, DBG_IMPORTANT, "mimeInit: " << filename << ": " << xstrerror());
+        int xerrno = errno;
+        debugs(25, DBG_IMPORTANT, "mimeInit: " << filename << ": " << xstrerr(xerrno));
         return;
     }
 
@@ -256,8 +260,6 @@ mimeInit(char *filename)
 
     mimeFreeMemory();
 
-    const auto re_flags = std::regex::extended | std::regex::nosubs | std::regex::icase;
-
     while (fgets(buf, BUFSIZ, fp)) {
         if ((t = strchr(buf, '#')))
             *t = '\0';
@@ -273,7 +275,6 @@ mimeInit(char *filename)
 
         xstrncpy(chopbuf, buf, BUFSIZ);
 
-        char *pattern;
         if ((pattern = strtok(chopbuf, w_space)) == NULL) {
             debugs(25, DBG_IMPORTANT, "mimeInit: parse error: '" << buf << "'");
             continue;
@@ -311,14 +312,14 @@ mimeInit(char *filename)
                 debugs(25, DBG_IMPORTANT, "mimeInit: unknown option: '" << buf << "' (" << option << ")");
         }
 
-        try {
-            m = new MimeEntry(pattern, re_flags, type, encoding, mode, view_option, download_option, icon);
-
-        } catch (std::regex_error &e) {
-            debugs(25, DBG_IMPORTANT, "mimeInit: invalid regular expression: '" << buf << "'");
+        if (regcomp(&re, pattern, re_flags) != 0) {
+            debugs(25, DBG_IMPORTANT, "mimeInit: regcomp error: '" << buf << "'");
             continue;
         }
 
+        m = new MimeEntry(pattern,re,type,encoding,mode,view_option,
+                          download_option,icon);
+
         *MimeTableTail = m;
 
         MimeTableTail = &m->next;
@@ -401,15 +402,15 @@ MimeIcon::created(StoreEntry *newEntry)
     EBIT_SET(e->flags, ENTRY_SPECIAL);
     e->setPublicKey();
     e->buffer();
-    HttpRequest *r = HttpRequest::CreateFromUrl(url_);
 
-    if (NULL == r)
+    const MasterXaction::Pointer mx = new MasterXaction(XactionInitiator::initIcon);
+    HttpRequestPointer r(HttpRequest::FromUrl(url_, mx));
+    if (!r)
         fatalf("mimeLoadIcon: cannot parse internal URL: %s", url_);
 
     e->mem_obj->request = r;
-    HTTPMSGLOCK(e->mem_obj->request);
 
-    HttpReply *reply = new HttpReply;
+    HttpReplyPointer reply(new HttpReply);
 
     if (status == Http::scNoContent)
         reply->setHeaders(status, NULL, NULL, 0, -1, -1);
@@ -418,17 +419,16 @@ MimeIcon::created(StoreEntry *newEntry)
     reply->cache_control = new HttpHdrCc();
     reply->cache_control->maxAge(86400);
     reply->header.putCc(reply->cache_control);
-    e->replaceHttpReply(reply);
+    e->replaceHttpReply(reply.getRaw());
 
     if (status == Http::scOkay) {
         /* read the file into the buffer and append it to store */
         int n;
-        char *buf = (char *)memAllocate(MEM_4K_BUF);
-        while ((n = FD_READ_METHOD(fd, buf, sizeof(*buf))) > 0)
-            e->append(buf, n);
+        std::array<char, 4096> buf;
+        while ((n = FD_READ_METHOD(fd, buf.data(), buf.size())) > 0)
+            e->append(buf.data(), n);
 
         file_close(fd);
-        memFree(buf, MEM_4K_BUF);
     }
 
     e->flush();
@@ -440,21 +440,23 @@ MimeIcon::created(StoreEntry *newEntry)
 
 MimeEntry::~MimeEntry()
 {
+    xfree(pattern);
     xfree(content_type);
     xfree(content_encoding);
+    regfree(&compiled_pattern);
 }
 
-MimeEntry::MimeEntry(const char *aPattern, const decltype(RegexPattern::flags) &reFlags,
+MimeEntry::MimeEntry(const char *aPattern, const regex_t &compiledPattern,
                      const char *aContentType, const char *aContentEncoding,
                      const char *aTransferMode, bool optionViewEnable,
                      bool optionDownloadEnable, const char *anIconName) :
-    pattern(reFlags, aPattern),
+    pattern(xstrdup(aPattern)),
+    compiled_pattern(compiledPattern),
     content_type(xstrdup(aContentType)),
     content_encoding(xstrdup(aContentEncoding)),
     view_option(optionViewEnable),
     download_option(optionDownloadEnable),
-    theIcon(anIconName),
-    next(nullptr)
+    theIcon(anIconName), next(NULL)
 {
     if (!strcasecmp(aTransferMode, "ascii"))
         transfer_mode = 'A';