diff --git a/source/cheats.c b/source/cheats.c index 1bafa52..d4bc096 100644 --- a/source/cheats.c +++ b/source/cheats.c @@ -367,17 +367,17 @@ bool Download_Cheats_TXT(char *id) //snprintf(D_S(url), "%s/%c/%.6s.txt", url_base, id[0], id); snprintf(D_S(url), "%s/R/%.6s.txt", url_base, id); dbg_printf("url: %s\n", url); - file = downloadfile(url); + file = downloadfile_noreferer(url); if (file.data == NULL || file.size == 0) { snprintf(D_S(url), "%s/G/%.6s.txt", url_base, id); dbg_printf("url: %s\n", url); - file = downloadfile(url); + file = downloadfile_noreferer(url); if (file.data == NULL || file.size == 0) { // 4 letters ID snprintf(D_S(url), "%s/%c/%.4s.txt", url_base, id[0], id); dbg_printf("url: %s\n", url); - file = downloadfile(url); + file = downloadfile_noreferer(url); if (file.data == NULL || file.size == 0) { printf_(gt("Error downloading.")); printf("\n"); diff --git a/source/http.c b/source/http.c index e06f031..69dd5a1 100644 --- a/source/http.c +++ b/source/http.c @@ -266,13 +266,141 @@ struct block downloadfile_fname(const char *url, const char *fname) //Form a nice request header to send to the webserver extern char CFG_VERSION[]; -//referer removed for compatability with geckocodes.org if it causes problems make it conditional -// char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nReferer: %s\r\nUser-Agent: CFG-Loader %s\r\n\r\n"; -// char header[strlen(headerformat) + strlen(domain) + strlen(path) + strlen(domain) + strlen(CFG_VERSION) + 16]; -// sprintf(header, headerformat, path, domain, domain, CFG_VERSION); - char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: CFG-Loader %s\r\n\r\n"; - char header[strlen(headerformat) + strlen(path) + strlen(domain) + strlen(CFG_VERSION) + 16]; - sprintf(header, headerformat, path, domain, CFG_VERSION); + char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nReferer: %s\r\nUser-Agent: CFG-Loader %s\r\n\r\n"; + char header[strlen(headerformat) + strlen(domain) + strlen(path) + strlen(domain) + strlen(CFG_VERSION) + 16]; + sprintf(header, headerformat, path, domain, domain, CFG_VERSION); + + //Do the request and get the response + send_message(connection, header); + struct block response = read_message(connection, fname); + net_close(connection); + + // Check response status. Should be something like HTTP/1.1 200 OK + if (response.size > 10 && strncmp((char*)response.data, "HTTP/", 5)==0) { + char htstat[100]; + int i; + for (i=0; i<100 && i= 400) { + printf("%s: %s", gt("ERROR"), htstat); + if (!http_progress) printf("\n"); + SAFE_FREE(response.data); + return emptyblock; + } + } + } + break; + } + } + } + + if (fname != NULL) { + return response; + } + // Search for the 4-character sequence \r\n\r\n in the response + // which signals the start of the http payload (file) + unsigned char *filestart = NULL; + u32 filesize = 0; + int i; + if (response.size > 3) //need at least the 4 chars we are trying to match + for(i = 0; i < response.size-3; i++) + { + if (memcmp(response.data+i, "\r\n\r\n", 4) == 0) { + filestart = response.data + i + 4; + filesize = response.size - i - 4; + break; + } + } + + if(filestart == NULL) + { + printf(gt("HTTP Response was without a file")); + printf("\n"); + SAFE_FREE(response.data); + return emptyblock; + } + + // move file part of the response into the start of the block + memmove(response.data, filestart, filesize); + // free extra memory + response.data = mem_realloc(response.data, filesize); + response.size = filesize; + + return response; +} + +struct block downloadfile_noreferer(const char *url) { + return downloadfile_noreferer_fname(url, NULL); +} + +struct block downloadfile_noreferer_fname(const char *url, const char *fname) +{ + //Check if the url starts with "http://", if not it is not considered a valid url + if(strncmp(url, "http://", strlen("http://")) != 0) + { + printf(gt("URL '%s' doesn't start with 'http://'"), url); + printf("\n"); + return emptyblock; + } + + //Locate the path part of the url by searching for '/' past "http://" + char *path = strchr(url + strlen("http://"), '/'); + + //At the very least the url has to end with '/', ending with just a domain is invalid + if(path == NULL) + { + printf(gt("URL '%s' has no PATH part"), url); + printf("\n"); + return emptyblock; + } + + //Extract the domain part out of the url + int domainlength = path - url - strlen("http://"); + + if(domainlength == 0) + { + printf(gt("No domain part in URL '%s'"), url); + printf("\n"); + return emptyblock; + } + + char domain[domainlength + 1]; + strncpy(domain, url + strlen("http://"), domainlength); + domain[domainlength] = '\0'; + + //Parsing of the URL is done, start making an actual connection + u32 ipaddress = getipbynamecached(domain); + + if(ipaddress == 0) + { + printf("\n"); + printf(gt("domain %s could not be resolved"), domain); + return emptyblock; + } + + + s32 connection = server_connect(ipaddress, 80); + + if(connection < 0) { + printf(gt("Error establishing connection")); + return emptyblock; + } + + //Form a nice request header to send to the webserver + extern char CFG_VERSION[]; + char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: libcurl-agent/1.0\r\n\r\n"; + char header[strlen(headerformat) + strlen(domain) + strlen(path) + 16]; + sprintf(header, headerformat, path, domain); //Do the request and get the response send_message(connection, header); diff --git a/source/http.h b/source/http.h index 2a48475..93cf3af 100644 --- a/source/http.h +++ b/source/http.h @@ -26,8 +26,10 @@ struct block extern const struct block emptyblock; struct block downloadfile(const char *url); +struct block downloadfile_noreferer(const char *url); struct block downloadfile_progress(const char *url, int size); struct block downloadfile_fname(const char *url, const char *fname); +struct block downloadfile_noreferer_fname(const char *url, const char *fname); struct block downloadfile_progress_fname(const char *url, int size, const char *fname); #endif /* _HTTP_H_ */