00001 /* 00002 Mini Web Server 00003 AUP2, Sec. 8.04.4 00004 00005 Copyright 2003 by Marc J. Rochkind. All rights reserved. 00006 May be copied only for purposes and under conditions described 00007 on the Web page www.basepath.com/aup/copyright.htm. 00008 00009 The Example Files are provided "as is," without any warranty; 00010 without even the implied warranty of merchantability or fitness 00011 for a particular purpose. The author and his publisher are not 00012 responsible for any damages, direct or incidental, resulting 00013 from the use or non-use of these Example Files. 00014 00015 The Example Files may contain defects, and some contain deliberate 00016 coding mistakes that were included for educational reasons. 00017 You are responsible for determining if and how the Example Files 00018 are to be used. 00019 00020 */ 00021 #include "defs.h" 00022 #include "ssi.h" 00023 00024 /* rfc2616 */ 00025 /*[top]*/ 00026 #define HEADER\ 00027 "HTTP/1.0 %s\r\n"\ 00028 "Server: AUP-ws\r\n"\ 00029 "Content-Length: %ld\r\n" 00030 00031 #define CONTENT_TEXT\ 00032 "Content-Type: text/html\r\n\r\n" 00033 00034 #define CONTENT_JPEG\ 00035 "Content-Type: image/jpeg\r\n\r\n" 00036 00037 #define HTML_NOTFOUND\ 00038 "<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"\ 00039 "<html><head><title>Error 404</title>\n"\ 00040 "</head><body>\n"\ 00041 "<h2>AUP-ws server can't find document</h2>"\ 00042 "</body></html>\r\n" 00043 /*[send_header]*/ 00044 static void send_header(SSI *ssip, const char *msg, off_t len, 00045 const char *path, int fd) 00046 { 00047 char buf[1000], *dot; 00048 00049 snprintf(buf, sizeof(buf), HEADER, msg, (long)len); 00050 ec_neg1( writeall(fd, buf, strlen(buf)) ) 00051 dot = strrchr(path, '.'); 00052 if (dot != NULL && (strcasecmp(dot, ".jpg") == 0 || 00053 strcasecmp(dot, ".jpeg") == 0)) 00054 ec_neg1( writeall(fd, CONTENT_JPEG, strlen(CONTENT_JPEG)) ) 00055 else 00056 ec_neg1( writeall(fd, CONTENT_TEXT, strlen(CONTENT_TEXT)) ) 00057 return; 00058 00059 EC_CLEANUP_BGN 00060 EC_FLUSH("Error sending response (nonfatal)") 00061 EC_CLEANUP_END 00062 } 00063 /*[handle_request]*/ 00064 #define DEFAULT_DOC "index.html" 00065 #define WEB_ROOT "/aup/webroot/" 00066 00067 static bool handle_request(SSI *ssip, char *s, int fd) 00068 { 00069 char *tkn, buf[1000], path[500]; 00070 int ntkn; 00071 FILE *in; 00072 struct stat statbuf; 00073 ssize_t nread; 00074 00075 for (ntkn = 1; (tkn = strtok(s, " ")) != NULL; ntkn++) { 00076 s = NULL; 00077 switch (ntkn) { 00078 case 1: 00079 if (strcasecmp(tkn, "get") != 0) { 00080 printf("Unknown request\n"); 00081 return false; 00082 } 00083 continue; 00084 case 2: 00085 break; 00086 } 00087 break; 00088 } 00089 snprintf(path, sizeof(path) - 1 - strlen(DEFAULT_DOC), 00090 "%s%s", WEB_ROOT, tkn); 00091 if (stat(path, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { 00092 if (path[strlen(path) - 1] != '/') 00093 strcat(path, "/"); 00094 strcat(path, DEFAULT_DOC); 00095 } 00096 if (stat(path, &statbuf) == -1 || 00097 (in = fopen(path, "rb")) == NULL) { 00098 send_header(ssip, "404 Not Found", strlen(HTML_NOTFOUND), "", fd); 00099 ec_neg1( writeall(fd, HTML_NOTFOUND, strlen(HTML_NOTFOUND)) ) 00100 return false; 00101 } 00102 send_header(ssip, "200 OK", statbuf.st_size, path, fd); 00103 while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) 00104 ec_neg1( writeall(fd, buf, nread) ) 00105 ec_eof( fclose(in) ) 00106 return true; 00107 00108 EC_CLEANUP_BGN 00109 EC_FLUSH("Error sending response (nonfatal)") 00110 return false; 00111 EC_CLEANUP_END 00112 } 00113 /*[main]*/ 00114 #define PORT ":8000" 00115 00116 int main(void) 00117 { 00118 SSI *ssip = NULL; 00119 char msg[1600]; 00120 ssize_t nrcv; 00121 int fd; 00122 char host[100] = "//"; 00123 00124 ec_neg1( gethostname(&host[2], sizeof(host) - 2 - strlen(PORT)) ) 00125 strcat(host, PORT); 00126 printf("Connecting to host \"%s\"\n", host); 00127 ec_null( ssip = ssi_open(host, true) ) 00128 printf("\t...connected\n"); 00129 while (true) { 00130 ec_neg1( fd = ssi_wait_server(ssip) ) 00131 switch (nrcv = read(fd, msg, sizeof(msg) - 1)) { 00132 case -1: 00133 printf("Read error (nonfatal)\n"); 00134 /* fall through */ 00135 case 0: 00136 ec_false( ssi_close_fd(ssip, fd) ) 00137 continue; 00138 default: 00139 msg[nrcv] = '\0'; 00140 (void)handle_request(ssip, msg, fd); 00141 } 00142 } 00143 ec_false( ssi_close(ssip) ) 00144 printf("Done.\n"); 00145 exit(EXIT_SUCCESS); 00146 00147 EC_CLEANUP_BGN 00148 return EXIT_FAILURE; 00149 EC_CLEANUP_END 00150 } 00151 /*[]*/ 00152 #if 0 00153 /*[html]*/ 00154 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> 00155 <html> 00156 <head> 00157 </head> 00158 <body> 00159 <h1>This is a test page.</h1> 00160 <p><img src="picture.jpg"> 00161 </body> 00162 </html> 00163 /*[]*/ 00164 #endif