#include "httpd.h" #include #include #include #include #include #include #include #include #include #include #include #define CONNMAX 1000 static int listenfd, clients[CONNMAX]; static void error(char *); static void startServer(const char *); static void respond(int); typedef struct { char *name, *value; } header_t; static header_t reqhdr[17] = { {"\0", "\0"} }; static int clientfd; static char *buf; void serve_forever(const char *PORT) { struct sockaddr_in clientaddr; socklen_t addrlen; char c; int slot=0; printf( "Server started %shttp://127.0.0.1:%s%s\n", "\033[92m",PORT,"\033[0m" ); // Setting all elements to -1: signifies there is no client connected int i; for (i=0; iai_next) { int option = 1; listenfd = socket (p->ai_family, p->ai_socktype, 0); setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option)); if (listenfd == -1) continue; if (bind(listenfd, p->ai_addr, p->ai_addrlen) == 0) break; } if (p==NULL) { perror ("socket() or bind()"); exit(1); } freeaddrinfo(res); // listen for incoming connections if ( listen (listenfd, 1000000) != 0 ) { perror("listen() error"); exit(1); } } // get request header char *request_header(const char* name) { header_t *h = reqhdr; while(h->name) { if (strcmp(h->name, name) == 0) return h->value; h++; } return NULL; } //client connection void respond(int n) { int rcvd, fd, bytes_read; char *ptr; buf = malloc(65535); rcvd=recv(clients[n], buf, 65535, 0); if (rcvd<0) // receive error fprintf(stderr,("recv() error\n")); else if (rcvd==0) // receive socket closed fprintf(stderr,"Client disconnected upexpectedly.\n"); else // message received { buf[rcvd] = '\0'; method = strtok(buf, " \t\r\n"); uri = strtok(NULL, " \t"); prot = strtok(NULL, " \t\r\n"); fprintf(stderr, "\x1b[32m + [%s] %s\x1b[0m\n", method, uri); if (qs = strchr(uri, '?')) { *qs++ = '\0'; //split URI } else { qs = uri - 1; //use an empty string } header_t *h = reqhdr; char *t, *t2; while(h < reqhdr+16) { char *k,*v,*t; k = strtok(NULL, "\r\n: \t"); if (!k) break; v = strtok(NULL, "\r\n"); while(*v && *v==' ') v++; h->name = k; h->value = v; h++; fprintf(stderr, "[H] %s: %s\n", k, v); t = v + 1 + strlen(v); if (t[1] == '\r' && t[2] == '\n') break; } t++; // now the *t shall be the beginning of user payload t2 = request_header("Content-Length"); // and the related header if there is payload = t; payload_size = t2 ? atol(t2) : (rcvd-(t-buf)); // bind clientfd to stdout, making it easier to write clientfd = clients[n]; dup2(clientfd, STDOUT_FILENO); close(clientfd); // call router route(); // tidy up fflush(stdout); shutdown(STDOUT_FILENO, SHUT_WR); close(STDOUT_FILENO); } //Closing SOCKET shutdown(clientfd, SHUT_RDWR); //All further send and recieve operations are DISABLED... close(clientfd); clients[n]=-1; }