diff --git a/.gitignore b/.gitignore
index da80573..4d9a0ed 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1 @@
-SOURCES/squid-4.11.tar.xz
+SOURCES/squid-4.15.tar.xz
diff --git a/.squid.metadata b/.squid.metadata
index 94d7ed2..30ac1f5 100644
--- a/.squid.metadata
+++ b/.squid.metadata
@@ -1 +1 @@
-053277bf5497163ffc9261b9807abda5959bb6fc SOURCES/squid-4.11.tar.xz
+60bda34ba39657e2d870c8c1d2acece8a69c3075 SOURCES/squid-4.15.tar.xz
diff --git a/SOURCES/squid-4.11-CVE-2020-14058.patch b/SOURCES/squid-4.11-CVE-2020-14058.patch
deleted file mode 100644
index 1567477..0000000
--- a/SOURCES/squid-4.11-CVE-2020-14058.patch
+++ /dev/null
@@ -1,295 +0,0 @@
-commit 93f5fda134a2a010b84ffedbe833d670e63ba4be
-Author: Christos Tsantilas <christos@chtsanti.net>
-Date:   2020-05-15 04:54:54 +0000
-
-    Fix sending of unknown validation errors to cert. validator (#633)
-    
-    Squid may be compiled with an OpenSSL release introducing X509
-    validation errors that Squid does not have the names for. Send their
-    integer codes.
-    
-    Also sync Squid certificate verification errors with OpenSSL v1.1.1g.
-    
-    This is a Measurement Factory project.
-
-diff --git a/src/format/Format.cc b/src/format/Format.cc
-index 8c5574b..4b4ad42 100644
---- a/src/format/Format.cc
-+++ b/src/format/Format.cc
-@@ -322,15 +322,6 @@ log_quoted_string(const char *str, char *out)
-     *p = '\0';
- }
- 
--#if USE_OPENSSL
--static char *
--sslErrorName(Security::ErrorCode err, char *buf, size_t size)
--{
--    snprintf(buf, size, "SSL_ERR=%d", err);
--    return buf;
--}
--#endif
--
- /// XXX: Misnamed. TODO: Split <h (and this function) to distinguish received
- /// headers from sent headers rather than failing to distinguish requests from responses.
- /// \retval HttpReply sent to the HTTP client (access.log and default context).
-@@ -959,9 +950,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
-         case LFT_SQUID_ERROR_DETAIL:
- #if USE_OPENSSL
-             if (al->request && al->request->errType == ERR_SECURE_CONNECT_FAIL) {
--                out = Ssl::GetErrorName(al->request->errDetail);
--                if (!out)
--                    out = sslErrorName(al->request->errDetail, tmp, sizeof(tmp));
-+                out = Ssl::GetErrorName(al->request->errDetail, true);
-             } else
- #endif
-                 if (al->request && al->request->errDetail != ERR_DETAIL_NONE) {
-@@ -1263,10 +1252,7 @@ Format::Format::assemble(MemBuf &mb, const AccessLogEntry::Pointer &al, int logS
-                     for (const Security::CertErrors *sslError = srvBump->sslErrors(); sslError; sslError = sslError->next) {
-                         if (!sb.isEmpty())
-                             sb.append(separator);
--                        if (const char *errorName = Ssl::GetErrorName(sslError->element.code))
--                            sb.append(errorName);
--                        else
--                            sb.append(sslErrorName(sslError->element.code, tmp, sizeof(tmp)));
-+                        sb.append(Ssl::GetErrorName(sslError->element.code, true));
-                         if (sslError->element.depth >= 0)
-                             sb.appendf("@depth=%d", sslError->element.depth);
-                     }
-diff --git a/src/ssl/ErrorDetail.cc b/src/ssl/ErrorDetail.cc
-index ddd61fd..00eb0e2 100644
---- a/src/ssl/ErrorDetail.cc
-+++ b/src/ssl/ErrorDetail.cc
-@@ -233,6 +233,9 @@ static SslErrorEntry TheSslErrorArray[] = {
-         "X509_V_ERR_SUBTREE_MINMAX"
-     },
- #endif
-+    {   X509_V_ERR_APPLICATION_VERIFICATION, //50
-+        "X509_V_ERR_APPLICATION_VERIFICATION"
-+    },
- #if defined(X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE)
-     {
-         X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE, //51
-@@ -257,9 +260,132 @@ static SslErrorEntry TheSslErrorArray[] = {
-         "X509_V_ERR_CRL_PATH_VALIDATION_ERROR"
-     },
- #endif
--    {   X509_V_ERR_APPLICATION_VERIFICATION,
--        "X509_V_ERR_APPLICATION_VERIFICATION"
-+#if defined(X509_V_ERR_PATH_LOOP)
-+    {
-+        X509_V_ERR_PATH_LOOP, //55
-+        "X509_V_ERR_PATH_LOOP"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_INVALID_VERSION)
-+    {
-+        X509_V_ERR_SUITE_B_INVALID_VERSION, //56
-+        "X509_V_ERR_SUITE_B_INVALID_VERSION"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_INVALID_ALGORITHM)
-+    {
-+        X509_V_ERR_SUITE_B_INVALID_ALGORITHM, //57
-+        "X509_V_ERR_SUITE_B_INVALID_ALGORITHM"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_INVALID_CURVE)
-+    {
-+        X509_V_ERR_SUITE_B_INVALID_CURVE, //58
-+        "X509_V_ERR_SUITE_B_INVALID_CURVE"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM)
-+    {
-+        X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM, //59
-+        "X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED)
-+    {
-+        X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED, //60
-+        "X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED"
-+    },
-+#endif
-+#if defined(X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256)
-+    {
-+        X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256, //61
-+        "X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256"
-+    },
-+#endif
-+#if defined(X509_V_ERR_HOSTNAME_MISMATCH)
-+    {
-+        X509_V_ERR_HOSTNAME_MISMATCH, //62
-+        "X509_V_ERR_HOSTNAME_MISMATCH"
-+    },
-+#endif
-+#if defined(X509_V_ERR_EMAIL_MISMATCH)
-+    {
-+        X509_V_ERR_EMAIL_MISMATCH, //63
-+        "X509_V_ERR_EMAIL_MISMATCH"
-+    },
-+#endif
-+#if defined(X509_V_ERR_IP_ADDRESS_MISMATCH)
-+    {
-+        X509_V_ERR_IP_ADDRESS_MISMATCH, //64
-+        "X509_V_ERR_IP_ADDRESS_MISMATCH"
-+    },
-+#endif
-+#if defined(X509_V_ERR_DANE_NO_MATCH)
-+    {
-+        X509_V_ERR_DANE_NO_MATCH, //65
-+        "X509_V_ERR_DANE_NO_MATCH"
-     },
-+#endif
-+#if defined(X509_V_ERR_EE_KEY_TOO_SMALL)
-+    {
-+        X509_V_ERR_EE_KEY_TOO_SMALL, //66
-+        "X509_V_ERR_EE_KEY_TOO_SMALL"
-+    },
-+#endif
-+#if defined(X509_V_ERR_CA_KEY_TOO_SMALL)
-+    {
-+        X509_V_ERR_CA_KEY_TOO_SMALL, //67
-+        "X509_V_ERR_CA_KEY_TOO_SMALL"
-+    },
-+#endif
-+#if defined(X509_V_ERR_CA_MD_TOO_WEAK)
-+    {
-+        X509_V_ERR_CA_MD_TOO_WEAK, //68
-+        "X509_V_ERR_CA_MD_TOO_WEAK"
-+    },
-+#endif
-+#if defined(X509_V_ERR_INVALID_CALL)
-+    {
-+        X509_V_ERR_INVALID_CALL, //69
-+        "X509_V_ERR_INVALID_CALL"
-+    },
-+#endif
-+#if defined(X509_V_ERR_STORE_LOOKUP)
-+    {
-+        X509_V_ERR_STORE_LOOKUP, //70
-+        "X509_V_ERR_STORE_LOOKUP"
-+    },
-+#endif
-+#if defined(X509_V_ERR_NO_VALID_SCTS)
-+    {
-+        X509_V_ERR_NO_VALID_SCTS, //71
-+        "X509_V_ERR_NO_VALID_SCTS"
-+    },
-+#endif
-+#if defined(X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION)
-+    {
-+        X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION, //72
-+        "X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION"
-+    },
-+#endif
-+#if defined(X509_V_ERR_OCSP_VERIFY_NEEDED)
-+    {
-+        X509_V_ERR_OCSP_VERIFY_NEEDED, //73
-+        "X509_V_ERR_OCSP_VERIFY_NEEDED"
-+    },
-+#endif
-+#if defined(X509_V_ERR_OCSP_VERIFY_FAILED)
-+    {
-+        X509_V_ERR_OCSP_VERIFY_FAILED, //74
-+        "X509_V_ERR_OCSP_VERIFY_FAILED"
-+    },
-+#endif
-+#if defined(X509_V_ERR_OCSP_CERT_UNKNOWN)
-+    {
-+        X509_V_ERR_OCSP_CERT_UNKNOWN, //75
-+        "X509_V_ERR_OCSP_CERT_UNKNOWN"
-+    },
-+#endif
-     { SSL_ERROR_NONE, "SSL_ERROR_NONE"},
-     {SSL_ERROR_NONE, NULL}
- };
-@@ -286,6 +412,27 @@ static const char *OptionalSslErrors[] = {
-     "X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX",
-     "X509_V_ERR_UNSUPPORTED_NAME_SYNTAX",
-     "X509_V_ERR_CRL_PATH_VALIDATION_ERROR",
-+    "X509_V_ERR_PATH_LOOP",
-+    "X509_V_ERR_SUITE_B_INVALID_VERSION",
-+    "X509_V_ERR_SUITE_B_INVALID_ALGORITHM",
-+    "X509_V_ERR_SUITE_B_INVALID_CURVE",
-+    "X509_V_ERR_SUITE_B_INVALID_SIGNATURE_ALGORITHM",
-+    "X509_V_ERR_SUITE_B_LOS_NOT_ALLOWED",
-+    "X509_V_ERR_SUITE_B_CANNOT_SIGN_P_384_WITH_P_256",
-+    "X509_V_ERR_HOSTNAME_MISMATCH",
-+    "X509_V_ERR_EMAIL_MISMATCH",
-+    "X509_V_ERR_IP_ADDRESS_MISMATCH",
-+    "X509_V_ERR_DANE_NO_MATCH",
-+    "X509_V_ERR_EE_KEY_TOO_SMALL",
-+    "X509_V_ERR_CA_KEY_TOO_SMALL",
-+    "X509_V_ERR_CA_MD_TOO_WEAK",
-+    "X509_V_ERR_INVALID_CALL",
-+    "X509_V_ERR_STORE_LOOKUP",
-+    "X509_V_ERR_NO_VALID_SCTS",
-+    "X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION",
-+    "X509_V_ERR_OCSP_VERIFY_NEEDED",
-+    "X509_V_ERR_OCSP_VERIFY_FAILED",
-+    "X509_V_ERR_OCSP_CERT_UNKNOWN",
-     NULL
- };
- 
-@@ -390,7 +537,7 @@ Ssl::ParseErrorString(const char *name, Security::Errors &errors)
-     return false; // not reached
- }
- 
--const char *Ssl::GetErrorName(Security::ErrorCode value)
-+const char *Ssl::GetErrorName(Security::ErrorCode value, const bool prefixRawCode)
- {
-     if (TheSslErrors.empty())
-         loadSslErrorMap();
-@@ -399,7 +546,9 @@ const char *Ssl::GetErrorName(Security::ErrorCode value)
-     if (it != TheSslErrors.end())
-         return it->second->name;
- 
--    return NULL;
-+    static char tmpBuffer[128];
-+    snprintf(tmpBuffer, sizeof(tmpBuffer), "%s%d", prefixRawCode ? "SSL_ERR=" : "", (int)value);
-+    return tmpBuffer;
- }
- 
- bool
-@@ -529,21 +678,14 @@ const char *Ssl::ErrorDetail::notafter() const
-  */
- const char *Ssl::ErrorDetail::err_code() const
- {
--    static char tmpBuffer[64];
-     // We can use the GetErrorName but using the detailEntry is faster,
-     // so try it first.
--    const char *err = detailEntry.name.termedBuf();
-+    if (const char *err = detailEntry.name.termedBuf())
-+        return err;
- 
-     // error details not loaded yet or not defined in error_details.txt,
-     // try the GetErrorName...
--    if (!err)
--        err = GetErrorName(error_no);
--
--    if (!err) {
--        snprintf(tmpBuffer, 64, "%d", (int)error_no);
--        err = tmpBuffer;
--    }
--    return err;
-+    return GetErrorName(error_no);
- }
- 
- /**
-diff --git a/src/ssl/ErrorDetail.h b/src/ssl/ErrorDetail.h
-index 48dc405..0eec0a9 100644
---- a/src/ssl/ErrorDetail.h
-+++ b/src/ssl/ErrorDetail.h
-@@ -26,8 +26,9 @@ bool ParseErrorString(const char *name, Security::Errors &);
- /// The Security::ErrorCode code of the error described by  "name".
- Security::ErrorCode GetErrorCode(const char *name);
- 
--/// The string representation of the TLS error "value"
--const char *GetErrorName(Security::ErrorCode value);
-+/// \return string representation of a known TLS error (or a raw error code)
-+/// \param prefixRawCode whether to prefix raw codes with "SSL_ERR="
-+const char *GetErrorName(Security::ErrorCode value, const bool prefixRawCode = false);
- 
- /// A short description of the TLS error "value"
- const char *GetErrorDescr(Security::ErrorCode value);
diff --git a/SOURCES/squid-4.11-CVE-2020-15049.patch b/SOURCES/squid-4.11-CVE-2020-15049.patch
deleted file mode 100644
index 5f7151d..0000000
--- a/SOURCES/squid-4.11-CVE-2020-15049.patch
+++ /dev/null
@@ -1,105 +0,0 @@
-commit ea12a34d338b962707d5078d6d1fc7c6eb119a22
-Author: Alex Rousskov <rousskov@measurement-factory.com>
-Date:   2020-05-13 14:05:00 +0000
-
-    Validate Content-Length value prefix (#629)
-    
-    The new code detects all invalid Content-Length prefixes but the old
-    code was already rejecting most invalid prefixes using strtoll(). The
-    newly covered (and now rejected) invalid characters are
-    
-    * explicit "+" sign;
-    * explicit "-" sign in "-0" values;
-    * isspace(3) characters that are not (relaxed) OWS characters.
-    
-    In most deployment environments, the last set is probably empty because
-    the relaxed OWS set has all the POSIX/C isspace(3) characters but the
-    new line, and the new line is unlikely to sneak in past other checks.
-    
-    Thank you, Amit Klein <amit.klein@safebreach.com>, for elevating the
-    importance of this 2016 TODO (added in commit a1b9ec2).
-
-diff --git a/CONTRIBUTORS b/CONTRIBUTORS
-index 36957f2..c10a221 100644
---- a/CONTRIBUTORS
-+++ b/CONTRIBUTORS
-@@ -25,6 +25,7 @@ Thank you!
-     Alex Wu <alex_wu2012@hotmail.com>
-     Alin Nastac <mrness@gentoo.org>
-     Alter <alter@alter.org.ua>
-+    Amit Klein <amit.klein@safebreach.com>
-     Amos Jeffries
-     Amos Jeffries <amosjeffries@squid-cache.org>
-     Amos Jeffries <squid3@treenet.co.nz>
-diff --git a/src/http/ContentLengthInterpreter.cc b/src/http/ContentLengthInterpreter.cc
-index 3fdf7de..a3741eb 100644
---- a/src/http/ContentLengthInterpreter.cc
-+++ b/src/http/ContentLengthInterpreter.cc
-@@ -28,6 +28,24 @@ Http::ContentLengthInterpreter::ContentLengthInterpreter(const int aDebugLevel):
- {
- }
- 
-+/// checks whether all characters before the Content-Length number are allowed
-+/// \returns the start of the digit sequence (or nil on errors)
-+const char *
-+Http::ContentLengthInterpreter::findDigits(const char *prefix, const char * const valueEnd) const
-+{
-+    // skip leading OWS in RFC 7230's `OWS field-value OWS`
-+    const CharacterSet &whitespace = Http::One::Parser::WhitespaceCharacters();
-+    while (prefix < valueEnd) {
-+        const auto ch = *prefix;
-+        if (CharacterSet::DIGIT[ch])
-+            return prefix; // common case: a pre-trimmed field value
-+        if (!whitespace[ch])
-+            return nullptr; // (trimmed) length does not start with a digit
-+        ++prefix;
-+    }
-+    return nullptr; // empty or whitespace-only value
-+}
-+
- /// checks whether all characters after the Content-Length are allowed
- bool
- Http::ContentLengthInterpreter::goodSuffix(const char *suffix, const char * const end) const
-@@ -52,10 +70,19 @@ Http::ContentLengthInterpreter::checkValue(const char *rawValue, const int value
- {
-     Must(!sawBad);
- 
-+    const auto valueEnd = rawValue + valueSize;
-+
-+    const auto digits = findDigits(rawValue, valueEnd);
-+    if (!digits) {
-+        debugs(55, debugLevel, "WARNING: Leading garbage or empty value in" << Raw("Content-Length", rawValue, valueSize));
-+        sawBad = true;
-+        return false;
-+    }
-+
-     int64_t latestValue = -1;
-     char *suffix = nullptr;
--    // TODO: Handle malformed values with leading signs (e.g., "-0" or "+1").
--    if (!httpHeaderParseOffset(rawValue, &latestValue, &suffix)) {
-+
-+    if (!httpHeaderParseOffset(digits, &latestValue, &suffix)) {
-         debugs(55, DBG_IMPORTANT, "WARNING: Malformed" << Raw("Content-Length", rawValue, valueSize));
-         sawBad = true;
-         return false;
-@@ -68,7 +95,7 @@ Http::ContentLengthInterpreter::checkValue(const char *rawValue, const int value
-     }
- 
-     // check for garbage after the number
--    if (!goodSuffix(suffix, rawValue + valueSize)) {
-+    if (!goodSuffix(suffix, valueEnd)) {
-         debugs(55, debugLevel, "WARNING: Trailing garbage in" << Raw("Content-Length", rawValue, valueSize));
-         sawBad = true;
-         return false;
-diff --git a/src/http/ContentLengthInterpreter.h b/src/http/ContentLengthInterpreter.h
-index ce36e22..f22de91 100644
---- a/src/http/ContentLengthInterpreter.h
-+++ b/src/http/ContentLengthInterpreter.h
-@@ -46,6 +46,7 @@ public:
-     bool sawGood;
- 
- protected:
-+    const char *findDigits(const char *prefix, const char *valueEnd) const;
-     bool goodSuffix(const char *suffix, const char * const end) const;
-     bool checkValue(const char *start, const int size);
-     bool checkList(const String &list);
diff --git a/SOURCES/squid-4.11-CVE-2020-15810.patch b/SOURCES/squid-4.11-CVE-2020-15810.patch
deleted file mode 100644
index 252ffad..0000000
--- a/SOURCES/squid-4.11-CVE-2020-15810.patch
+++ /dev/null
@@ -1,44 +0,0 @@
-diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
-index 67543a4..19efc6d 100644
---- a/src/HttpHeader.cc
-+++ b/src/HttpHeader.cc
-@@ -445,18 +445,6 @@ HttpHeader::parse(const char *header_start, size_t hdrLen)
-             return 0;
-         }
- 
--        if (e->id == Http::HdrType::OTHER && stringHasWhitespace(e->name.termedBuf())) {
--            debugs(55, warnOnError, "WARNING: found whitespace in HTTP header name {" <<
--                   getStringPrefix(field_start, field_end-field_start) << "}");
--
--            if (!Config.onoff.relaxed_header_parser) {
--                delete e;
--                PROF_stop(HttpHeaderParse);
--                clean();
--                return 0;
--            }
--        }
--
-         addEntry(e);
-     }
- 
-@@ -1451,6 +1439,20 @@ HttpHeaderEntry::parse(const char *field_start, const char *field_end, const htt
-         }
-     }
- 
-+    /* RFC 7230 section 3.2:
-+     *
-+     *  header-field   = field-name ":" OWS field-value OWS
-+     *  field-name     = token
-+     *  token          = 1*TCHAR
-+     */
-+    for (const char *pos = field_start; pos < (field_start+name_len); ++pos) {
-+        if (!CharacterSet::TCHAR[*pos]) {
-+            debugs(55, 2, "found header with invalid characters in " <<
-+                   Raw("field-name", field_start, min(name_len,100)) << "...");
-+            return nullptr;
-+        }
-+    }
-+
-     /* now we know we can parse it */
- 
-     debugs(55, 9, "parsing HttpHeaderEntry: near '" <<  getStringPrefix(field_start, field_end-field_start) << "'");
diff --git a/SOURCES/squid-4.11-CVE-2020-15811.patch b/SOURCES/squid-4.11-CVE-2020-15811.patch
deleted file mode 100644
index 080124f..0000000
--- a/SOURCES/squid-4.11-CVE-2020-15811.patch
+++ /dev/null
@@ -1,139 +0,0 @@
-diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
-index dc6e0ff..67543a4 100644
---- a/src/HttpHeader.cc
-+++ b/src/HttpHeader.cc
-@@ -174,6 +174,7 @@ HttpHeader::operator =(const HttpHeader &other)
-         update(&other); // will update the mask as well
-         len = other.len;
-         conflictingContentLength_ = other.conflictingContentLength_;
-+        teUnsupported_ = other.teUnsupported_;
-     }
-     return *this;
- }
-@@ -222,6 +223,7 @@ HttpHeader::clean()
-     httpHeaderMaskInit(&mask, 0);
-     len = 0;
-     conflictingContentLength_ = false;
-+    teUnsupported_ = false;
-     PROF_stop(HttpHeaderClean);
- }
- 
-@@ -464,11 +466,23 @@ HttpHeader::parse(const char *header_start, size_t hdrLen)
-                Raw("header", header_start, hdrLen));
-     }
- 
--    if (chunked()) {
-+    String rawTe;
-+    if (getByIdIfPresent(Http::HdrType::TRANSFER_ENCODING, &rawTe)) {
-         // RFC 2616 section 4.4: ignore Content-Length with Transfer-Encoding
-         // RFC 7230 section 3.3.3 #3: Transfer-Encoding overwrites Content-Length
-         delById(Http::HdrType::CONTENT_LENGTH);
-         // and clen state becomes irrelevant
-+
-+        if (rawTe == "chunked") {
-+            ; // leave header present for chunked() method
-+        } else if (rawTe == "identity") { // deprecated. no coding
-+            delById(Http::HdrType::TRANSFER_ENCODING);
-+        } else {
-+            // This also rejects multiple encodings until we support them properly.
-+            debugs(55, warnOnError, "WARNING: unsupported Transfer-Encoding used by client: " << rawTe);
-+            teUnsupported_ = true;
-+        }
-+
-     } else if (clen.sawBad) {
-         // ensure our callers do not accidentally see bad Content-Length values
-         delById(Http::HdrType::CONTENT_LENGTH);
-diff --git a/src/HttpHeader.h b/src/HttpHeader.h
-index e3553a4..64f294a 100644
---- a/src/HttpHeader.h
-+++ b/src/HttpHeader.h
-@@ -140,7 +140,13 @@ public:
-     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
-+
-+    /// whether the message uses chunked Transfer-Encoding
-+    /// optimized implementation relies on us rejecting/removing other codings
-+    bool chunked() const { return has(Http::HdrType::TRANSFER_ENCODING); }
-+
-+    /// whether message used an unsupported and/or invalid Transfer-Encoding
-+    bool unsupportedTe() const { return teUnsupported_; }
- 
-     /* protected, do not use these, use interface functions instead */
-     std::vector<HttpHeaderEntry *> entries;     /**< parsed fields in raw format */
-@@ -158,6 +164,9 @@ protected:
- private:
-     HttpHeaderEntry *findLastEntry(Http::HdrType id) const;
-     bool conflictingContentLength_; ///< found different Content-Length fields
-+    /// unsupported encoding, unnecessary syntax characters, and/or
-+    /// invalid field-value found in Transfer-Encoding header
-+    bool teUnsupported_ = false;
- };
- 
- int httpHeaderParseQuotedString(const char *start, const int len, String *val);
-@@ -167,13 +176,6 @@ SBuf httpHeaderQuoteString(const char *raw);
- 
- void httpHeaderCalcMask(HttpHeaderMask * mask, Http::HdrType http_hdr_type_enums[], size_t count);
- 
--inline bool
--HttpHeader::chunked() const
--{
--    return has(Http::HdrType::TRANSFER_ENCODING) &&
--           hasListMember(Http::HdrType::TRANSFER_ENCODING, "chunked", ',');
--}
--
- void httpHeaderInitModule(void);
- 
- #endif /* SQUID_HTTPHEADER_H */
-diff --git a/src/client_side.cc b/src/client_side.cc
-index 5f5a79e..000a00b 100644
---- a/src/client_side.cc
-+++ b/src/client_side.cc
-@@ -1600,9 +1600,7 @@ void
- clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp, Http::Stream *context)
- {
-     ClientHttpRequest *http = context->http;
--    bool chunked = false;
-     bool mustReplyToOptions = false;
--    bool unsupportedTe = false;
-     bool expectBody = false;
- 
-     // We already have the request parsed and checked, so we
-@@ -1659,13 +1657,7 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
-         request->http_ver.minor = http_ver.minor;
-     }
- 
--    if (request->header.chunked()) {
--        chunked = true;
--    } else if (request->header.has(Http::HdrType::TRANSFER_ENCODING)) {
--        const String te = request->header.getList(Http::HdrType::TRANSFER_ENCODING);
--        // HTTP/1.1 requires chunking to be the last encoding if there is one
--        unsupportedTe = te.size() && te != "identity";
--    } // else implied identity coding
-+    const auto unsupportedTe = request->header.unsupportedTe();
- 
-     mustReplyToOptions = (request->method == Http::METHOD_OPTIONS) &&
-                          (request->header.getInt64(Http::HdrType::MAX_FORWARDS) == 0);
-@@ -1682,6 +1674,7 @@ clientProcessRequest(ConnStateData *conn, const Http1::RequestParserPointer &hp,
-         return;
-     }
- 
-+    const auto chunked = request->header.chunked();
-     if (!chunked && !clientIsContentLengthValid(request.getRaw())) {
-         clientStreamNode *node = context->getClientReplyContext();
-         clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
-diff --git a/src/http.cc b/src/http.cc
-index 9654c4a..6f4d3b2 100644
---- a/src/http.cc
-+++ b/src/http.cc
-@@ -1292,6 +1292,9 @@ HttpStateData::continueAfterParsingHeader()
-             } else if (vrep->header.conflictingContentLength()) {
-                 fwd->dontRetry(true);
-                 error = ERR_INVALID_RESP;
-+            } else if (vrep->header.unsupportedTe()) {
-+                fwd->dontRetry(true);
-+                error = ERR_INVALID_RESP;
-             } else {
-                 return true; // done parsing, got reply, and no error
-             }
diff --git a/SOURCES/squid-4.11-CVE-2020-24606.patch b/SOURCES/squid-4.11-CVE-2020-24606.patch
deleted file mode 100644
index d277507..0000000
--- a/SOURCES/squid-4.11-CVE-2020-24606.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-commit b789e719affbb0a6ff9c22095f6ca8db6a5f4926
-Author: Eduard Bagdasaryan <eduard.bagdasaryan@measurement-factory.com>
-Date:   2020-07-27 15:28:31 +0000
-
-    Fix livelocking in peerDigestHandleReply (#698)
-    
-    peerDigestHandleReply() was missing a premature EOF check. The existing
-    peerDigestFetchedEnough() cannot detect EOF because it does not have
-    access to receivedData.length used to indicate the EOF condition. We did
-    not adjust peerDigestFetchedEnough() because it is abused to check both
-    post-I/O state and the state after each digest processing step. The
-    latter invocations lack access to receivedData.length and should not
-    really bother with EOF anyway.
-
-diff --git a/src/peer_digest.cc b/src/peer_digest.cc
-index d48340f97..265f16183 100644
---- a/src/peer_digest.cc
-+++ b/src/peer_digest.cc
-@@ -483,6 +483,15 @@ peerDigestHandleReply(void *data, StoreIOBuffer receivedData)
- 
-     } while (cbdataReferenceValid(fetch) && prevstate != fetch->state && fetch->bufofs > 0);
- 
-+    // Check for EOF here, thus giving the parser one extra run. We could avoid this overhead by
-+    // checking at the beginning of this function. However, in this case, we would have to require
-+    // that the parser does not regard EOF as a special condition (it is true now but may change
-+    // in the future).
-+    if (!receivedData.length) { // EOF
-+        peerDigestFetchAbort(fetch, fetch->buf, "premature end of digest reply");
-+        return;
-+    }
-+
-     /* Update the copy offset */
-     fetch->offset += receivedData.length;
- 
diff --git a/SOURCES/squid-4.11-CVE-2020-25097.patch b/SOURCES/squid-4.11-CVE-2020-25097.patch
deleted file mode 100644
index 16fa1f8..0000000
--- a/SOURCES/squid-4.11-CVE-2020-25097.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-From dfd818595b54942cb1adc45f6aed95c9b706e3a8 Mon Sep 17 00:00:00 2001
-From: Amos Jeffries <yadij@users.noreply.github.com>
-Date: Fri, 4 Sep 2020 17:38:30 +1200
-Subject: [PATCH] Merge pull request from GHSA-jvf6-h9gj-pmj6
-
-* Add slash prefix to path-rootless or path-noscheme URLs
-
-* Update src/anyp/Uri.cc
-
-Co-authored-by: Alex Rousskov <rousskov@measurement-factory.com>
-
-* restore file trailer GH auto-removes
-
-* Remove redundant path-empty check
-
-* Removed stale comment left behind by b2ab59a
-
-Many things imply a leading `/` in a URI. Their enumeration is likely to
-(and did) become stale, misleading the reader.
-
-* fixup: Remind that the `src` iterator may be at its end
-
-We are dereferencing `src` without comparing it to `\0`.
-To many readers that (incorrectly) implies that we are not done iterating yet.
-
-Also fixed branch-added comment indentation.
-
-Co-authored-by: Alex Rousskov <rousskov@measurement-factory.com>
----
- src/anyp/Uri.cc | 10 +++-------
- 1 file changed, 3 insertions(+), 7 deletions(-)
-
-diff --git a/src/anyp/Uri.cc b/src/anyp/Uri.cc
-index b745c54..31f02d5 100644
---- a/src/anyp/Uri.cc
-+++ b/src/anyp/Uri.cc
-@@ -293,8 +293,9 @@ AnyP::Uri::parse(const HttpRequestMethod& method, const SBuf &rawUrl)
-                 return false;
-             *dst = '\0';
- 
--            // bug 3074: received 'path' starting with '?', '#', or '\0' implies '/'
--            if (*src == '?' || *src == '#' || *src == '\0') {
-+            // We are looking at path-abempty.
-+            if (*src != '/') {
-+                // path-empty, including the end of the `src` c-string cases
-                 urlpath[0] = '/';
-                 dst = &urlpath[1];
-             } else {
-@@ -308,11 +309,6 @@ AnyP::Uri::parse(const HttpRequestMethod& method, const SBuf &rawUrl)
-             /* We -could- be at the end of the buffer here */
-             if (i > l)
-                 return false;
--            /* If the URL path is empty we set it to be "/" */
--            if (dst == urlpath) {
--                *dst = '/';
--                ++dst;
--            }
-             *dst = '\0';
- 
-             foundPort = scheme.defaultPort(); // may be reset later
diff --git a/SOURCES/squid-4.11-cache-mgr-auth-strdup.patch b/SOURCES/squid-4.11-cache-mgr-auth-strdup.patch
deleted file mode 100644
index 88c903e..0000000
--- a/SOURCES/squid-4.11-cache-mgr-auth-strdup.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-diff --git a/tools/cachemgr.cc b/tools/cachemgr.cc
-index 36d8e38..50bb9b6 100644
---- a/tools/cachemgr.cc
-+++ b/tools/cachemgr.cc
-@@ -1092,14 +1092,20 @@ make_pub_auth(cachemgr_request * req)
-     if (!req->passwd || !strlen(req->passwd))
-         return;
- 
-+    auto *rfc1738_username = xstrdup(rfc1738_escape(safe_str(req->user_name)));
-+    auto *rfc1738_passwd = xstrdup(rfc1738_escape(req->passwd));
-+
-     /* host | time | user | passwd */
-     const int bufLen = snprintf(buf, sizeof(buf), "%s|%d|%s|%s",
-                                 req->hostname,
-                                 (int) now,
--                                rfc1738_escape(safe_str(req->user_name)),
--                                rfc1738_escape(req->passwd));
-+                                rfc1738_username,
-+                                rfc1738_passwd);
-     debug("cmgr: pre-encoded for pub: %s\n", buf);
- 
-+    safe_free(rfc1738_username);
-+    safe_free(rfc1738_passwd);
-+
-     const int encodedLen = base64_encode_len(bufLen);
-     req->pub_auth = (char *) xmalloc(encodedLen);
-     struct base64_encode_ctx ctx;
diff --git a/SOURCES/squid-4.11-convert-ipv4.patch b/SOURCES/squid-4.11-convert-ipv4.patch
index 4a6e47f..5198f35 100644
--- a/SOURCES/squid-4.11-convert-ipv4.patch
+++ b/SOURCES/squid-4.11-convert-ipv4.patch
@@ -14,131 +14,129 @@ Move client_ip_max_connections test later in the TCP accept process to ensure ds
  1 file changed, 39 insertions(+), 43 deletions(-)
 
 diff --git a/src/comm/TcpAcceptor.cc b/src/comm/TcpAcceptor.cc
-index cae92a7b1e..2109913008 100644
+index d4b576d..936aa30 100644
 --- a/src/comm/TcpAcceptor.cc
 +++ b/src/comm/TcpAcceptor.cc
-@@ -282,16 +282,7 @@ Comm::TcpAcceptor::acceptOne()
+@@ -282,7 +282,16 @@ Comm::TcpAcceptor::acceptOne()
      ConnectionPointer newConnDetails = new Connection();
      const Comm::Flag flag = oldAccept(newConnDetails);
  
--    /* Check for errors */
--    if (!newConnDetails->isOpen()) {
--
--        if (flag == Comm::NOMESSAGE) {
--            /* register interest again */
--            debugs(5, 5, HERE << "try later: " << conn << " handler Subscription: " << theCallSub);
--            SetSelect(conn->fd, COMM_SELECT_READ, doAccept, this, 0);
--            return;
--        }
--
-+    if (flag == Comm::COMM_ERROR) {
+-    if (flag == Comm::COMM_ERROR) {
++    /* Check for errors */
++    if (!newConnDetails->isOpen()) {
++
++        if (flag == Comm::NOMESSAGE) {
++            /* register interest again */
++            debugs(5, 5, HERE << "try later: " << conn << " handler Subscription: " << theCallSub);
++            SetSelect(conn->fd, COMM_SELECT_READ, doAccept, this, 0);
++            return;
++        }
++
          // A non-recoverable error; notify the caller */
          debugs(5, 5, HERE << "non-recoverable error:" << status() << " handler Subscription: " << theCallSub);
          if (intendedForUserConnections())
-@@ -301,12 +292,16 @@ Comm::TcpAcceptor::acceptOne()
+@@ -292,16 +301,12 @@ Comm::TcpAcceptor::acceptOne()
          return;
      }
  
--    newConnDetails->nfmark = Ip::Qos::getNfmarkFromConnection(newConnDetails, Ip::Qos::dirAccepted);
-+    if (flag == Comm::NOMESSAGE) {
-+        /* register interest again */
-+        debugs(5, 5, "try later: " << conn << " handler Subscription: " << theCallSub);
-+    } else {
-+        debugs(5, 5, "Listener: " << conn <<
-+               " accepted new connection " << newConnDetails <<
-+               " handler Subscription: " << theCallSub);
-+        notify(flag, newConnDetails);
-+    }
+-    if (flag == Comm::NOMESSAGE) {
+-        /* register interest again */
+-        debugs(5, 5, "try later: " << conn << " handler Subscription: " << theCallSub);
+-    } else {
+-        debugs(5, 5, "Listener: " << conn <<
+-               " accepted new connection " << newConnDetails <<
+-               " handler Subscription: " << theCallSub);
+-        notify(flag, newConnDetails);
+-    }
++    newConnDetails->nfmark = Ip::Qos::getNfmarkFromConnection(newConnDetails, Ip::Qos::dirAccepted);
  
--    debugs(5, 5, HERE << "Listener: " << conn <<
--           " accepted new connection " << newConnDetails <<
--           " handler Subscription: " << theCallSub);
--    notify(flag, newConnDetails);
++    debugs(5, 5, HERE << "Listener: " << conn <<
++           " accepted new connection " << newConnDetails <<
++           " handler Subscription: " << theCallSub);
++    notify(flag, newConnDetails);
      SetSelect(conn->fd, COMM_SELECT_READ, doAccept, this, 0);
  }
  
-@@ -346,8 +341,8 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer &
+@@ -341,8 +346,8 @@ Comm::TcpAcceptor::notify(const Comm::Flag flag, const Comm::ConnectionPointer &
   *
   * \retval Comm::OK          success. details parameter filled.
   * \retval Comm::NOMESSAGE   attempted accept() but nothing useful came in.
-- * \retval Comm::COMM_ERROR  an outright failure occurred.
-  *                           Or this client has too many connections already.
-+ * \retval Comm::COMM_ERROR  an outright failure occurred.
+- *                           Or this client has too many connections already.
+  * \retval Comm::COMM_ERROR  an outright failure occurred.
++ *                           Or this client has too many connections already.
   */
  Comm::Flag
  Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
-@@ -382,15 +377,6 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
-     details->fd = sock;
+@@ -383,6 +388,15 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
+ 
      details->remote = *gai;
  
--    if ( Config.client_ip_max_connections >= 0) {
--        if (clientdbEstablished(details->remote, 0) > Config.client_ip_max_connections) {
--            debugs(50, DBG_IMPORTANT, "WARNING: " << details->remote << " attempting more than " << Config.client_ip_max_connections << " connections.");
--            Ip::Address::FreeAddr(gai);
--            PROF_stop(comm_accept);
--            return Comm::COMM_ERROR;
--        }
--    }
--
++    if ( Config.client_ip_max_connections >= 0) {
++        if (clientdbEstablished(details->remote, 0) > Config.client_ip_max_connections) {
++            debugs(50, DBG_IMPORTANT, "WARNING: " << details->remote << " attempting more than " << Config.client_ip_max_connections << " connections.");
++            Ip::Address::FreeAddr(gai);
++            PROF_stop(comm_accept);
++            return Comm::COMM_ERROR;
++        }
++    }
++
      // lookup the local-end details of this new connection
      Ip::Address::InitAddr(gai);
      details->local.setEmpty();
-@@ -404,6 +390,34 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
+@@ -396,6 +410,23 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
      details->local = *gai;
      Ip::Address::FreeAddr(gai);
  
-+    // Perform NAT or TPROXY operations to retrieve the real client/dest IP addresses
-+    if (conn->flags&(COMM_TRANSPARENT|COMM_INTERCEPTION) && !Ip::Interceptor.Lookup(details, conn)) {
-+        debugs(50, DBG_IMPORTANT, "ERROR: NAT/TPROXY lookup failed to locate original IPs on " << details);
-+        // Failed.
-+        PROF_stop(comm_accept);
-+        return Comm::COMM_ERROR;
-+    }
++    /* fdstat update */
++    fdd_table[sock].close_file = NULL;
++    fdd_table[sock].close_line = 0;
 +
-+#if USE_SQUID_EUI
-+    if (Eui::TheConfig.euiLookup) {
-+        if (details->remote.isIPv4()) {
-+            details->remoteEui48.lookup(details->remote);
-+        } else if (details->remote.isIPv6()) {
-+            details->remoteEui64.lookup(details->remote);
-+        }
-+    }
-+#endif
++    fde *F = &fd_table[sock];
++    details->remote.toStr(F->ipaddr,MAX_IPSTRLEN);
++    F->remote_port = details->remote.port();
++    F->local_addr = details->local;
++    F->sock_family = details->local.isIPv6()?AF_INET6:AF_INET;
 +
-+    details->nfmark = Ip::Qos::getNfmarkFromConnection(details, Ip::Qos::dirAccepted);
++    // set socket flags
++    commSetCloseOnExec(sock);
++    commSetNonBlocking(sock);
 +
-+    if (Config.client_ip_max_connections >= 0) {
-+        if (clientdbEstablished(details->remote, 0) > Config.client_ip_max_connections) {
-+            debugs(50, DBG_IMPORTANT, "WARNING: " << details->remote << " attempting more than " << Config.client_ip_max_connections << " connections.");
-+            PROF_stop(comm_accept);
-+            return Comm::NOMESSAGE;
-+        }
-+    }
++    /* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
++    F->flags.transparent = fd_table[conn->fd].flags.transparent; // XXX: can we remove this line yet?
 +
-     /* fdstat update */
-     // XXX : these are not all HTTP requests. use a note about type and ip:port details->
-     // so we end up with a uniform "(HTTP|FTP-data|HTTPS|...) remote-ip:remote-port"
-@@ -425,24 +439,6 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
-     /* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
-     F->flags.transparent = fd_table[conn->fd].flags.transparent; // XXX: can we remove this line yet?
+     // Perform NAT or TPROXY operations to retrieve the real client/dest IP addresses
+     if (conn->flags&(COMM_TRANSPARENT|COMM_INTERCEPTION) && !Ip::Interceptor.Lookup(details, conn)) {
+         debugs(50, DBG_IMPORTANT, "ERROR: NAT/TPROXY lookup failed to locate original IPs on " << details);
+@@ -414,33 +445,6 @@ Comm::TcpAcceptor::oldAccept(Comm::ConnectionPointer &details)
+     }
+ #endif
  
--    // Perform NAT or TPROXY operations to retrieve the real client/dest IP addresses
--    if (conn->flags&(COMM_TRANSPARENT|COMM_INTERCEPTION) && !Ip::Interceptor.Lookup(details, conn)) {
--        debugs(50, DBG_IMPORTANT, "ERROR: NAT/TPROXY lookup failed to locate original IPs on " << details);
--        // Failed.
--        PROF_stop(comm_accept);
--        return Comm::COMM_ERROR;
--    }
+-    details->nfmark = Ip::Qos::getNfmarkFromConnection(details, Ip::Qos::dirAccepted);
 -
--#if USE_SQUID_EUI
--    if (Eui::TheConfig.euiLookup) {
--        if (details->remote.isIPv4()) {
--            details->remoteEui48.lookup(details->remote);
--        } else if (details->remote.isIPv6()) {
--            details->remoteEui64.lookup(details->remote);
+-    if (Config.client_ip_max_connections >= 0) {
+-        if (clientdbEstablished(details->remote, 0) > Config.client_ip_max_connections) {
+-            debugs(50, DBG_IMPORTANT, "WARNING: " << details->remote << " attempting more than " << Config.client_ip_max_connections << " connections.");
+-            PROF_stop(comm_accept);
+-            return Comm::NOMESSAGE;
 -        }
 -    }
--#endif
+-
+-    /* fdstat update */
+-    fdd_table[sock].close_file = NULL;
+-    fdd_table[sock].close_line = 0;
+-
+-    fde *F = &fd_table[sock];
+-    details->remote.toStr(F->ipaddr,MAX_IPSTRLEN);
+-    F->remote_port = details->remote.port();
+-    F->local_addr = details->local;
+-    F->sock_family = details->local.isIPv6()?AF_INET6:AF_INET;
+-
+-    // set socket flags
+-    commSetCloseOnExec(sock);
+-    commSetNonBlocking(sock);
+-
+-    /* IFF the socket is (tproxy) transparent, pass the flag down to allow spoofing */
+-    F->flags.transparent = fd_table[conn->fd].flags.transparent; // XXX: can we remove this line yet?
 -
      PROF_stop(comm_accept);
      return Comm::OK;
diff --git a/SOURCES/squid-4.11-perlpath.patch b/SOURCES/squid-4.11-perlpath.patch
index 18c74a6..9e7fbbc 100644
--- a/SOURCES/squid-4.11-perlpath.patch
+++ b/SOURCES/squid-4.11-perlpath.patch
@@ -6,5 +6,5 @@ index 90ac6a4..8dbed90 100755
 -#!/usr/local/bin/perl -Tw
 +#!/usr/bin/perl -Tw
  #
- # * Copyright (C) 1996-2020 The Squid Software Foundation and contributors
+ # * Copyright (C) 1996-2021 The Squid Software Foundation and contributors
  # *
diff --git a/SOURCES/squid-4.11-systemd.patch b/SOURCES/squid-4.11-systemd.patch
deleted file mode 100644
index a461881..0000000
--- a/SOURCES/squid-4.11-systemd.patch
+++ /dev/null
@@ -1,39 +0,0 @@
-diff --git a/configure b/configure
-index 17b2ebf..9530f6b 100755
---- a/configure
-+++ b/configure
-@@ -33915,6 +33915,7 @@ done
-   fi
-   if test "x$SYSTEMD_LIBS" != "x" ; then
-     CXXFLAGS="$SYSTEMD_CFLAGS $CXXFLAGS"
-+    LDFLAGS="$SYSTEMD_LIBS $LDFLAGS"
- 
- $as_echo "#define USE_SYSTEMD 1" >>confdefs.h
- 
-diff --git a/src/Debug.h b/src/Debug.h
-index 6eecd01..ddd9e38 100644
---- a/src/Debug.h
-+++ b/src/Debug.h
-@@ -99,6 +99,10 @@ public:
- 
-     /// configures the active debugging context to write syslog ALERT
-     static void ForceAlert();
-+
-+    /// prefixes each grouped debugs() line after the first one in the group
-+    static std::ostream& Extra(std::ostream &os) { return os << "\n    "; }
-+
- private:
-     static Context *Current; ///< deepest active context; nil outside debugs()
- };
-diff --git a/configure.ac b/configure.ac
-index d3c5da8..806302c 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -2162,6 +2162,7 @@ if test "x$with_systemd" != "xno" -a "x$squid_host_os" = "xlinux"; then
-   fi
-   if test "x$SYSTEMD_LIBS" != "x" ; then
-     CXXFLAGS="$SYSTEMD_CFLAGS $CXXFLAGS"
-+    LDFLAGS="$SYSTEMD_LIBS $LDFLAGS"
-     AC_DEFINE(USE_SYSTEMD,1,[systemd support is available])
-   else
-     with_systemd=no
diff --git a/SOURCES/squid-4.11.tar.xz.asc b/SOURCES/squid-4.11.tar.xz.asc
deleted file mode 100644
index 79a79ee..0000000
--- a/SOURCES/squid-4.11.tar.xz.asc
+++ /dev/null
@@ -1,25 +0,0 @@
-File: squid-4.11.tar.xz
-Date: Sun Apr 19 12:56:37 UTC 2020
-Size: 2447700
-MD5 : 10f34e852153a9996aa4614670e2bda1
-SHA1: 053277bf5497163ffc9261b9807abda5959bb6fc
-Key : CD6DBF8EF3B17D3E <squid3@treenet.co.nz>
-            B068 84ED B779 C89B 044E  64E3 CD6D BF8E F3B1 7D3E
-      keyring = http://www.squid-cache.org/pgp.asc
-      keyserver = pool.sks-keyservers.net
------BEGIN PGP SIGNATURE-----
-
-iQIzBAABCgAdFiEEsGiE7bd5yJsETmTjzW2/jvOxfT4FAl6cSpEACgkQzW2/jvOx
-fT6YbA/6A+IbIbNBJUW45oj23Io9Tw/CzAcTeLHR+McKwV77qMbR+L+kQ+fUdM5F
-rHAmd8bVVlyHc4WanVfWItEmzBzHA/ifTNvVpefSGGEbDb80RF66k7ACiZUokg1b
-kkPwc/SjDhe2wvketIaBiVVd7pylrlCdVvazcF8gE9MWDOIlJND5mnHXidXvwkbJ
-T2//8JZVEmcmN9pdFGNAUVckFm+AnwWXcRM1SQPYDGSVUtjVlqido8snLTA1mZwl
-rIpjppujMV54OOWlj+Gqa3MZkpNzIaMCAfphzUFlsQY+/sRUYAOv1wmxw2WclxlK
-WlWM+fw8OsYNDMwkOScKZZWceoAkq6UsUHzCAdJIdLqV/R6mZ9nfuZ6BHIr0+2dP
-bDf9MU4KXbwEuXiRD/KPziUxxOZwSPivbm3wy9DqTTZfO9V+Iq6FVHX+ahxJ0XbM
-JWRYA3GW+DRLjorfsWxU5r4UJsrnBfhItPUAfGPjPjEGZ/pn8r9G6MGenNGPLMKy
-wP1rMlOhrZPwerzokzAvKx8G0WWkfN+IPv2JK3rDot6RiJIOuvnZZd4RIuVNTGbh
-liO7M24JlWX3WD2wHBzxQag46+plb3VvrrVChwIQnZ2Qzpf50w0Bife/wtNBGpK0
-k/Xi/nocO796YS8GZBnmhS1lEGEwp/YpJBFWmIjTWMUMEOcswVA=
-=PKl0
------END PGP SIGNATURE-----
diff --git a/SOURCES/squid-4.15.tar.xz.asc b/SOURCES/squid-4.15.tar.xz.asc
new file mode 100644
index 0000000..7305eaa
--- /dev/null
+++ b/SOURCES/squid-4.15.tar.xz.asc
@@ -0,0 +1,25 @@
+File: squid-4.15.tar.xz
+Date: Mon 10 May 2021 10:50:22 UTC
+Size: 2454176
+MD5 : a593de9dc888dfeca4f1f7db2cd7d3b9
+SHA1: 60bda34ba39657e2d870c8c1d2acece8a69c3075
+Key : CD6DBF8EF3B17D3E <squid3@treenet.co.nz>
+            B068 84ED B779 C89B 044E  64E3 CD6D BF8E F3B1 7D3E
+      keyring = http://www.squid-cache.org/pgp.asc
+      keyserver = pool.sks-keyservers.net
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCgAdFiEEsGiE7bd5yJsETmTjzW2/jvOxfT4FAmCZD/UACgkQzW2/jvOx
+fT6zZg/+N8JMIYpmVJ7jm4lF0Ub2kEHGTOrc+tnlA3LGnlMQuTm61+BYk58g0SKW
+96NbJ0cycW215Q34L+Y0tWuxEbIU01vIc3AA7rQd0LKy+fQU0OtBuhk5Vf4bKilW
+uHEVIQZs9HmY6bqC+kgtCf49tVZvR8FZYNuilg/68+i/pQdwaDDmVb+j2oF7w+y2
+dgkTFWtM5NTL6bqUVC0E7lLFPjzMefKfxkkpWFdV/VrAhU25jN24kpnjcfotQhdW
+LDFy5okduz3ljso9pBYJfLeMXM1FZPpceC91zj32x3tcUyrD3yIoXob58rEKvfe4
+RDXN4SuClsNe4UQ4oNoGIES9XtaYlOzPR1PlbqPUrdp1cDnhgLJ+1fkAixlMqCml
+wuI1VIKSEY+nvRzQzFHnXJK9otV8QwMF76AHaytO9y+X6JuZmu/CcV1pq61qY9qv
+t1/8z99wWSxpu17zthZgq64J225GF/hkBedaFlYoS5k5YUMDLPlRSCC0yPmb8JBF
+Cns5i/aq2PmOx2ZhQ2RQIF416J3HK8Galw8ytFOjnEcn4ux9yzKNjL38p4+PJJA0
+7GCMAqYYNjok3LSkGbiR7cPgbHnkqRfYbPFLMj4FtruoFlZ9L5MIU3oFvqA3ZR6l
+Az6LaKLsAYPUmukAOPUSIrqpKXZHc7hdBWkT+7RYA4qaoU+9oIo=
+=1Re1
+-----END PGP SIGNATURE-----
diff --git a/SPECS/squid.spec b/SPECS/squid.spec
index 3ecf752..20aa8ac 100644
--- a/SPECS/squid.spec
+++ b/SPECS/squid.spec
@@ -1,8 +1,8 @@
 %define __perl_requires %{SOURCE98}
 
 Name:     squid
-Version:  4.11
-Release:  4%{?dist}.2
+Version:  4.15
+Release:  1%{?dist}
 Summary:  The Squid proxy caching server
 Epoch:    7
 # See CREDITS for breakdown of non GPLv2+ code
@@ -33,26 +33,9 @@ Patch204: squid-4.11-include-guards.patch
 Patch205: squid-4.11-large-acl.patch
 # https://bugzilla.redhat.com/show_bug.cgi?id=980511
 Patch206: squid-4.11-active-ftp.patch
-# https://github.com/squid-cache/squid/commit/c26cd1cb6a60ff196ef13c00e82576d3bfeb2e30
-Patch207: squid-4.11-systemd.patch
 Patch208: squid-4.11-convert-ipv4.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1890606
-Patch209: squid-4.11-cache-mgr-auth-strdup.patch
 
 # Security fixes
-# https://bugzilla.redhat.com/show_bug.cgi?id=1852554
-Patch500: squid-4.11-CVE-2020-14058.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1852550
-Patch501: squid-4.11-CVE-2020-15049.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1871705
-Patch502: squid-4.11-CVE-2020-24606.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1871702
-Patch503: squid-4.11-CVE-2020-15811.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1871700
-Patch504: squid-4.11-CVE-2020-15810.patch
-# https://bugzilla.redhat.com/show_bug.cgi?id=1944260
-Patch505: squid-4.11-CVE-2020-25097.patch
-
 
 Requires: bash >= 2.0
 Requires(pre): shadow-utils
@@ -111,17 +94,9 @@ lookup program (dnsserver), a program for retrieving FTP data
 %patch204 -p1 -b .include-guards
 %patch205 -p1 -b .large_acl
 %patch206 -p1 -b .active-ftp
-%patch207 -p1 -b .systemd
-%patch208 -p1 -R -b .convert-ipv4
-%patch209 -p1 -b .cachemgr-strdup
+%patch208 -p1 -b .convert-ipv4
 
 # Security patches
-%patch500 -p1 -b .cve-2020-14058
-%patch501 -p1 -b .cve-2020-15049
-%patch502 -p1 -b .cve-2020-24606
-%patch503 -p1 -b .CVE-2020-15811
-%patch504 -p1 -b .CVE-2020-15810
-%patch505 -p1 -b .CVE-2020-25097
 
 # https://bugzilla.redhat.com/show_bug.cgi?id=1679526
 # Patch in the vendor documentation and used different location for documentation
@@ -338,8 +313,12 @@ fi
 
 
 %changelog
-* Wed Mar 31 2021 Lubos Uhliarik <luhliari@redhat.com> - 7:4.11-4.2
-- Resolves: #1944260 - CVE-2020-25097 squid:4/squid: improper input validation
+* Fri Jun 18 2021 Luboš Uhliarik <luhliari@redhat.com> - 7:4.15-1
+- new version 4.15
+- Resolves: #1964384 - squid:4 rebase to 4.15
+
+* Wed Mar 31 2021 Lubos Uhliarik <luhliari@redhat.com> - 7:4.11-5
+- Resolves: #1944261 - CVE-2020-25097 squid:4/squid: improper input validation
   may allow a trusted client to perform HTTP Request Smuggling
 
 * Mon Oct 26 2020 Lubos Uhliarik <luhliari@redhat.com> - 7:4.11-4