src/server/util/util.c

changeset 693
b26cae13b79a
parent 660
f00d03835dd9
equal deleted inserted replaced
692:32faa1d6a744 693:b26cae13b79a
1171 return 0; 1171 return 0;
1172 ++t; 1172 ++t;
1173 } 1173 }
1174 return 0; 1174 return 0;
1175 } 1175 }
1176
1177 /* -------------------------- util_parse_http_uri -------------------------- */
1178
1179 NSAPI_PUBLIC int util_parse_uri(const char *uri, WSUri *result) {
1180 if(!uri) {
1181 return 0;
1182 }
1183 return util_parse_uri_len(uri, strlen(uri), result);
1184 }
1185
1186 NSAPI_PUBLIC int util_parse_uri_len(const char *uri, size_t length, WSUri *result) {
1187 if(length == 0) {
1188 return 0;
1189 }
1190
1191 memset(result, 0, sizeof(WSUri));
1192
1193 // get uri scheme
1194 int scheme = -1;
1195 const char *scheme_str = uri;
1196 size_t scheme_len = length;
1197 short port = 0;
1198 size_t i = 0;
1199 for(;i<length;i++) {
1200 if(uri[i] == ':') {
1201 if(i+3 < length && uri[i+1] == '/' && uri[i+2] == '/') {
1202 cxstring scheme_s = cx_strn(uri, i);
1203 scheme_len = i;
1204 if(!cx_strcmp(scheme_s, "http")) {
1205 scheme = WS_URI_HTTP;
1206 port = 80;
1207 } else if(!cx_strcmp(scheme_s, "https")) {
1208 scheme = WS_URI_HTTPS;
1209 port = 443;
1210 } else {
1211 scheme = WS_URI_OTHER;
1212 }
1213 i += 3;
1214 break;
1215 } else {
1216 return 0; // invalid uri
1217 }
1218 }
1219 }
1220 result->scheme_num = scheme;
1221 result->scheme = scheme_str;
1222 result->schemelen = scheme_len;
1223
1224 if(i == length) {
1225 return 0; // invlid uri
1226 }
1227
1228 // get host
1229 size_t hostlen = 0;
1230 const char *port_str = NULL;
1231 const char *path = NULL;
1232 int is_ipv6_addr = 0;
1233 size_t host_start = i;
1234 if(uri[i] == '[') {
1235 host_start++;
1236 is_ipv6_addr = 1;
1237 i++;
1238 }
1239 for(;i<length;i++) {
1240 char c = uri[i];
1241 if(is_ipv6_addr) {
1242 if(c == ']') {
1243 // end of ipv6 address
1244 result->host = uri + host_start;
1245 result->hostlen = i - host_start;
1246 is_ipv6_addr = 0;
1247
1248 // the next character must be a port or path separator
1249 if(i+1 < length) {
1250 c = uri[i+1];
1251 if(c != '/' && c != ':') {
1252 return 0; // invalid uri
1253 }
1254 }
1255 } else if(c != ':' && c != '.' && c != '%' && !isalnum(c)) {
1256 return 0; // invalid ipv6 address
1257 }
1258 } else if(c == ':') {
1259 if(port_str) {
1260 return 0; // error: port was already specified
1261 }
1262 if(!result->host) {
1263 result->host = uri + host_start;
1264 result->hostlen = i - host_start;
1265 }
1266 // get port
1267 port_str = uri + i + 1;
1268 } else if(c == '/') {
1269 path = uri + i;
1270 break;
1271 } else if(c == '[' || c == ']') {
1272 return 0; // invalid hostname
1273 }
1274 }
1275 if(is_ipv6_addr) {
1276 return 0; // ipv6 address was not terminated
1277 }
1278
1279 if(port_str) {
1280 size_t port_len = uri + i - port_str;
1281 cxstring port_s = cx_strn(port_str, port_len);
1282 if(cx_strtos(port_s, &port, 10)) {
1283 return 0; // invalid port
1284 }
1285 }
1286 if(!result->host) {
1287 result->host = uri + host_start;
1288 result->hostlen = i - host_start;
1289 }
1290 if(result->hostlen == 0) {
1291 return 0;
1292 }
1293
1294 size_t pathlen = 0;
1295 if(path) {
1296 pathlen = uri + length - path;
1297 }
1298
1299 result->path = path;
1300 result->pathlen = pathlen;
1301 result->port = port;
1302
1303 return 1;
1304 }

mercurial