Hello,

This patch fixes URI schemes to be case-insensitive (r14802 regression).

The bug was introduced by r14802 (better support of unknown
URL schemes). AnyP::UriScheme constructor had a problem: the
explicitly-specified img parameter (always provided by URL::setScheme())
was used for all schemes, not only for unknown ones (as it obviously
should be). As a result, the code responsible for lower-case
transformation was not executed.

There are a couple of XXX and one of them (about "broken caller" for
PROTO_NONE) needs clarification. This caller uses PROTO_NONE
(i.e., absent scheme) together with "http" scheme image inside
clientReplyContext::createStoreEntry() which looks inconsistent and
probably is a bug. Am I missing anything there?


Thanks,
Eduard.

Fix URI schemes to be case-insensitive (caused by r14802).

The patch fixes a bug introduced by r14802 (better support of unknown
URL schemes). AnyP::UriScheme constructor had a problem: the
explicitly-specified img parameter (always provided by URL::setScheme())
was used for all schemes, not only for unknown ones (as it obviously
should be). As a result, the code responsible for lower-case
transformation was not executed.

=== modified file 'src/anyp/UriScheme.cc'
--- src/anyp/UriScheme.cc	2016-08-17 00:38:25 +0000
+++ src/anyp/UriScheme.cc	2017-01-05 14:57:10 +0000
@@ -1,61 +1,71 @@
 /*
  * Copyright (C) 1996-2016 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.
  */
 
 /* DEBUG: section 23    URL Scheme parsing */
 
 #include "squid.h"
 #include "anyp/UriScheme.h"
 
 AnyP::UriScheme::UriScheme(AnyP::ProtocolType const aScheme, const char *img) :
     theScheme_(aScheme)
 {
-    if (img)
-        // image could be provided explicitly (case-sensitive)
-        image_ = img;
-
+    // RFC 3986 section 3.1: schemes are case-insensitive.
+
+    // To improve diagnostic, remember exactly how an unsupported scheme looks like.
+    // XXX: Object users may rely on toLower() canonicalization that we refuse to provide.
+    if (img && theScheme_ == AnyP::PROTO_UNKNOWN)
+         image_ = img;
+
+    // XXX: A broken caller supplies an image of an absent scheme?
+    // XXX: We assume that the caller is using a lower-case image.
+    else if (img && theScheme_ == AnyP::PROTO_NONE)
+         image_ = img;
+
+    // the caller knows nothing about the scheme
+    // TODO: Avoid special casing by storing this string in the generated ProtocolType_str?
     else if (theScheme_ == AnyP::PROTO_UNKNOWN)
-        // image could be actually unknown and not provided
-        image_ = "(unknown)";
+         image_ = "(unknown)";
 
+    // use the standard image (and ignore supplied one, if any) for known transfer protocols
     else if (theScheme_ > AnyP::PROTO_NONE && theScheme_ < AnyP::PROTO_MAX) {
-        // image could be implied by a registered transfer protocol
-        // which use upper-case labels, so down-case for scheme image
+        // XXX: do not allocate (and lower-case) a new SBuf every time we need a well-known image
         image_ = AnyP::ProtocolType_str[theScheme_];
         image_.toLower();
     }
-    // else, image is an empty string ("://example.com/")
+    // else, the image remains empty (e.g., "://example.com/")
+    // hopefully, theScheme_ is PROTO_NONE here
 }
 
 unsigned short
 AnyP::UriScheme::defaultPort() const
 {
     switch (theScheme_) {
 
     case AnyP::PROTO_HTTP:
         return 80;
 
     case AnyP::PROTO_HTTPS:
         return 443;
 
     case AnyP::PROTO_FTP:
         return 21;
 
     case AnyP::PROTO_COAP:
     case AnyP::PROTO_COAPS:
         // coaps:// default is TBA as of draft-ietf-core-coap-08.
         // Assuming IANA policy of allocating same port for base and TLS protocol versions will occur.
         return 5683;
 
     case AnyP::PROTO_GOPHER:
         return 70;
 
     case AnyP::PROTO_WAIS:
         return 210;
 
     case AnyP::PROTO_CACHE_OBJECT:
         return CACHE_HTTP_PORT;

=== modified file 'src/anyp/UriScheme.h'
--- src/anyp/UriScheme.h	2016-08-17 00:38:25 +0000
+++ src/anyp/UriScheme.h	2017-01-03 18:04:03 +0000
@@ -1,56 +1,57 @@
 /*
  * Copyright (C) 1996-2016 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_ANYP_URISCHEME_H
 #define SQUID_ANYP_URISCHEME_H
 
 #include "anyp/ProtocolType.h"
 #include "sbuf/SBuf.h"
 
 #include <iosfwd>
 
 namespace AnyP
 {
 
 /** This class represents a URI Scheme such as http:// https://, wais://, urn: etc.
  * It does not represent the PROTOCOL that such schemes refer to.
  */
 class UriScheme
 {
 public:
     UriScheme() : theScheme_(AnyP::PROTO_NONE) {}
+    /// \param img Explicit scheme representation for unknown/none schemes.
     UriScheme(AnyP::ProtocolType const aScheme, const char *img = nullptr);
     UriScheme(const AnyP::UriScheme &o) : theScheme_(o.theScheme_), image_(o.image_) {}
     UriScheme(AnyP::UriScheme &&) = default;
     ~UriScheme() {}
 
     AnyP::UriScheme& operator=(const AnyP::UriScheme &o) {
         theScheme_ = o.theScheme_;
         image_ = o.image_;
         return *this;
     }
     AnyP::UriScheme& operator=(AnyP::UriScheme &&) = default;
 
     operator AnyP::ProtocolType() const { return theScheme_; }
     // XXX: does not account for comparison of unknown schemes (by image)
     bool operator != (AnyP::ProtocolType const & aProtocol) const { return theScheme_ != aProtocol; }
 
     /** Get a char string representation of the scheme.
      * Does not include the ':' or "://" terminators.
      */
     SBuf image() const {return image_;}
 
     unsigned short defaultPort() const;
 
 private:
     /// This is a typecode pointer into the enum/registry of protocols handled.
     AnyP::ProtocolType theScheme_;
 
     /// the string representation
     SBuf image_;
 };

_______________________________________________
squid-dev mailing list
[email protected]
http://lists.squid-cache.org/listinfo/squid-dev

Reply via email to