1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <sys/wait.h>
#include <signal.h>
#include <time.h>
#include <dirent.h>
#define LENGTH 512
#define MAXDATASIZE 1000
typedef enum {FALSE, TRUE} bool;
/* inout() - This function prints out the results of the file descriptor
* after finishing sending the request to the server
*/
int inout(int in, int out)
{
char *s;
int i = 0;
s = (char *) malloc (1000*sizeof(char));
while(read(in, s+i, 1) != 0) {
if (s[i] == '\n') {
write(out, s, i+1);
return i+1;
}
i++;
}
return 0;
}
void *get_in_addr(struct sockaddr *sa)
{
if (sa->sa_family == AF_INET) {
return &(((struct sockaddr_in*)sa)->sin_addr);
}
return &(((struct sockaddr_in6*)sa)->sin6_addr);
}
/* isvalidip() - Uses the inet_pton() function to check whether or not
* the specified IP address is valid. Returns TRUE if valid and FALSE
* otherwise.
*/
bool isvalidip(char *ip)
{
struct sockaddr_in sa;
int valid = inet_pton(AF_INET, ip, &(sa.sin_addr));
return valid != 0;
}
/* send_request() - Contains the principal code the for the program.
* The function creates a HTTP GET string to send to the server
* and returns everything on a file descriptor to pass it to main().
*/
int send_request(char *dns, char *port,char *reqtype)
{
int sockfd, bindfd; // socket and bind file descriptors
char *ptr, *host, path[100];
char getrequest[1024];
struct addrinfo hints, *res;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
// conditions to differentiate between an IP address and a hostname
if ( isvalidip(dns) ) { // when an IP is found then no paths are specified
sprintf(getrequest, "%s / HTTP/1.0\nHOST: %s\n\n",reqtype, dns); // create a get request only for the IP
} else { // if it's not an IP, then it should be a DNS name
if ( (ptr = strstr(dns, "/")) == NULL) { // if the DNS name does not contain a slash at the end
sprintf(getrequest, "%s / HTTP/1.0\nHOST: %s\n\n",reqtype, dns);// we send a request only for the dns name
}
else { // it there is a slash right after the DNS name then there is path to a filename
strcpy(path, ptr);
host = strtok(dns, "/"); //truncate the argument to a PATH and DNS name
sprintf(getrequest, "%s %s HTTP/1.0\nHOST: %s\n\n",reqtype, path, dns);
}
}
// gets linked list of results of a specified hostname
if ( getaddrinfo(dns, port, &hints, &res) != 0 ){
fprintf(stderr, "Host or IP not valid\n"); //quits program if the hostname was not found
exit(0);
}
// creates a socket from hostname results and passes everything to a file descriptor
sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
// bind the socket to the port passed to getaddrinfo()
bindfd = bind(sockfd, res->ai_addr, res->ai_addrlen);
// establish a connection and quits if there is a connection error
if ( connect(sockfd, res->ai_addr, res->ai_addrlen) != 0 ){
fprintf(stderr, "Connection error\n");
exit(0);
}
int optval = 1; //is
setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval);
// writes the HTTP request to the socked file descriptor
write(sockfd, getrequest, strlen(getrequest));
return sockfd; //returns the results to main
}
int main(int argc, char **argv)
{
int port, sockfd;
char *host, *ptr;
port = atoi(argv[2]);
sprintf(host,"%s/%s",argv[1],argv[4]);
if(argv[3][0]=='G'&&argv[3][1]=='E'&&argv[3][2]=='T') //For GET requests
{
sockfd = send_request(host, argv[2],argv[3]);
while(inout(sockfd, 1) > 0);
} else if(argv[3][0]=='P'&&argv[3][1]=='U'&&argv[3][2]=='T') //For PUT requests
{
char* fs_name = argv[4];
char sdbuf[LENGTH];
printf("\nclient>> Sending %s to the Server... ", fs_name);
FILE *fs = fopen(fs_name, "r");
if(fs == NULL)
{
printf("\nclient>> ERROR: File %s not found.", fs_name);
exit(1);
}
sockfd = send_request(host, argv[2],argv[3]);
bzero(sdbuf, LENGTH);
int fs_block_sz;
while((fs_block_sz = fread(sdbuf, sizeof(char), LENGTH, fs)) > 0)
{
if(send(sockfd, sdbuf, fs_block_sz, 0) < 0)
{
fprintf(stderr, "ERROR: Failed to send file %s. (errno = %d)", fs_name, errno);
exit(1);
}
bzero(sdbuf, LENGTH);
}
shutdown(sockfd, SHUT_WR);
printf("\nclient>> Ok File %s from Client was Sent!\n", fs_name);
} else { //For INVALID requests
printf("\nclient>> Invalid request.\n");
exit(1);
}
close(sockfd);
return 0;
}
|