Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- helloworld.c
- Dylan Weber
- */
- #include <stdio.h>
- #include <stdint.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netdb.h>
- typedef struct URLdata {
- char *protocol;
- char *username;
- char *password;
- char *host;
- char *port;
- char *path;
- } URLdata;
- typedef struct HTTPresponse {
- int status;
- char **headers;
- char *content;
- } HTTPresponse;
- URLdata *createURLdata(char *weburl);
- void freeURLdata(URLdata *freeURL);
- HTTPresponse *requestHTTPresponse(URLdata *requestDestination);
- void *get_in_addr(struct sockaddr *sa);
- char **generateHeaderList(char *headers);
- void freeHTTPresponse(HTTPresponse *freeResponse);
- int main(int argc, char *argv[]) {
- if (argc != 2) {
- printf("Usage: helloworld ... destination\n");
- return 1;
- }
- URLdata *inputURL = createURLdata(argv[1]);
- HTTPresponse *outputResponse = requestHTTPresponse(inputURL);
- freeURLdata(inputURL);
- freeHTTPresponse(outputResponse);
- return 0;
- }
- URLdata *createURLdata(char *weburl) {
- char *postprotocol, *postuserinfo, *postusername, *login, *posthost, *posthostname, *hostloc, *postport;
- int isPath, userlen;
- URLdata *returnURL = malloc(sizeof(URLdata));
- returnURL->protocol = NULL;
- returnURL->username = NULL;
- returnURL->password = NULL;
- returnURL->host = NULL;
- returnURL->port = NULL;
- returnURL->path = NULL;
- if ((postprotocol = strstr(weburl, "://")) == NULL) {
- return returnURL;
- }
- returnURL->protocol = malloc(sizeof(char) * (postprotocol - weburl + 1));
- strncpy(returnURL->protocol, weburl, postprotocol - weburl);
- postprotocol = (postprotocol + (*(postprotocol+3)=='/'?4:3));
- if ((postuserinfo = strstr(postprotocol, "@")) != NULL) {
- if ((postusername = strchr(postprotocol, ':')) != NULL) {
- returnURL->password = malloc(sizeof(char) * (postuserinfo - postusername + 1));
- strncpy(returnURL->password, postusername + 1, (postuserinfo - postusername - 1));
- }
- userlen = (postusername?postusername:postuserinfo) - postprotocol;
- returnURL->username = malloc(sizeof(char) * userlen + 1);
- strncpy(returnURL->username, postprotocol, userlen);
- }
- hostloc = (postuserinfo?postuserinfo + 1:postprotocol);
- if ((posthost = strchr(hostloc, '/')) == NULL) {
- posthost = hostloc + strlen(hostloc);
- isPath = 1;
- }
- if ((posthostname = strchr(hostloc, ':')) == NULL) {
- posthostname = posthost;
- }
- returnURL->host = malloc(sizeof(char) * (posthostname - hostloc + 1));
- strncpy(returnURL->host, hostloc, (posthostname - hostloc));
- if (posthostname != posthost) {
- posthostname++;
- returnURL->port = malloc(sizeof(char) * (posthost - posthostname + 1));
- strncpy(returnURL->port, posthostname, (posthost - posthostname));
- } else {
- returnURL->port = malloc(sizeof(char) * 2 + 1);
- strncpy(returnURL->port, "80", 2);
- }
- if (isPath) {
- returnURL->path = malloc(sizeof(char) * strlen(posthost) + 1);
- strncpy(returnURL->path, posthost, strlen(posthost));
- } else {
- returnURL->path = calloc(1, 1);
- }
- return returnURL;
- }
- void freeURLdata(URLdata *freeURL) {
- free(freeURL->protocol);
- free(freeURL->username);
- free(freeURL->password);
- free(freeURL->host);
- free(freeURL->port);
- free(freeURL->path);
- free(freeURL);
- }
- HTTPresponse *requestHTTPresponse(URLdata *requestDestination) {
- char ip[INET6_ADDRSTRLEN], *request, *response = malloc(1), *headerTerminator = NULL, *responseTerminator = NULL, *headerString, *contentString, buffer[100];
- int sockfd, bufferLength, responseLength;
- struct addrinfo hints, *servinfo, *p;
- /* Initialize HTTP response structure */
- HTTPresponse *returnresponse = malloc(sizeof(HTTPresponse));
- returnresponse->status = 0;
- returnresponse->headers = NULL;
- returnresponse->content = NULL;
- /* Retrieve IP address of host */
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(requestDestination->host, requestDestination->port, &hints, &servinfo) != 0) {
- return returnresponse;
- }
- /* Loop through all possible connections */
- for (p = servinfo; p != NULL; p = p->ai_next) {
- if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
- continue;
- }
- if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
- close(sockfd);
- continue;
- }
- break;
- }
- if (p == NULL) {
- return returnresponse;
- }
- /* Print IP address & free server information */
- inet_ntop(p->ai_family, get_in_addr((struct sockaddr*)p->ai_addr), ip, sizeof(ip));
- printf("The IP address is: %s\n", ip);
- freeaddrinfo(servinfo);
- /* Format HTTP request */
- request = malloc(27 + (int)strlen(requestDestination->path) + (int)strlen(requestDestination->host) * sizeof(char));
- if (request == NULL) {
- printf("Failure to allocate memory.\n");
- exit(1);
- }
- sprintf(request, "GET %s HTTP/1.1\r\nHost: %s\r\n\r\n", (*(requestDestination->path) == 0)?"/":requestDestination->path, requestDestination->host);
- /* Send HTTP request */
- send(sockfd, request, 26 + strlen(requestDestination->path) + strlen(requestDestination->host), 0);
- free(request);
- /* Receive HTTP response */
- do {
- bufferLength = recv(sockfd, buffer, 99, 0);
- if (bufferLength == -1) {
- break;
- }
- responseLength += bufferLength;
- response = realloc(response, (responseLength + 1) * sizeof(char));
- if (response == NULL) {
- printf("Failure to allocate memory.\n");
- exit(2);
- }
- strncpy(response + responseLength - bufferLength, buffer, bufferLength);
- if (headerTerminator) {
- responseTerminator = strstr(response, "\r\n\r\n");
- } else {
- headerTerminator = strstr(response, "\r\n\r\n");
- }
- } while (responseTerminator == NULL);
- /* Store data in structs */
- headerString = malloc((headerTerminator - response + 1) * sizeof(char));
- if (headerString == NULL) {
- printf("Failure to allocate memory.\n");
- exit(1);
- }
- strncpy(headerString, response, headerTerminator - response);
- contentString = malloc((responseTerminator - headerTerminator) * sizeof(char));
- if (contentString == NULL) {
- printf("Failure to allocate memory.\n");
- exit(1);
- }
- strncpy(contentString, headerTerminator, responseTerminator - headerTerminator);
- returnresponse->headers = generateHeaderList(headerString);
- returnresponse->content = contentString;
- free(response);
- /* Close connection & return HTTP response */
- close(sockfd);
- return returnresponse;
- }
- void *get_in_addr(struct sockaddr *sa) {
- if (sa->sa_family == AF_INET) {
- return &(((struct sockaddr_in*)sa)->sin_addr);
- } else if (sa->sa_family == AF_INET6) {
- return &(((struct sockaddr_in6*)sa)->sin6_addr);
- }
- }
- char **generateHeaderList(char *headers) {
- char **returnHeaders = NULL, *nextLine;
- int len, n = 0;
- do {
- returnHeaders = realloc(returnHeaders, (n + 1) * sizeof(char *));
- if (returnHeaders == NULL) {
- printf("Failure to allocate memory.\n");
- exit(1);
- }
- nextLine = strstr(headers, "\r\n");
- if (nextLine == NULL) break;
- len = nextLine - headers;
- *(returnHeaders + n) = malloc(((len==0)?1:len) * sizeof(char));
- strncpy(*(returnHeaders + n), headers, len);
- headers = nextLine + (2 * (int)(n!=0));
- if (len != 0) {
- n++;
- } else {
- free(*(returnHeaders + n));
- }
- } while (nextLine != NULL);
- return returnHeaders;
- }
- void freeHTTPresponse(HTTPresponse *freeResponse) {
- int n;
- for (n = 0; *((freeResponse->headers) + n) != NULL; n++) {
- free(*((freeResponse->headers) + n));
- }
- free(freeResponse->headers);
- free(freeResponse->content);
- free(freeResponse);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement