00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "defs.h"
00022 #include "ssi.h"
00023
00024
00025
00026
00027
00028 #define WEB_ROOT "/aup/webroot/"
00029 #define NOTFOUND_PAGE "/aup/notfound.htm"
00030
00031 #define HEADER_OK\
00032 "HTTP/1.1 200 OK\r\n"\
00033 "Server: AUP-ws\r\n"\
00034 "Content-Length: %ld\r\n"
00035
00036 #define CONTENT_TEXT\
00037 "Content-Type: text/html\r\n\r\n"
00038
00039 #define CONTENT_JPEG\
00040 "Content-Type: image/jpeg\r\n\r\n"
00041
00042 #define HEADER_NOTFOUND\
00043 "HTTP/1.1 404 Not Found\r\n"\
00044 "Server: AUP-ws\r\n"\
00045 "Transfer-Encoding: chunked\r\n"\
00046 "Content-Type: text/html\r\n\r\n"
00047
00048 #define HTML_NOTFOUND\
00049 "<!DOCTYPE html PUBLIC \"-//IETF//DTD HTML 2.0//EN\">\n"\
00050 "<html><head><title>Error 404</title>\n"\
00051 "</head><body>\n"\
00052 "<h2>AUP-ws server can't find page %s</h2>"\
00053 "</body></html>\r\n"
00054
00055
00056 static void send_header_OK(SSI *ssip, off_t len, const char *path, int fd)
00057 {
00058 char buf[1000], *dot;
00059
00060 snprintf(buf, sizeof(buf), HEADER_OK, (long)len);
00061 ec_neg1( writeall(fd, buf, strlen(buf)) )
00062
00063 dot = strrchr(path, '.');
00064 if (dot != NULL && (strcasecmp(dot, ".jpg") == 0 ||
00065 strcasecmp(dot, ".jpeg") == 0))
00066 ec_neg1( writeall(fd, CONTENT_JPEG, strlen(CONTENT_JPEG)) )
00067 else {
00068 time_t tm;
00069 char buf[100];
00070
00071 ec_neg1( writeall(fd, CONTENT_TEXT, strlen(CONTENT_TEXT)) )
00072 (void)time(&tm);
00073 strcpy(buf, ctime(&tm));
00074 ec_neg1( writeall(fd, buf, strlen(buf)) )
00075 }
00076 return;
00077
00078 EC_CLEANUP_BGN
00079 EC_FLUSH("Error sending response (nonfatal)")
00080 EC_CLEANUP_END
00081 }
00082
00083 static void send_header_notfound(SSI *ssip, const char *path, int fd)
00084 {
00085 char buf[2000], buf_html[1000];
00086
00087
00088 snprintf(buf_html, sizeof(buf_html), HTML_NOTFOUND, path);
00089 snprintf(buf, sizeof(buf), "%s%x\r\n%s\r\n0\r\n\r\n",
00090 HEADER_NOTFOUND, strlen(buf_html), buf_html);
00091 ec_neg1( writeall(fd, buf, strlen(buf)) )
00092 return;
00093
00094 EC_CLEANUP_BGN
00095 EC_FLUSH("Error sending response (nonfatal)")
00096 EC_CLEANUP_END
00097 }
00098
00099 static bool handle_request(SSI *ssip, const char *s, int fd)
00100 {
00101 char *p, buf[1000], path[FILENAME_MAX];
00102 FILE *in;
00103 struct stat statbuf;
00104 ssize_t nread, nsent, nsenttotal = 0;
00105
00106 if (strncasecmp(s, "GET ", 4) == 0) {
00107 s += 4;
00108 p = strchr(s, ' ');
00109 if (p != NULL)
00110 *p = '\0';
00111 strcpy(path, WEB_ROOT);
00112 strncat(path, s, sizeof(path));
00113 if (stat(path, &statbuf) == 0 &&
00114 (statbuf.st_mode & S_IFDIR) == S_IFDIR) {
00115 if (path[strlen(path) - 1] != '/')
00116 strncat(path, "/", sizeof(path));
00117 strncat(path, "index.html", sizeof(path));
00118 }
00119 if (stat(path, &statbuf) == -1 ||
00120 (in = fopen(path, "rb")) == NULL) {
00121 send_header_notfound(ssip, s, fd);
00122 return false;
00123 }
00124 send_header_OK(ssip, statbuf.st_size, path, fd);
00125
00126 while ((nread = fread(buf, 1, sizeof(buf), in)) > 0) {
00127 ec_neg1( nsent = writeall(fd, buf, nread) )
00128 nsenttotal += nsent;
00129 }
00130 if (statbuf.st_size != nsenttotal)
00131 printf("Sizes different stat = %ld; sent = %d\n",
00132 (long)statbuf.st_size, nsenttotal);
00133 (void)fclose(in);
00134 }
00135 else
00136 printf("Unknown request: %.25s\n", s);
00137 return true;
00138
00139 EC_CLEANUP_BGN
00140 EC_FLUSH("Error sending response (nonfatal)")
00141 return false;
00142 EC_CLEANUP_END
00143 }
00144
00145 int main(int argc, char *argv[])
00146 {
00147 SSI *ssip = NULL;
00148 char msg[1600];
00149 ssize_t nrcv;
00150 int i, fd, c;
00151 char hostbuf[100] = "//", *host = NULL;
00152
00153 while ((c = getopt(argc, argv, ":h:")) != -1)
00154 switch(c) {
00155 case 'h':
00156 host = optarg;
00157 break;
00158 case ':':
00159 fprintf(stderr, "Option -%c requires an operand\n", optopt);
00160
00161 default:
00162 fprintf(stderr, "Usage: ws [-h host]\n");
00163 exit(EXIT_FAILURE);
00164 }
00165 if (host == NULL) {
00166 ec_neg1( gethostname(&hostbuf[2], sizeof(hostbuf) - 2) )
00167 host = hostbuf;
00168 }
00169 if (strchr(host, ':') == NULL)
00170 strcat(host, ":8000");
00171 printf("Connecting to host \"%s\"\n", host);
00172 ec_null( ssip = ssi_open(host, true) )
00173 printf("\t...connected\n");
00174 while (true) {
00175 ec_neg1( fd = ssi_wait_server(ssip) )
00176 nrcv = read(fd, msg, sizeof(msg));
00177 switch (nrcv) {
00178 case 0:
00179 continue;
00180 case -1:
00181 if (errno == ECONNRESET)
00182 fprintf(stderr, "ECONNRESET\n");
00183 syserr_print("smi_receive_skt_string got error (nonfatal)\n");
00184 continue;
00185 default:
00186 msg[nrcv] = '\0';
00187 printf("Got %d bytes:\n", nrcv);
00188 for (i = 0; i < nrcv; i++) {
00189 if (isgraph((int)msg[i]) || isspace((int)msg[i]))
00190 printf("%c", msg[i]);
00191 else
00192 printf("'\\%o'", msg[i]);
00193 }
00194 (void)handle_request(ssip, msg, fd);
00195 }
00196 }
00197 ec_false( ssi_close(ssip) )
00198 printf("Done.\n");
00199 exit(EXIT_SUCCESS);
00200
00201 EC_CLEANUP_BGN
00202 return EXIT_FAILURE;
00203 EC_CLEANUP_END
00204 }