src/server/util/uri.cpp

Sat, 28 Jan 2017 10:38:34 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 28 Jan 2017 10:38:34 +0100
changeset 162
b169992137a8
parent 161
aadda87bad1b
child 355
4a7dd7ff92c9
permissions
-rw-r--r--

improves cgi error handling and allows requests with empty headers

also fixes broken windows porting commit

1
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
1 /*
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
3 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
4 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
5 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
6 * THE BSD LICENSE
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
7 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
8 * Redistribution and use in source and binary forms, with or without
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
9 * modification, are permitted provided that the following conditions are met:
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
10 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
11 * Redistributions of source code must retain the above copyright notice, this
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
12 * list of conditions and the following disclaimer.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
13 * Redistributions in binary form must reproduce the above copyright notice,
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
14 * this list of conditions and the following disclaimer in the documentation
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
15 * and/or other materials provided with the distribution.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
16 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
17 * Neither the name of the nor the names of its contributors may be
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
18 * used to endorse or promote products derived from this software without
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
19 * specific prior written permission.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
20 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
25 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
26 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
27 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
28 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
30 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
31 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
32 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
33
162
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
34 #ifdef XP_WIN32
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
35 #define _MBCS
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
36 #include <windows.h>
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
37 #include <mbctype.h>
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
38 #endif
b169992137a8 improves cgi error handling and allows requests with empty headers
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 161
diff changeset
39
161
aadda87bad1b more windows porting
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 70
diff changeset
40 #include "util.h"
aadda87bad1b more windows porting
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 70
diff changeset
41 #include "pool.h"
aadda87bad1b more windows porting
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 70
diff changeset
42 //include "frame/conf_api.h"
aadda87bad1b more windows porting
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 70
diff changeset
43 //include "support/stringvalue.h"
aadda87bad1b more windows porting
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 70
diff changeset
44
1
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
45 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
46 static PRBool _getfullpathname = -1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
47 #endif /* XP_WIN32 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
48
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
49 /* --------------------------- util_uri_is_evil --------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
50
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
51 static inline int allow_dbcs_uri()
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
52 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
53 /*
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
54 static int flagDbcsUri = -1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
55 if (flagDbcsUri == -1) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
56 flagDbcsUri = StringValue::getBoolean(conf_findGlobal("DbcsUri"));
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
57 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
58 return flagDbcsUri;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
59 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
60 return PR_FALSE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
61 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
62
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
63 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
64 void set_fullpathname(PRBool b)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
65 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
66 _getfullpathname = b;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
67 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
68 #endif /*XP_WIN32*/
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
69
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
70 NSAPI_PUBLIC int util_uri_is_evil_internal(const char *t, int allow_tilde, int allow_dot_dir)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
71 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
72 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
73 int flagDbcsUri = allow_dbcs_uri();
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
74 #endif // XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
75 PRBool flagEmptySegment = PR_FALSE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
76 register int x;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
77
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
78 for (x = 0; t[x]; ++x) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
79 if (t[x] == '/') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
80 if (flagEmptySegment)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
81 return 1; // "/;a/b"
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
82 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
83 if (t[x+1] == '/' && x != 0)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
84 #else
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
85 if (t[x+1] == '/')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
86 #endif
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
87 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
88 if (t[x+1] == ';')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
89 flagEmptySegment = PR_TRUE; // "/;a/b" is evil, "/a/;b" is not
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
90 if (t[x+1] == '.') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
91 /* "." at end of line is always prohibited */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
92 if (t[x+2] == '\0')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
93 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
94
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
95 /* "." as a path segment is prohibited conditionally */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
96 if (!allow_dot_dir && (t[x+2] == '/' || t[x+2] == ';'))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
97 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
98
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
99 /* ".." as a path segment is always prohibited */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
100 if (t[x+2] == '.' && (t[x+3] == '/' || t[x+3] == ';' || t[x+3] == '\0'))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
101 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
102 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
103 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
104 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
105 // Don't allow '~' in the filename. On some filesystems a long name
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
106 // (e.g. longfilename.htm) can be accessed using '~' bypassing any ACL
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
107 // checks (e.g. longfi~1.htm).
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
108 if (!allow_tilde && (t[x] == '~')) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
109 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
110 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
111
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
112 // Do not allow ':' apart from drive letter. Windows filestream
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
113 // will treat filename::$DATA as a plain file & display content.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
114 // So block it to prevent source viewing vulnerability.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
115 if ((t[x] == ':') && x > 1) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
116 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
117 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
118
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
119 // On NT, the directory "abc...." is the same as "abc"
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
120 // The only cheap way to catch this globally is to disallow
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
121 // names with the trailing "."s. Hopefully this is not over
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
122 // restrictive.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
123 // Also trailing spaces in names can wreak havoc on ACL checks
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
124 // and name resolution. Therefore, ban them on the end of a
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
125 // name.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
126 if (((t[x] == '.') || (t[x] == ' ')) &&
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
127 ((t[x+1] == ';') || (t[x+1] == '/') || (t[x+1] == '\0')))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
128 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
129 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
130 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
131
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
132 // Skip past the second byte of two byte DBCS characters. Bug 353999
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
133 if (flagDbcsUri && t[x+1] && IsDBCSLeadByte(t[x])) x++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
134 #endif // XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
135 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
136 return 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
137 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
138
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
139 NSAPI_PUBLIC int util_uri_is_evil(const char *t)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
140 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
141 return util_uri_is_evil_internal(t, 0, 0);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
142 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
143
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
144
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
145 /* -------------------- util_uri_unescape_and_normalize -------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
146
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
147 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
148 /* The server calls this function to unescape the URI and also normalize
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
149 * the uri. Normalizing the uri converts all "\" characters in the URI
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
150 * and pathinfo portion to "/". Does not touch "\" in query strings.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
151 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
152 NSAPI_PUBLIC
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
153 int util_uri_unescape_and_normalize(pool_handle_t *pool, char *s, char *unnormalized)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
154 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
155 if(!(util_uri_unescape_strict(s)))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
156 return 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
157
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
158 if (unnormalized) strcpy(unnormalized, s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
159
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
160 if (_getfullpathname == -1)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
161 _getfullpathname = (_getmbcp() != 0);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
162
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
163 /* Get canonical filename Bugid: 4672869 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
164 if(_getfullpathname && strcmp(s, "*") && (*s == '/' ) ) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
165 char *pzAbsPath = NULL;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
166 int pathlen = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
167 int len = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
168 int ret = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
169 if(!(pzAbsPath = util_canonicalize_uri(pool, s, strlen(s), NULL))) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
170 //Error canonicalizing; possibly pointing out of docroot
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
171 return 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
172 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
173 char *pzPath = (char *)MALLOC(MAX_PATH + 1); /* reserved byte for trailing slash */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
174 char *pzFilename = NULL;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
175
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
176 /* If required length of the buffer(pzPath) is more than the allocated one i.e. MAX_PATH(neglecting the reserved byte for trailing slash), return BAD REQUEST. This will happen if length of uri is more than the specified uri length(257) for MBCS windows */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
177 if(!(ret = GetFullPathName(pzAbsPath, MAX_PATH, pzPath, &pzFilename)) || ( ret > MAX_PATH)){
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
178 FREE(pzAbsPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
179 FREE(pzPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
180 return 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
181 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
182 len = strlen(pzAbsPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
183 pathlen = strlen( pzPath );
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
184
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
185 /* GetFullPathName behaves differently in case of WINNT and WIN2K */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
186 /* o/p string doesn't contain the trailing slash in case of WINNT */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
187 /* if i/p is /foo/, we get o/p as c:\foo instead of c:\foo\ */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
188 /* Checking if i/p has trailing slash and o/p doesn't have, then */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
189 /* adding slash */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
190 if ( pzAbsPath[len-1] == '/' && pzPath[pathlen-1] != '\\')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
191 strcat( pzPath, "\\");
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
192 FREE(pzAbsPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
193 pzFilename = strchr(pzPath, '\\');
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
194 if(!pzFilename) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
195 FREE(pzPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
196 return 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
197 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
198 strcpy(s, pzFilename);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
199 FREE(pzPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
200 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
201
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
202 util_uri_normalize_slashes(s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
203
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
204 return 1;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
205 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
206 #endif /* XP_WIN32 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
207
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
208
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
209 /* ---------------------- util_uri_normalize_slashes ---------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
210
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
211 void util_uri_normalize_slashes(char *s)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
212 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
213 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
214 int flagDbcsUri = allow_dbcs_uri();
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
215
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
216 while (*s) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
217 if (*s == '\\') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
218 // Normalize '\\' to '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
219 *s = '/';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
220 } else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0])) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
221 // Skip past two byte DBCS characters. Bug 353999
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
222 s++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
223 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
224 s++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
225 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
226 #endif
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
227 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
228
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
229
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
230 /* --------------------------- util_uri_escape ---------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
231 /*
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
232 NSAPI_PUBLIC char *util_uri_escape(char *od, const char *s)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
233 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
234 int flagDbcsUri = allow_dbcs_uri();
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
235 char *d;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
236
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
237 if (!od)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
238 od = (char *) MALLOC((strlen(s)*3) + 1);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
239 d = od;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
240
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
241 while (*s) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
242 if (strchr("% ?#:+&*\"'<>\r\n", *s)) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
243 util_sprintf(d, "%%%02x", (unsigned char)*s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
244 ++s; d += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
245 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
246 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
247 else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
248 #else
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
249 // Treat any character with the high bit set as a DBCS lead byte
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
250 else if (flagDbcsUri && s[1] && (s[0] & 0x80))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
251 #endif
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
252 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
253 // Escape the second byte of DBCS characters. The first byte will
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
254 // have been escaped already. IE translates all unescaped '\\'s
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
255 // into '/'.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
256 // Bug 353999
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
257 util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
258 s += 2; d += 6;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
259 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
260 else if (0x80 & *s) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
261 util_sprintf(d, "%%%02x", (unsigned char)*s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
262 ++s; d += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
263 } else {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
264 *d++ = *s++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
265 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
266 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
267 *d = '\0';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
268 return od;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
269 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
270 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
271
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
272
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
273 /* --------------------------- util_url_escape ---------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
274 /*
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
275 NSAPI_PUBLIC char *util_url_escape(char *od, const char *s)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
276 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
277 int flagDbcsUri = allow_dbcs_uri();
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
278 char *d;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
279
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
280 if (!od)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
281 od = (char *) MALLOC((strlen(s)*3) + 1);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
282 d = od;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
283
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
284 while (*s) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
285 if (strchr("% +*\"'<>\r\n", *s)) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
286 util_sprintf(d, "%%%02x", (unsigned char)*s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
287 ++s; d += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
288 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
289 #ifdef XP_WIN32
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
290 else if (flagDbcsUri && s[1] && IsDBCSLeadByte(s[0]))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
291 #else
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
292 // Treat any character with the high bit set as a DBCS lead byte
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
293 else if (flagDbcsUri && s[1] && (s[0] & 0x80))
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
294 #endif
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
295 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
296 // Escape the second byte of DBCS characters. The first byte will
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
297 // have been escaped already. IE translates all unescaped '\\'s
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
298 // into '/'.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
299 // Bug 353999
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
300 util_sprintf(d, "%%%02x%%%02x", (unsigned char)s[0], (unsigned char)s[1]);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
301 s += 2; d += 6;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
302 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
303 else if (0x80 & *s) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
304 util_sprintf(d, "%%%02x", (unsigned char)*s);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
305 ++s; d += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
306 } else {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
307 *d++ = *s++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
308 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
309 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
310 *d = '\0';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
311 return od;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
312 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
313 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
314
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
315 /* ------------------------- util_uri_strip_params ------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
316
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
317 NSAPI_PUBLIC char* util_uri_strip_params(char *uri)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
318 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
319 // As per RFC2396, URI path segments can contain parameters beginning with
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
320 // ';'. These parameters must be removed from the ppath. Bug 418271
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
321 char* out;
70
4e6e812c1d97 fixed some warnings
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 24
diff changeset
322 if((out = strchr(uri, ';'))) {
1
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
323 char* in = out;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
324 while (*in) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
325 if (*in == ';') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
326 // Skip past parameter
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
327 do in++; while (*in && *in != '/');
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
328 } else {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
329 // Copy non-parameter path data
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
330 *out++ = *in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
331 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
332 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
333 *out = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
334 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
335 return uri;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
336 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
337
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
338
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
339 /* ------------------------ util_canonicalize_uri ------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
340
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
341 /*
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
342 * rewrite rules:
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
343 * // -> '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
344 * /./ -> '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
345 * /.\0 -> '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
346 * /foo/../ -> '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
347 * /foo/..\0 -> '/'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
348 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
349 * Allocate a new string, as otherwise replacing in-line would impact the
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
350 * RequestURI, i.e. original URI in the request.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
351 * Some guidelines in: http://www.ietf.org/rfc/rfc2396.txt
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
352 * Uniform Resource Identifiers (URI): Generic Syntax
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
353 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
354 NSAPI_PUBLIC char* util_canonicalize_uri(pool_handle_t *pool, const char *uri, int len, int *pcanonlen)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
355 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
356 PRBool success = PR_TRUE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
357 const char *in_ptr = uri;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
358 int in = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
359 int in_len = len;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
360
24
1a7853a4257e removed some NSPR dependencies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 14
diff changeset
361 //PR_ASSERT(uri != NULL); // TODO
1
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
362
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
363 char* canonPath = (char *)pool_malloc(pool, in_len+1);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
364 char* out_ptr = canonPath;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
365
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
366 if (!canonPath) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
367 success = PR_FALSE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
368 goto done;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
369 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
370
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
371
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
372 /* in goes from 0 .. sURIPath.len-1; out_ptr points to
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
373 * space where next char from input would be copied to
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
374 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
375 while (in < in_len) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
376
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
377 /* If the character isn't '/' then copy it out and move on*/
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
378 if (in_ptr[0] != '/') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
379 *out_ptr++ = *in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
380 in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
381 continue;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
382 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
383
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
384 /* found '/' and reached end of sURIPath, done */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
385 if (in+1 >= in_len) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
386 *out_ptr++ = *in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
387 in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
388 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
389 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
390
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
391 /* we have '/' and there are more chars in the string */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
392 switch(in_ptr[1]) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
393 case '/':
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
394 /* '//' => '/' */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
395 in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
396 in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
397 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
398
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
399 case '.':
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
400 /* we have "/." so far */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
401 if (in+2 >= in_len) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
402 /* the string ends after this; basically ignore '.'
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
403 * make sure the ending / is transferred to output.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
404 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
405 *out_ptr++ = *in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
406 goto done;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
407 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
408
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
409 /* more chars after "/."; see if it is a '/' */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
410 if (in_ptr[2] == '/') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
411 /* in deed, compact "/./" => "/"; */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
412 in_ptr += 2;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
413 in += 2;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
414 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
415 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
416
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
417 if (in_ptr[2] != '.') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
418 /* "/.x" where x is not '.'; copy as is */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
419 *out_ptr++ = *in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
420 in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
421 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
422 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
423
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
424 /* we have "/.." so far. see if we have either string
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
425 * ending after this or '/' following.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
426 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
427 if (in+3 < in_len && in_ptr[3] != '/' && in_ptr[3] != ';') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
428 /* we have "/..x" here; so copy as is */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
429 *out_ptr++ = *in_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
430 in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
431 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
432 else {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
433 /* we have "foo/../" or "foo/.." at the end; */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
434 if (out_ptr == canonPath) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
435 /* oops, we found "/../" pointing out of docroot */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
436 success = PR_FALSE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
437 goto done;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
438 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
439
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
440 /* remove the previous segment in the output */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
441 for (out_ptr--;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
442 out_ptr != canonPath && out_ptr[0] != '/';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
443 out_ptr--); /* Empty Loop */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
444
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
445 /* point to '/' if the last segment ended with .. then
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
446 * leave the '/' before the previous segment.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
447 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
448 if(in+3 == in_len)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
449 out_ptr++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
450
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
451 /* skip the input as well */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
452 in_ptr += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
453 in += 3;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
454 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
455 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
456
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
457 default:
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
458 /* If we already have '/' at out_ptr we donot need to copy */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
459 if (out_ptr == canonPath || *(out_ptr-1) != '/')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
460 *out_ptr++ = *in_ptr;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
461 in_ptr++; in++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
462 break;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
463 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
464 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
465
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
466 done:
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
467 int canonLen = 0;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
468
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
469 if (success) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
470 /* the path looks fine; return the canonicalized form */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
471 canonLen = out_ptr - canonPath;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
472 canonPath[canonLen] = '\0';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
473 } else {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
474 /* error canonicalizing */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
475 pool_free(pool, canonPath);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
476 canonPath = NULL;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
477 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
478
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
479 if (pcanonlen)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
480 *pcanonlen = canonLen;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
481
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
482 return canonPath;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
483 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
484
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
485
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
486 /* ---------------------- util_canonicalize_redirect ---------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
487
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
488 NSAPI_PUBLIC char* util_canonicalize_redirect(pool_handle_t *pool, const char *baseUri, const char *newUri)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
489 {
24
1a7853a4257e removed some NSPR dependencies
Olaf Wintermann <olaf.wintermann@gmail.com>
parents: 14
diff changeset
490 //PR_ASSERT(baseUri != NULL); // TODO
1
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
491
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
492 if (*newUri == '/')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
493 return util_canonicalize_uri(pool, newUri, strlen(newUri), NULL);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
494
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
495 int bLen = strlen(baseUri);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
496 if (bLen > 0 && baseUri[bLen - 1] != '/') {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
497 while (bLen > 0 && baseUri[bLen - 1] != '/')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
498 bLen--;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
499 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
500
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
501 int pLen = strlen(newUri) + bLen + 1; // 1 for slash
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
502 char *pUri = (char *)pool_malloc(pool, pLen + 1);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
503 if (!pUri)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
504 return PR_FALSE;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
505
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
506 memcpy(pUri, baseUri, bLen);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
507 pUri[bLen] = '/';
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
508 strcpy(pUri + bLen + 1, newUri);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
509
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
510 char *rval = util_canonicalize_uri(pool, pUri, pLen, NULL);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
511 pool_free(pool, pUri);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
512
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
513 return rval;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
514 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
515
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
516
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
517 /* ------------------------ util_host_port_suffix ------------------------- */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
518
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
519 NSAPI_PUBLIC char *util_host_port_suffix(char *h)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
520 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
521 return (char *)util_host_port_suffix((const char *)h);
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
522 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
523
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
524 const char *util_host_port_suffix(const char *h)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
525 {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
526 /* Return a pointer to the colon preceding the port number in a hostname.
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
527 *
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
528 * util_host_port_suffix("foo.com:80") = ":80"
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
529 * util_host_port_suffix("foo.com") = NULL
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
530 * util_host_port_suffix("[::]:80") = ":80"
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
531 * util_host_port_suffix("[::]") = NULL
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
532 */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
533
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
534 if (h == NULL)
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
535 return h;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
536
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
537 for (;;) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
538 /* Find end of host, beginning of ":port", or an IPv6 address */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
539 for (;;) {
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
540 register char c = *h;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
541
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
542 if (c == '\0')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
543 return NULL; /* end of host, no port found */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
544
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
545 if (c == '/')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
546 return NULL; /* end of host, no port found */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
547
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
548 if (c == ':')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
549 return h; /* found port */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
550
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
551 if (c == '[')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
552 break; /* skip IPv6 address */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
553
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
554 h++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
555 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
556
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
557 /* Skip IPv6 address */
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
558 while (*h != '\0' && *h != ']')
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
559 h++;
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
560 }
3c066d52342d added source
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff changeset
561 }

mercurial