1 #include "config.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <string.h>
6 #include <unistd.h>
7 #include <fcntl.h>
8 #include <errno.h>
9 #include <syslog.h>
10 #include <time.h>
11
12 #include <sys/time.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16
17 #include "httpd.h"
18
19 /* ---------------------------------------------------------------------- */
20
21 static struct HTTP_STATUS {
22 int status;
23 char *head;
24 char *body;
25 } http[] = {
26 { 200, "200 OK", NULL },
27 { 400, "400 Bad Request", "*PLONK*\n" },
28 { 404, "404 Not Found", "videotext page not found in cache\n" },
29 { 408, "408 Request Timeout", "Request Timeout\n" },
30 { 500, "500 Internal Server Error", "Sorry folks\n" },
31 { 501, "501 Not Implemented", "Sorry folks\n" },
32 { 0, NULL, NULL }
33 };
34
35 /* ---------------------------------------------------------------------- */
36
37 #define RESPONSE_START \
38 "HTTP/1.1 %s\r\n" \
39 "Server: %s\r\n" \
40 "Connection: %s\r\n"
41 #define RFCTIME \
42 "%a, %d %b %Y %H:%M:%S GMT"
43 #define BOUNDARY \
44 "XXX_CUT_HERE_%ld_XXX"
45
46 void
47 mkerror(struct REQUEST *req, int status, int ka)
48 {
49 int i;
50 for (i = 0; http[i].status != 0; i++)
51 if (http[i].status == status)
52 break;
53 req->status = status;
54 req->body = http[i].body;
55 req->lbody = strlen(req->body);
56 if (!ka)
57 req->keep_alive = 0;
58 req->lres = sprintf(req->hres,
59 RESPONSE_START
60 "Content-Type: text/plain\r\n"
61 "Content-Length: %d\r\n",
62 http[i].head,server_name,
63 req->keep_alive ? "Keep-Alive" : "Close",
64 req->lbody);
65 if (401 == status)
66 req->lres += sprintf(req->hres+req->lres,
67 "WWW-Authenticate: Basic, realm=\"webfs\"\r\n");
68 req->lres += strftime(req->hres+req->lres,80,
69 "Date: " RFCTIME "\r\n\r\n",
70 gmtime(&now));
71 req->state = STATE_WRITE_HEADER;
72 if (debug)
73 fprintf(stderr,"%03d: error: %d, connection=%s\n",
74 req->fd, status, req->keep_alive ? "Keep-Alive" : "Close");
75 }
76
77 void
78 mkredirect(struct REQUEST *req)
79 {
80 req->status = 302;
81 req->body = req->path;
82 req->lbody = strlen(req->body);
83 req->lres = sprintf(req->hres,
84 RESPONSE_START
85 "Location: http://%s:%d%s\r\n"
86 "Content-Type: text/plain\r\n"
87 "Content-Length: %d\r\n",
88 "302 Redirect",server_name,
89 req->keep_alive ? "Keep-Alive" : "Close",
90 req->hostname,tcp_port,req->path,
91 req->lbody);
92 req->lres += strftime(req->hres+req->lres,80,
93 "Date: " RFCTIME "\r\n\r\n",
94 gmtime(&now));
95 req->state = STATE_WRITE_HEADER;
96 if (debug)
97 fprintf(stderr,"%03d: 302 redirect: %s, connection=%s\n",
98 req->fd, req->path, req->keep_alive ? "Keep-Alive" : "Close");
99 }
100
101 void
102 mkheader(struct REQUEST *req, int status, time_t mtime)
103 {
104 int i;
105 for (i = 0; http[i].status != 0; i++)
106 if (http[i].status == status)
107 break;
108 req->status = status;
109 req->lres = sprintf(req->hres,
110 RESPONSE_START,
111 http[i].head,server_name,
112 req->keep_alive ? "Keep-Alive" : "Close");
113 req->lres += sprintf(req->hres+req->lres,
114 "Content-Type: %s\r\n"
115 "Content-Length: %d\r\n",
116 req->mime,
117 req->lbody);
118 if (mtime != -1)
119 req->lres += strftime(req->hres+req->lres,80,
120 "Last-Modified: " RFCTIME "\r\n",
121 gmtime(&mtime));
122 req->lres += strftime(req->hres+req->lres,80,
123 "Date: " RFCTIME "\r\n\r\n",
124 gmtime(&now));
125 req->state = STATE_WRITE_HEADER;
126 if (debug)
127 fprintf(stderr,"%03d: %d, connection=%s\n",
128 req->fd, status, req->keep_alive ? "Keep-Alive" : "Close");
129 }
130
131 /* ---------------------------------------------------------------------- */
132
133 void write_request(struct REQUEST *req)
134 {
135 int rc;
136
137 for (;;) {
138 switch (req->state) {
139 case STATE_WRITE_HEADER:
140 rc = write(req->fd,req->hres + req->written,
141 req->lres - req->written);
142 switch (rc) {
143 case -1:
144 if (errno == EAGAIN)
145 return;
146 if (errno == EINTR)
147 continue;
148 xperror(LOG_INFO,"write",req->peerhost);
149 /* fall through */
150 case 0:
151 req->state = STATE_CLOSE;
152 return;
153 default:
154 req->written += rc;
155 req->bc += rc;
156 if (req->written != req->lres)
157 return;
158 }
159 req->written = 0;
160 if (req->head_only) {
161 req->state = STATE_FINISHED;
162 return;
163 } else {
164 req->state = STATE_WRITE_BODY;
165 }
166 break;
167 case STATE_WRITE_BODY:
168 rc = write(req->fd,req->body + req->written,
169 req->lbody - req->written);
170 switch (rc) {
171 case -1:
172 if (errno == EAGAIN)
173 return;
174 if (errno == EINTR)
175 continue;
176 xperror(LOG_INFO,"write",req->peerhost);
177 /* fall through */
178 case 0:
179 req->state = STATE_CLOSE;
180 return;
181 default:
182 req->written += rc;
183 req->bc += rc;
184 if (req->written != req->lbody)
185 return;
186 }
187 req->state = STATE_FINISHED;
188 return;
189 } /* switch(state) */
190 } /* for (;;) */
191 }
192
|
This page was automatically generated by the
LXR engine.
|