-
-
Save cristian-programmer/1a24cdba34dfd3b5b4103a48a4ec0662 to your computer and use it in GitHub Desktop.
Revisions
-
laobubu revised this gist
Nov 8, 2016 . 2 changed files with 23 additions and 11 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,15 +1,16 @@ #include "httpd.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netdb.h> #include <fcntl.h> #include <signal.h> #define CONNMAX 1000 @@ -42,6 +43,9 @@ void serve_forever(const char *PORT) for (i=0; i<CONNMAX; i++) clients[i]=-1; startServer(PORT); // Ignore SIGCHLD to avoid zombie threads signal(SIGCHLD,SIG_IGN); // ACCEPT connections while (1) @@ -140,6 +144,13 @@ void respond(int n) 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; This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -11,7 +11,8 @@ void serve_forever(const char *PORT); // Client request char *method, // "GET" or "POST" *uri, // "/index.html" things before '?' *qs, // "a=1&b=2" things after '?' *prot; // "HTTP/1.1" char *payload; // for POST -
laobubu created this gist
Nov 7, 2016 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,17 @@ # Pico HTTP Server in C This is a very simple HTTP server for Unix, using fork(). It's very easy to use ## How to use 1. include header `httpd.h` 2. write your route method, handling requests. 3. call `serve_forever("12913")` to start serving on port 12913 See `main.c`, an interesting example. To log stuff, use `fprintf(stderr, "message");` View `httpd.h` for more information based on <http://blog.abhijeetr.com/2010/04/very-simple-http-server-writen-in-c.html> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,15 @@ all: server clean: @rm -rf *.o @rm -rf server server: main.o httpd.o gcc -o server $^ main.o: main.c httpd.h gcc -c -o main.o main.c httpd.o: httpd.c httpd.h gcc -c -o httpd.o httpd.c This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,180 @@ #include "httpd.h" #include<stdio.h> #include<string.h> #include<stdlib.h> #include<unistd.h> #include<sys/types.h> #include<sys/stat.h> #include<sys/socket.h> #include<arpa/inet.h> #include<netdb.h> #include<fcntl.h> #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; i<CONNMAX; i++) clients[i]=-1; startServer(PORT); // ACCEPT connections while (1) { addrlen = sizeof(clientaddr); clients[slot] = accept (listenfd, (struct sockaddr *) &clientaddr, &addrlen); if (clients[slot]<0) { perror("accept() error"); } else { if ( fork()==0 ) { respond(slot); exit(0); } } while (clients[slot]!=-1) slot = (slot+1)%CONNMAX; } } //start server void startServer(const char *port) { struct addrinfo hints, *res, *p; // getaddrinfo for host memset (&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; if (getaddrinfo( NULL, port, &hints, &res) != 0) { perror ("getaddrinfo() error"); exit(1); } // socket and bind for (p = res; p!=NULL; p=p->ai_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); 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; } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,36 @@ #ifndef _HTTPD_H___ #define _HTTPD_H___ #include <string.h> #include <stdio.h> //Server control functions void serve_forever(const char *PORT); // Client request char *method, // "GET" or "POST" *uri, // "/index.html" *prot; // "HTTP/1.1" char *payload; // for POST int payload_size; char *request_header(const char* name); // user shall implement this function void route(); // some interesting macro for `route()` #define ROUTE_START() if (0) { #define ROUTE(METHOD,URI) } else if (strcmp(URI,uri)==0&&strcmp(METHOD,method)==0) { #define ROUTE_GET(URI) ROUTE("GET", URI) #define ROUTE_POST(URI) ROUTE("POST", URI) #define ROUTE_END() } else printf(\ "HTTP/1.1 500 Not Handled\r\n\r\n" \ "The server has no handler to the request.\r\n" \ ); #endif This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,27 @@ #include "httpd.h" int main(int c, char** v) { serve_forever("12913"); return 0; } void route() { ROUTE_START() ROUTE_GET("/") { printf("HTTP/1.1 200 OK\r\n\r\n"); printf("Hello! You are using %s", request_header("User-Agent")); } ROUTE_POST("/") { printf("HTTP/1.1 200 OK\r\n\r\n"); printf("Wow, seems that you POSTed %d bytes. \r\n", payload_size); printf("Fetch the data using `payload` variable."); } ROUTE_END() }