int main(int argc, char *argv[])
{
	int sockfd, numbytes;  
	char buf[DATA];
	struct addrinfo hints, *servinfo, *p;
	int rv;
	char s[INET6_ADDRSTRLEN];
	char * host;

	if (argc != 2) {
	    fprintf(stderr,"usage: client hostname\r\n");
	    exit(1);
	}
	host = argv[1];
	char * array = host + 7;
	char * port;
	char * page;
	char * ip;
	char pointer;
	int z = 0;
	while(z < strlen(array))
	{
		pointer = array[z];
		if(pointer == ':')
		{
			ip = strtok(array, ":");
			
			port = strtok(NULL, "/");
			page = strtok(NULL, "\r\n");
		}
		else if(pointer == '/')
		{
			ip = strtok(array, "/");
			port = "80";
			page = strtok(NULL,"\r\n");
		}
		z++;
	}
	//GETQUERY
	char * get = getquery(array, page);
	fprintf(stderr, "Query: %s\n", get);

	memset(&hints, 0, sizeof hints);
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_STREAM;

	if ((rv = getaddrinfo(ip, port, &hints, &servinfo)) != 0) {
		fprintf(stderr, "getaddrinfo: %s\r\n", gai_strerror(rv));
		return 1;
	}

	// loop through all the results and connect to the first we can
	for(p = servinfo; p != NULL; p = p->ai_next) {
		if ((sockfd = socket(p->ai_family, p->ai_socktype,
				p->ai_protocol)) == -1) {
			perror("client: socket");
			continue;
		}

		if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
			close(sockfd);
			perror("client: connect");
			continue;
		}

		break;
	}

	if (p == NULL) {
		fprintf(stderr, "client: failed to connect\r\n");
		return 2;
	}

	inet_ntop(p->ai_family, get_in_addr((struct sockaddr *)p->ai_addr),
			s, sizeof s);
	printf("client: connecting to %s\r\n", s);

	freeaddrinfo(servinfo); // all done with this structure


	//PRINT OUT MESSAGE
	memset(buf, '\0', sizeof(buf));
	sprintf(buf, "GET /%s HTTP/1.1\r\n", page);
	sprintf(buf + strlen(buf), "User-Agent: Wget/1.12 (linux-gnu)\r\n");
	sprintf(buf + strlen(buf), "Host: %s\r\n", ip);
	sprintf(buf + strlen(buf),"Connection: Keep-Alive\r\n\r\n");


	if((numbytes = send(sockfd, buf, strlen(buf), 0)) == -1)
	{
		perror("send");
		exit(1);
	}

	//RECEIVING STUFF
	FILE * output;
	output = fopen("temp", "wb");
	while(1)
	{
		if((numbytes = recv(sockfd, buf, DATA-1, 0)) == -1)
		{
			perror("recv");
			exit(1);
		}

		if(numbytes == 0)
		{
			break;
		}

		fwrite(buf, sizeof(char), numbytes, output);

	}

	close(sockfd);
	fclose(output);
	output = fopen("temp", "rb");
	FILE * foutput;
	foutput = fopen("output", "wb");

	int headerprocessed = 0;

	char * t;
	do
	{
		numbytes = fread(buf, sizeof(char), DATA, output);
		if(!headerprocessed)
		{
			t = strstr(buf, "\r\n\r\n") + 4;
			fwrite(t, sizeof(char), numbytes - (t - buf), foutput);
			headerprocessed = 1;
		}
		else
		{
			fwrite(buf, sizeof(char), numbytes, foutput);
		}
	}
	while(numbytes == DATA);
	fclose(foutput);
	fclose(output);
	remove("temp");

	return 0;
}
Exemple #2
0
/**
 * Parse host, port, path, and query components from uri.
 * If destination host and/or port are in the URI they are elided
 * from the options list.
 *
 * @todo Does not reject URI's with fragments (RFC7252 6.4 Step 4).
 * @todo Does perform percent-decoding.
 *
 * Note: Host is elided if it matches desthost, RFC7252 says this only
 * happens if desthost is IP v6 or v4 literal. We rely on the caller
 * to only pass in the desthost string if it is an IP literal.
 *
 * @return the corresponding options list or 0 on error.
 */
mc_options_list_t* mc_uri_to_options(mc_options_list_t* const list, sockaddr_t* const dest, char* const uri) {
	mc_option_t* options;
	sockaddr_t uriaddr;
	char* host;
	char* path;
	char* query;
	uint32_t port;
	uint32_t nopts;
	uint32_t iopt;

	char* current = (char*)uri;
	char* scheme = getscheme(current);
	if (!validscheme(scheme)) {
		if (scheme) ms_free(scheme);
		return 0;
	}
	ms_free(scheme);

	current = advanceto(current, ":");
	current = advanceby(current, "://");
	if (!current) {
		return 0;
	}

	host = getaddress(current);
	if (!host) {
		return 0;
	}

	if (strlen(host) == 0) {
		ms_free(host);
		return 0;
	}

	/* Check and compensate for IP v6 []'s if needed. */
	if (current && (*current == '[')) current += 2;

	current += strlen(host);
	port = getport(current);
	current = advanceto(current, "/?");

	/* Estimate the number of options needed based on remaining path, */
	/* and if the destination matches the URI, then allocate the option array. */
	/* Note the RFC only omits the host if it is an IP literal. */
	nopts = estimatenopts(current);
	mn_sockaddr_inet_init(&uriaddr, host, port);
	if (!equaladdr(&uriaddr, dest)) {
		nopts += 2;
	}
	options = ms_calloc(nopts, mc_option_t);

	/* Note does not properly account for IP literal requirement in section 6.4 step 5. */
	iopt = 0;
	if (!equaladdr(&uriaddr, dest)) {
		mc_option_init_str(&options[iopt], OPTION_URI_HOST, host);
		iopt++;

		mc_option_init_uint32(&options[iopt], OPTION_URI_PORT, port);
		iopt++;
	}

	path = getpath(current);
	while (path) {
		mc_option_init_str(&options[iopt], OPTION_URI_PATH, ms_copy_str(path));
		iopt++;
		current = advanceto(++current, "/?");
		ms_free(path);
		path = getpath(current);
	}

	query = getquery(current);
	while (query) {
		mc_option_init_str(&options[iopt], OPTION_URI_QUERY, ms_copy_str(query));
		iopt++;
		current = advanceto(++current, "&");
		ms_free(query);
		query= getquery(current);
	}

	return mc_options_list_init(mc_options_list_alloc(), iopt, options);
}