2018-08-05 23:04:34 +00:00
|
|
|
#pragma noroot
|
|
|
|
|
2018-07-31 02:35:45 +00:00
|
|
|
#include <types.h>
|
|
|
|
#include <errno.h>
|
2018-08-01 23:24:43 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
2018-07-31 02:35:45 +00:00
|
|
|
#include "session.h"
|
|
|
|
#include "urlparser.h"
|
|
|
|
#include "strcasecmp.h"
|
|
|
|
#include "hostname.h"
|
|
|
|
#include "http.h"
|
|
|
|
#include "tcpconnection.h"
|
|
|
|
#include "seturl.h"
|
|
|
|
|
|
|
|
#define DEFAULT_HTTP_PORT 80
|
|
|
|
|
|
|
|
/* Limit to make sure sizes stay within the range of 16-bit values */
|
|
|
|
#define MAX_URL_LENGTH 30000
|
|
|
|
|
|
|
|
|
|
|
|
enum SetURLResult
|
|
|
|
SetURL(Session *sess, char *url, Boolean permissive, Boolean partialOK) {
|
|
|
|
if (strlen(url) > MAX_URL_LENGTH) {
|
|
|
|
return URL_TOO_LONG;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(unsigned int i = 0; url[i] != '\0'; i++) {
|
2018-08-01 05:05:19 +00:00
|
|
|
if ((unsigned char)url[i] <= ' ') {
|
2018-07-31 02:35:45 +00:00
|
|
|
return INVALID_CHARACTER_IN_URL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
URLParts urlParts = ParseURL(url);
|
|
|
|
|
|
|
|
if (urlParts.errorFound)
|
|
|
|
return BAD_URL_SYNTAX;
|
|
|
|
|
|
|
|
if (urlParts.scheme == NULL) {
|
|
|
|
if (permissive) {
|
|
|
|
urlParts.scheme = "http";
|
|
|
|
} else {
|
|
|
|
return BAD_URL_SYNTAX;
|
|
|
|
}
|
|
|
|
} else if (strcasecmp(urlParts.scheme, "http") != 0) {
|
|
|
|
return UNSUPPORTED_URL_SCHEME;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (urlParts.username != NULL || urlParts.password != NULL) {
|
|
|
|
return AUTHENTICATION_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (urlParts.fragment != NULL) {
|
|
|
|
return FRAGMENT_NOT_SUPPORTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned long portNum;
|
|
|
|
char *endPtr;
|
|
|
|
if (urlParts.port == NULL || *urlParts.port == '\0') {
|
|
|
|
portNum = DEFAULT_HTTP_PORT;
|
|
|
|
} else {
|
|
|
|
errno = 0;
|
|
|
|
portNum = strtoul(urlParts.port, &endPtr, 10);
|
|
|
|
if (errno || *endPtr != '\0' || portNum > 0xFFFF) {
|
|
|
|
return INVALID_PORT_NUMBER;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sess->port = portNum;
|
|
|
|
|
|
|
|
if (urlParts.host == NULL) {
|
|
|
|
if (!partialOK || sess->hostName[0] == 0) {
|
|
|
|
return NO_HOST_SPECIFIED;
|
|
|
|
}
|
|
|
|
} else if (*urlParts.host == '\0') {
|
|
|
|
return NO_HOST_SPECIFIED;
|
|
|
|
} else if (*urlParts.host == '[') {
|
|
|
|
return IPV6_NOT_SUPPORTED;
|
|
|
|
} else {
|
|
|
|
size_t len;
|
|
|
|
if ((len = strlen(urlParts.host)) > 255) {
|
|
|
|
return HOSTNAME_TOO_LONG;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(&sess->hostName[1], urlParts.host);
|
|
|
|
sess->hostName[0] = len;
|
|
|
|
|
|
|
|
if (!DoLookupName(sess)) {
|
|
|
|
return NAME_LOOKUP_FAILED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!BuildHTTPRequest(sess, urlParts.path)) {
|
|
|
|
return OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* End any existing TCP connection to old URL */
|
|
|
|
EndTCPConnection(sess);
|
|
|
|
|
|
|
|
return SETURL_SUCCESSFUL;
|
|
|
|
}
|