#include #include #include #include #include #include #include #include #include #include #include #define BUFFER_SIZE 256 /* assume the max command we get is this big */ #define RECEIVE_BUFFER_SIZE 4096 /* Default port to listen on */ #define DEFAULT_PORT 80 #define MIME_HTML 0 #define MIME_TXT 1 #define MIME_PNG 2 #define MIME_JPG 3 #define MIME_MAX 4 struct mime_type { char extension[5]; char string[32]; }; struct mime_type mime[MIME_MAX] = { {"html", "text/html"}, {"txt", "text/plain"}, {"png", "image/png"}, {"jpg", "image/jpeg"}, }; static int detect_mime(char *filename) { int i,j; i=strlen(filename); while(i>0) { if (filename[i]=='.') break; i--; } i++; for(j=0;j418 I'm a teapot\r\n" "\r\n" "

I'm a Teapot

\r\n" "

I'm a *little* teapot.
\r\n" "

\r\n" "\r\n"; sprintf(out_buffer, "HTTP/1.1 418 I'm a teapot\r\n" "Date: %s\r\n" "Server: VMW-web\r\n" "Content-Length: %d\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n" "\r\n" "%s", time_string,(int)strlen(message418),message418); out_size=strlen(out_buffer); } else if (result<0) { char message404[]= "\r\n" "400 Bad Request\r\n" "\r\n" "

Bad Request

\r\n" "

Your browser sent a request that this server could not understand.
\r\n" "

\r\n" "\r\n"; sprintf(out_buffer, "HTTP/1.1 400 Bad Request\r\n" "Date: %s\r\n" "Server: VMW-web\r\n" "Content-Length: %d\r\n" "Connection: close\r\n" "Content-Type: text/html; charset=iso-8859-1\r\n" "\r\n" "%s", time_string,(int)strlen(message404),message404); out_size=strlen(out_buffer); } else { char mod_string[1000]; tm = *gmtime(&stat_buf.st_mtime); int in_fd,out_offset; char file_buffer[256]; strftime(mod_string, sizeof(mod_string), "%a, %d %b %Y %H:%M:%S %Z", &tm); sprintf(out_buffer, "HTTP/1.1 200 OK\r\n" "Date: %s\r\n" "Server: VMW-web\r\n" "Last-Modified: %s\r\n" "Content-Length: %ld\r\n" "Content-Type: %s\r\n" "\r\n", time_string, mod_string, stat_buf.st_size, mime[mime_type].string); out_offset=strlen(out_buffer); in_fd=open(filename,O_RDONLY); if (in_fd<0) { fprintf(stderr,"Could not open %s\n",filename); } else { while(1) { result=read(in_fd,&file_buffer,256); if (result<=0) break; memcpy(out_buffer+out_offset, file_buffer,result); out_offset+=result; } close(in_fd); } out_size=out_offset; } /* Send a response */ printf("Sending:\n"); printf("%s\n",out_buffer); n = write(fd,out_buffer,out_size); if (n<0) { fprintf(stderr,"Error writing. %s\n", strerror(errno)); } return 0; } int main(int argc, char **argv) { int socket_fd,new_socket_fd; struct sockaddr_in server_addr, client_addr; struct addrinfo hints,*server_info; int port=DEFAULT_PORT; int n; socklen_t client_len; char buffer[BUFFER_SIZE]; char in[RECEIVE_BUFFER_SIZE]; int i,result,in_ptr=0; char port_string[BUFFER_SIZE]; if (argc>1) { port=atoi(argv[1]); } sprintf(port_string,"%d",port); printf("Starting server on port %d\n",port); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; /* Null means localhost */ /* How can we get IP of default interface? */ result=getaddrinfo(NULL,port_string,&hints,&server_info); if (result<0) { fprintf(stderr,"Error getaddrinfo!\n"); return -1; } /* Open a socket to listen on */ /* AF_INET means an IPv4 connection */ /* SOCK_STREAM means reliable two-way connection (TCP) */ socket_fd = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol); if (socket_fd<0) { fprintf(stderr,"Error opening socket! %s\n", strerror(errno)); return -1; } /* Set up the server address to listen on */ memset(&server_addr,0,sizeof(struct sockaddr_in)); server_addr.sin_family=AF_INET; /* Convert the port we want to network byte order */ server_addr.sin_port=htons(port); /* Bind to the port */ if (bind(socket_fd, server_info->ai_addr,server_info->ai_addrlen)) { fprintf(stderr,"Error binding! %s\n", strerror(errno)); return -1; } /* Tell the server we want to listen on the port */ /* Second argument is backlog, how many pending connections can */ /* build up */ listen(socket_fd,5); listen_connection: /* Call accept to create a new file descriptor for an incoming */ /* connection. It takes the oldest one off the queue */ /* We're blocking so it waits here until a connection happens */ client_len=sizeof(client_addr); new_socket_fd = accept(socket_fd, (struct sockaddr *)&client_addr,&client_len); if (new_socket_fd<0) { fprintf(stderr,"Error accepting! %s\n",strerror(errno)); } in_ptr=0; while(1) { /* Someone connected! Let's try to read BUFFER_SIZE-1 bytes */ memset(buffer,0,BUFFER_SIZE); n = read(new_socket_fd,buffer,(BUFFER_SIZE-1)); if (n==0) { fprintf(stderr,"Connection to client lost\n\n"); break; } else if (n<0) { fprintf(stderr,"Error reading from socket %s\n", strerror(errno)); } if (in_ptr+n>RECEIVE_BUFFER_SIZE) { fprintf(stderr,"Overflow receive buffer!\n"); break; } memcpy(&in[in_ptr],buffer,n); in_ptr+=n; in[in_ptr]=0; /* See if last chars were CRLFCRLF (empty line) */ /* Which indicates done talking */ if ((in[in_ptr-1]=='\n') && (in[in_ptr-3]=='\n')) { break; } } /* Print the message we received */ char filename[BUFSIZ]; printf("Request from webserver:\n"); i=0; int found_filename=0,file_ptr=0; while(iBUFSIZ) break; } filename[file_ptr]=0; } } } } } printf("%c",in[i]); i++; } if (!strcmp(filename,"/")) { printf("Mapping / to index.html\n"); strcpy(filename,"/index.html"); } printf("Sending back file: %s\n",filename); /* Skip leading / */ serve_file(new_socket_fd,filename+1); printf("Exiting server\n\n"); /* Try to avoid TIME_WAIT */ // sleep(1); /* Close the sockets */ close(new_socket_fd); goto listen_connection; close(socket_fd); return 0; }