• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010, Google Inc. All rights reserved.
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google Inc. nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 
30 #ifndef URLQueryCanonicalizer_h
31 #define URLQueryCanonicalizer_h
32 
33 #include "RawURLBuffer.h"
34 #include "URLBuffer.h"
35 #include "URLCharacterTypes.h"
36 #include "URLComponent.h"
37 #include "URLEscape.h"
38 
39 namespace WTF {
40 
41 template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)>
42 class URLQueryCanonicalizer {
43 public:
canonicalize(const InChar * spec,const URLComponent & query,URLBuffer<OutChar> & buffer,URLComponent & resultQuery)44     static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery)
45     {
46         if (query.length() < 0) {
47             resultQuery = URLComponent();
48             return;
49         }
50 
51         buffer->append('?');
52         resultQuery.setBegin(buffer->length());
53         convertToQueryEncoding(spec, query, buffer);
54         resultQuery.setLength(buffer->length() - resultQuery.begin());
55     }
56 
57 private:
isAllASCII(const InChar * spec,const URLComponent & query)58     static bool isAllASCII(const InChar* spec, const URLComponent& query)
59     {
60         int end = query.end();
61         for (int i = query.begin(); i < end; ++i) {
62             if (static_cast<unsigned>(spec[i]) >= 0x80)
63                 return false;
64         }
65         return true;
66     }
67 
68 #ifndef NDEBUG
isRaw8Bit(const InChar * source,int length)69     static bool isRaw8Bit(const InChar* source, int length)
70     {
71         for (int i = source; i < length; ++i) {
72             if (source[i] & 0xFF != source[i])
73                 return false;
74         }
75         return true;
76     }
77 #endif
78 
appendRaw8BitQueryString(const InChar * source,int length,URLBuffer<OutChar> * buffer)79     static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer)
80     {
81         ASSERT(isRaw8Bit(source, length));
82         for (int i = 0; i < length; ++i) {
83             if (!URLCharacterTypes::isQueryChar(source[i]))
84                 appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer);
85             else
86                 buffer->append(static_cast<char>(source[i]));
87         }
88     }
89 
convertToQueryEncoding(const InChar * spec,const URLComponent & query,URLBuffer<OutChar> & buffer)90     static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer)
91     {
92         if (isAllASCII(spec, query)) {
93             appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer);
94             return;
95         }
96 
97         RawURLBuffer<char, 1024> convertedQuery;
98         convertCharset(spec, query, convertedQuery);
99         appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer);
100     }
101 };
102 
103 }
104 
105 #endif
106 
107 
108