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