Ejemplo n.º 1
0
/****************************************************************************
 * Test if connection to the address is available (PING)
 ***************************************************************************/
bool CheckConnection(const char *url, float timeout)
{
	//Check if the url starts with "http://", if not it is not considered a valid url
	if (strncmp(url, "http://", strlen("http://")) != 0)
		return false;

	//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)
		return false;

	//Extract the domain part out of the url
	int domainlength = path - url - strlen("http://");
	if (domainlength == 0)
		return false;

	char domain[domainlength + 1];
	strlcpy(domain, url + strlen("http://"), domainlength + 1);

	//Parsing of the URL is done, start making an actual connection
	u32 ipaddress = getipbynamecached(domain);
	if (ipaddress == 0)
		return false;

	//Initialize socket
	s32 connection = net_socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
	if (connection < 0) return connection;

	s32 flags = net_fcntl(connection, F_GETFL, 0);
	if (flags >= 0) flags = net_fcntl(connection, F_SETFL, flags | 4);

	struct sockaddr_in connect_addr;
	memset(&connect_addr, 0, sizeof(connect_addr));
	connect_addr.sin_family = AF_INET;
	connect_addr.sin_port = 80;
	connect_addr.sin_addr.s_addr = getipbynamecached(domain);

	Timer netTime;

	int res = -1;
	while(res < 0 && res != -127 && netTime.elapsed() < timeout)
	{
		res = net_connect(connection, (struct sockaddr*) &connect_addr, sizeof(connect_addr));
		usleep(1000);
	}

	net_close(connection);

	return !(res < 0 && res != -127);
}
Ejemplo n.º 2
0
s32 GetConnection(char * domain) {

    u32 ipaddress = getipbynamecached(domain);
    if(ipaddress == 0) {
        return -1;
    }
    s32 connection = server_connect(ipaddress, 80);
    return connection;

}
Ejemplo n.º 3
0
/**
 * Downloads the contents of a URL to memory
 * This method is not threadsafe (because networking is not threadsafe on the Wii)
 */
u8 *downloadfile (const char *url, u32 *size, http_Callback cb)
	{
	*size = 0;
	u8 *buff = NULL;
	
	memset (&http, 0, sizeof(s_http));

	http.cb = cb;
	
	//Check if the url starts with "http://", if not it is not considered a valid url
	if (strncmp(url, "http://", strlen("http://")) != 0)
		{
		//printf("URL '%s' doesn't start with 'http://'\n", url);
		return NULL;
		}

	//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("URL '%s' has no PATH part\n", url);
		return NULL;
		}

	//Extract the domain part out of the url
	int domainlength = path - url - strlen("http://");

	if (domainlength == 0)
		{
		//printf("No domain part in URL '%s'\n", url);
		return NULL;
		}

	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("\ndomain %s could not be resolved", domain);
		return NULL;
		}

	Debug ("downloadfile:connecting");
	s32 connection = server_connect(ipaddress, 80);

	if(connection < 0) {
		//printf("Error establishing connection");
		return NULL;
	}
	
	Debug ("downloadfile:success");

	//Form a nice request header to send to the webserver
	char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nReferer: %s\r\nUser-Agent: postLoader2\r\n\r\n";
	char header[strlen(headerformat) + strlen(path) + strlen(domain)*2 + 1];
	sprintf(header, headerformat, path, domain, domain);

	//Do the request and get the response
	send_message(connection, header);
	buff = read_message(connection, size);
	net_close(connection);

	//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;
	unsigned int i;
	for(i = 3; i < *size; i++)
	{
		if(buff[i] == '\n' &&
			buff[i-1] == '\r' &&
			buff[i-2] == '\n' &&
			buff[i-3] == '\r')
		{
			filestart = buff + i + 1;
			filesize = *size - i - 1;
			break;
		}
	}

	if(filestart == NULL)
	{
		//printf("HTTP Response was without a file\n");
		free(buff);
		return NULL;
	}

	//Copy the file part of the response into a new memoryblock to return
	u8 *file = malloc(filesize);

	if(file == NULL)
	{
		//printf("No more memory to copy file from HTTP response\n");
		free(buff);
		return NULL;
	}

	memcpy(file, filestart, filesize);

	//Dispose of the original response
	free(buff);

	*size = filesize;
	return file;
}
Ejemplo n.º 4
0
/* Downloads the contents of a URL to memory
 * This method is not threadsafe (because networking is not threadsafe on the Wii) */
struct block downloadfile(u8 *buffer, u32 bufferSize, const char *url, bool (*f)(void *, int, int), void *ud)
{
	//Check if the url starts with "http://", if not it is not considered a valid url
	if(strncmp(url, "http://", strlen("http://")) != 0) return emptyblock;
	
	//Locate the path part of the url by searching for '/' past "http://"
	char *path = strchr(url + strlen("http://"), '/');
	if(path == NULL) return emptyblock;
	
	//Extract the domain part out of the url
	int domainlength = path - url - strlen("http://");
	if(domainlength == 0) 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) return emptyblock;

	s32 connection = server_connect(ipaddress, 80);
	if(connection < 0) return emptyblock;
	
	//Form a nice request header to send to the webserver
	char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: Wiiflow Advanced 3.0\r\n\r\n";;
	char header[strlen(headerformat) + strlen(domain) + strlen(path)];
	sprintf(header, headerformat, path, domain);

	//Do the request and get the response
	send_message(connection, header);
	if (bufferSize == 0) return emptyblock;
	struct block buf;
	buf.data = buffer;
	buf.size = bufferSize;
	struct block response = read_message(connection, buf, f, ud);
	net_close(connection);

	//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;
	u32 i;
	for(i = 3; i < response.size; i++)
	{
		if(response.data[i] == '\n' &&
			response.data[i-1] == '\r' &&
			response.data[i-2] == '\n' &&
			response.data[i-3] == '\r')
		{
			filestart = response.data + i + 1;
			filesize = response.size - i - 1;
			break;
		}
	}
	
	if(response.size == 0 || response.data == NULL) return emptyblock;
	
	// Check for the headers
	char httpCode[3];
	memcpy(httpCode, &response.data[9], 3);
	int retCode = atoi(httpCode);

	switch(retCode)
	{
		case 301:
		case 302:
		case 307: // Moved
/*
			{
			char redirectedTo[255];
			if(findHeader((char *) response.data, (filestart - response.data), "Location", redirectedTo, 255) == 0) {
				return downloadfile(buffer, bufferSize, (char *) redirectedTo, f, ud);
			}
			return emptyblock;
			break;
		}
*/		
		case 404: // Error, file not found!
			return emptyblock;
	}
	
	if(filestart == NULL) return emptyblock;
	
	//Copy the file part of the response into a new memoryblock to return
	struct block file;
	file.data = filestart;
	file.size = filesize;
	return file;
}
Ejemplo n.º 5
0
struct block downloadfile_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\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<response.size; i++) {
			if (response.data[i] == '\n' || response.data[i] == '\r') {
				strncpy(htstat, (char*)response.data, i);
				htstat[i] = 0;
				//printf("HTTP response status: %s\n", htstat);
				char *codep;
				codep = strchr(htstat, ' ');
				if (codep) {
					int code;
					if (sscanf(codep+1, "%d", &code) == 1) {
						//printf("HTTP response code: %d\n", code);
						//if (code != 200) {
						if (code >= 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;
	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;
}
Ejemplo n.º 6
0
/**
 * Downloads the contents of a URL to memory
 * This method is not threadsafe (because networking is not threadsafe on the Wii)
 */
struct block downloadfile(const char *url)
{
	int sslcontext = -1;

	//Check if the url starts with "http://", if not it is not considered a valid url
	if (strncmp(url, "http://", strlen("http://")) == 0)
		http_port = 80;
	else if(strncmp(url, "https://", strlen("https://")) == 0)
	{
		http_port = 443;
		gprintf("Initializing ssl...\n");
		if(ssl_init() < 0)
			return emptyblock;
	}
	else
		return emptyblock;

	//Locate the path part of the url by searching for '/' past "http://"
	char *path = 0;
	if(http_port == 443)
		path = strchr(url + strlen("https://"), '/');
	else
		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("URL '%s' has no PATH part\n", url);
		return emptyblock;
	}

	//Extract the domain part out of the url
	int domainlength = path - url - strlen("http://") - (http_port == 443 ? 1 : 0);

	if (domainlength == 0)
	{
		//printf("No domain part in URL '%s'\n", url);
		return emptyblock;
	}

	char domain[domainlength + 1];
	strlcpy(domain, url + strlen("http://") + (http_port == 443 ? 1 : 0), domainlength + 1);

	//Parsing of the URL is done, start making an actual connection
	u32 ipaddress = getipbynamecached(domain);

	if (ipaddress == 0)
	{
		//printf("\ndomain %s could not be resolved", domain);
		return emptyblock;
	}

	s32 connection = tcp_connect(ipaddress, http_port);

	if (connection < 0)
	{
		//printf("Error establishing connection");
		return emptyblock;
	}

	if(http_port == 443)
	{
		//patched out anyways so just to set something
		sslcontext = ssl_new((u8*)domain,0);

		if(sslcontext < 0)
		{
			//gprintf("ssl_new\n");
			result = HTTPR_ERR_CONNECT;
			net_close (connection);
			return emptyblock;
		}
		//patched out anyways so just to set something
		ssl_setbuiltinclientcert(sslcontext,0);
		if(ssl_connect(sslcontext,connection) < 0)
		{
			//gprintf("ssl_connect\n");
			result = HTTPR_ERR_CONNECT;
			ssl_shutdown(sslcontext);
			net_close (connection);
			return emptyblock;
		}
		int ret = ssl_handshake(sslcontext);
		if(ret < 0)
		{
			//gprintf("ssl_handshake %i\n", ret);
			result = HTTPR_ERR_STATUS;
			ssl_shutdown(sslcontext);
			net_close (connection);
			return emptyblock;
		}
	}

	// Remove Referer from the request header for incompatible websites (ex. Cloudflare proxy)
	char referer[domainlength + 12];
	snprintf(referer, sizeof(referer), "Referer: %s\r\n", domain);
	if(strstr(url, "geckocodes"))
	{
		strcpy(referer, "");
	}

	//Form a nice request header to send to the webserver
	char* headerformat = "GET %s HTTP/1.0\r\nHost: %s\r\n%sUser-Agent: USBLoaderGX r%s\r\n\r\n";
	char header[strlen(headerformat) + strlen(path) + strlen(domain) + strlen(referer) + 100];
	sprintf(header, headerformat, path, domain, referer, GetRev());
	//gprintf("\nHTTP Request:\n");
	//gprintf("%s\n",header);

	//Do the request and get the response
	tcp_write(http_port == 443 ? sslcontext : connection, header);
	read_header( http_port == 443 ? sslcontext : connection);

	if (http_status >= 400) // Not found
	{
		//gprintf("HTTP ERROR: %d\n", http_status);
		return emptyblock;
	}

	if(!content_length)
		content_length = 0;

	// create data buffer to return
	struct block response;
	response.data = malloc(content_length);
	response.size = content_length;
	if (response.data == NULL)
	{
		return emptyblock;
	}

	if (http_status == 200)
	{
		if(displayProgressWindow)
		{
			ProgressCancelEnable(true);
			StartProgress(tr("Downloading file..."), tr("Please wait"), 0, false, false);
		}

		int ret = tcp_readData(http_port == 443 ? sslcontext : connection, &response.data, content_length);
		if(!ret)
		{
			free(response.data);
			result = HTTPR_ERR_RECEIVE;
			if(http_port == 443)
				ssl_shutdown(sslcontext);
			net_close (connection);
			return emptyblock;
		}
	}
	else if (http_status == 302) // 302 FOUND (redirected link)
	{
		// close current connection
		if(http_port == 443)
			ssl_shutdown(sslcontext);
		net_close (connection);

		// prevent infinite loops
		retryloop++;
		if(retryloop > 3)
		{
			retryloop = 0;
			return emptyblock;
		}

		struct block redirected = downloadfile(content_location);
		if(redirected.size == 0)
			return emptyblock;

		// copy the newURL data into the original data
		u8 * tmp = realloc(response.data, redirected.size);
		if (tmp == NULL)
		{
			gprintf("Could not allocate enough memory for new URL. Download canceled.\n");
			free(response.data);
			response.size = 0;
			free(redirected.data);
			result = HTTPR_ERR_RECEIVE;
			if(http_port == 443)
				ssl_shutdown(sslcontext);
			net_close (connection);
			return emptyblock;
		}
		response.data = tmp;
		memcpy(response.data, redirected.data, redirected.size);
		free(redirected.data);
		response.size = redirected.size;

	}
	retryloop = 0;
	
	// reset progress window if used
	if(displayProgressWindow)
	{
		ProgressStop();
		ProgressCancelEnable(false);
		displayProgressWindow = false;
	}

	return response;
}