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; }
/** * 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); }