Add basic client socket config
This commit is contained in:
		
							
								
								
									
										20
									
								
								http/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								http/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | ||||
| # http | ||||
| The aim of these two modules is to implement a client and a server that partially implement HTTP 1.1 | ||||
|  | ||||
| ## client | ||||
|  | ||||
| The client takes a URL as input, connects to the corresponding server on the corresponding port(`80` by default) and requests the file specified in | ||||
| the URL. The transmitted content of that file is written to `stdout`, to a file or to a directory. | ||||
|  | ||||
|     SYNOPSIS | ||||
|     client [-p PORT] [ -o FILE | -d DIR ] URL | ||||
|  | ||||
|     EXAMPLE | ||||
|     client http://ivayloivanov.eu/en/ | ||||
|  | ||||
|  | ||||
| ## server | ||||
|  | ||||
| Not implemented yet | ||||
|  | ||||
| **Note: The description is from the task I got from TU.** | ||||
| @@ -1,14 +1,38 @@ | ||||
| /** | ||||
|  * @file client.c | ||||
|  * @author Ivaylo Ivanov 11777707 | ||||
|  * @date 03.11.2018 | ||||
|  * | ||||
|  * @brief Client program module. | ||||
|  * | ||||
|  * The client module takes a URL as input, connects to the corresponding server on the corresponding | ||||
|  * port(`80` by default) and requests the file specified in the URL. | ||||
|  * The content of that file is written to `stdout`, to a file or to a directory. | ||||
|  * | ||||
|  *   SYNOPSIS | ||||
|  *   client [-p PORT] [ -o FILE | -d DIR ] URL | ||||
|  * | ||||
|  *   EXAMPLE | ||||
|  *   client http://ivayloivanov.eu/en/ | ||||
|  * | ||||
|  **/ | ||||
|  | ||||
| #define _GNU_SOURCE ///< in order for optarg to be defined | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
| #include <string.h> | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <netdb.h> | ||||
| #include "shared/http.h" | ||||
|  | ||||
| static struct addrinfo* get_host_info(const char *hostname, char *port); | ||||
|  | ||||
| int main(int argc, char *argv[]) { | ||||
|     check_opts_number(argc); | ||||
|  | ||||
|     int port = 80; | ||||
|     char *port = "80"; | ||||
|     char *ofile = NULL; | ||||
|     char *dir = NULL; | ||||
|     char *url = NULL; | ||||
| @@ -18,7 +42,7 @@ int main(int argc, char *argv[]) { | ||||
|     while((c = getopt(argc, argv, "p:o:d:h")) != -1) { | ||||
|         switch(c) { | ||||
|             case 'p': | ||||
|                 port = atoi(optarg); | ||||
|                 port = optarg; | ||||
|                 break; | ||||
|             case 'o': | ||||
|                 ofile = optarg; | ||||
| @@ -57,6 +81,11 @@ int main(int argc, char *argv[]) { | ||||
|  | ||||
|     const char *full_url = strstr(url, "http://") + 7; //< the full url starts after http:// | ||||
|     const char *path = strstr(full_url, "/"); | ||||
|     const char *hostname = "google.com"; //< TODO: Change this later | ||||
|  | ||||
|     struct addrinfo* res = get_host_info(hostname, port); //< Check if the address is resolvable | ||||
|  | ||||
|     freeaddrinfo(res); //< Free the addrinfo struct | ||||
| } | ||||
|  | ||||
| static void print_usage(void) { | ||||
| @@ -67,7 +96,7 @@ static void print_usage(void) { | ||||
|  * @brief Function to check the number of arguments | ||||
|  * @details Checks the number of arguments supplied to the command line. | ||||
|  *          If the arguments are less than the required or more than possible, it exits | ||||
|  * @param argc Number of arguments obtained from the command line | ||||
|  * @param argc - Number of arguments obtained from the command line | ||||
|  * @return none | ||||
|  * | ||||
|  **/ | ||||
| @@ -82,3 +111,38 @@ static void check_opts_number(int argc) { | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * @brief Function to check if the address is resolvable by the client | ||||
|  * @details Checks if the address is resolvable by the client. | ||||
|  *          If the address is resolvable, it writes the result to res | ||||
|  *          If the address is not resolvable, it exits with an error | ||||
|  * @param | ||||
|  *          hostname - The address to be resolved | ||||
|  *          port     - The port to try | ||||
|  * @return res - The result of getaddrinfo() | ||||
|  * | ||||
|  **/ | ||||
| static struct addrinfo* get_host_info(const char *hostname, char *port) { | ||||
|     struct addrinfo hints; //< Configuration for the client | ||||
|     hints.ai_family = AF_INET; //< Use IPv4 | ||||
|     hints.ai_socktype = SOCK_STREAM; //< Stream socket | ||||
|     hints.ai_flags = 0; //< Do not use any flags | ||||
|     hints.ai_protocol = IPPROTO_TCP; //< Use only TCP | ||||
|  | ||||
|     struct addrinfo* res = NULL; | ||||
|  | ||||
|     int err = getaddrinfo(hostname, port, &hints, &res); | ||||
|  | ||||
|     if(err != 0) { | ||||
|         (void) fprintf(stderr, "ERROR:  %s\n", gai_strerror(err)); | ||||
|         exit(EXIT_FAILURE); //< Exit if there is an error | ||||
|     } | ||||
|  | ||||
|     if(res == NULL) { | ||||
|         (void) fprintf(stderr, "ERROR:  Could not resolve address %s\n", hostname); | ||||
|         exit(EXIT_FAILURE); //< Exit if the address is not resolved | ||||
|     } | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| #ifndef HTTP_HEADER_FILE | ||||
| #define HTTP_HEADER_FILE | ||||
|  | ||||
| static void print_usage(); | ||||
| static void print_usage(void); | ||||
| static void check_opts_number(int argc); | ||||
|  | ||||
| #endif | ||||
		Reference in New Issue
	
	Block a user