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