/[hydra]/hydra/src/response.c
ViewVC logotype

Annotation of /hydra/src/response.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations)
Wed Sep 25 20:39:04 2002 UTC (21 years, 6 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_0_2
Changes since 1.5: +28 -31 lines
File MIME type: text/plain
Cleanups

1 nmav 1.1 /*
2     * Boa, an http server
3     * Copyright (C) 1995 Paul Phillips <paulp@go2net.com>
4     * Some changes Copyright (C) 1996 Larry Doolittle <ldoolitt@boa.org>
5     * Some changes Copyright (C) 1996-99 Jon Nelson <jnelson@boa.org>
6     *
7     * This program is free software; you can redistribute it and/or modify
8     * it under the terms of the GNU General Public License as published by
9     * the Free Software Foundation; either version 1, or (at your option)
10     * any later version.
11     *
12     * This program is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with this program; if not, write to the Free Software
19     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     *
21     */
22    
23 nmav 1.6 /* $Id: response.c,v 1.5 2002/09/25 19:55:53 nmav Exp $*/
24 nmav 1.1
25     #include "boa.h"
26    
27     void print_content_type(request * req)
28     {
29     req_write(req, "Content-Type: ");
30     req_write(req, get_mime_type(req->request_uri));
31     req_write(req, "\r\n");
32     }
33    
34     void print_content_length(request * req)
35     {
36 nmav 1.2 char buf[22];
37 nmav 1.3
38     simple_itoa( (req->range_stop)-(req->range_start), buf);
39 nmav 1.1 req_write(req, "Content-Length: ");
40 nmav 1.2 req_write(req, buf);
41 nmav 1.1 req_write(req, "\r\n");
42     }
43    
44 nmav 1.3 void print_content_range(request * req)
45     {
46     char start[22];
47     char stop[22];
48     char total[22];
49     char buf[22*3 + 5];
50    
51     req_write(req, "Content-Range: bytes ");
52    
53     simple_itoa( req->range_stop, stop);
54     simple_itoa( req->range_start, start);
55     simple_itoa( req->filesize, total);
56    
57     sprintf( buf, "%s-%s/%s\r\n", start, stop, total);
58     req_write(req, buf);
59     }
60    
61 nmav 1.1 void print_last_modified(request * req)
62     {
63 nmav 1.2 char lm[] = "Last-Modified: "
64 nmav 1.1 " " "\r\n";
65     rfc822_time_buf(lm + 15, req->last_modified);
66     req_write(req, lm);
67     }
68    
69     void print_ka_phrase(request * req)
70     {
71 nmav 1.2
72 nmav 1.1 if (req->kacount > 0 &&
73     req->keepalive == KA_ACTIVE && req->response_status < 500) {
74 nmav 1.2 char buf[22];
75 nmav 1.1 req_write(req, "Connection: Keep-Alive\r\nKeep-Alive: timeout=");
76 nmav 1.2 simple_itoa(ka_timeout, buf);
77     req_write(req, buf);
78 nmav 1.1 req_write(req, ", max=");
79 nmav 1.2 simple_itoa(req->kacount, buf);
80     req_write(req, buf);
81 nmav 1.1 req_write(req, "\r\n");
82     } else
83     req_write(req, "Connection: close\r\n");
84     }
85    
86     extern char * version;
87    
88     void print_http_headers(request * req)
89     {
90 nmav 1.2 char date_stuff[] = "Date: "
91 nmav 1.1 " "
92     "\r\n";
93    
94     static char tls_version_stuff[64] = "\0";
95 nmav 1.5 static char version_stuff[] = "Server: "SERVER_NAME"/"SERVER_VERSION"\r\n";
96 nmav 1.1
97     #ifdef ENABLE_SSL
98     if ( tls_version_stuff[0] == 0) {
99 nmav 1.5 strcpy( tls_version_stuff, "Server: "SERVER_NAME"/"SERVER_VERSION" GnuTLS/");
100 nmav 1.1 strcat( tls_version_stuff, gnutls_check_version(NULL));
101     strcat( tls_version_stuff, "\r\n");
102     }
103     #endif
104    
105     rfc822_time_buf(date_stuff + 6, 0);
106    
107     req_write(req, date_stuff);
108    
109     if (!req->secure)
110     req_write(req, version_stuff);
111     else
112     req_write(req, tls_version_stuff);
113    
114 nmav 1.3 req_write(req, "Accept-Ranges: bytes\r\n");
115 nmav 1.1 print_ka_phrase(req);
116     }
117    
118     /* The routines above are only called by the routines below.
119     * The rest of Boa only enters through the routines below.
120     */
121    
122     /* R_REQUEST_OK: 200 */
123     void send_r_request_ok(request * req)
124     {
125     req->response_status = R_REQUEST_OK;
126     if (req->simple)
127     return;
128    
129 nmav 1.6 req_write(req, HTTP_VERSION" 200 OK\r\n");
130 nmav 1.1 print_http_headers(req);
131    
132     if (!req->is_cgi) {
133     print_content_length(req);
134     print_last_modified(req);
135     print_content_type(req);
136     req_write(req, "\r\n");
137     }
138     }
139    
140 nmav 1.3 /* R_REQUEST_PARTIAL: 206 */
141     void send_r_request_partial(request * req)
142     {
143     req->response_status = R_REQUEST_PARTIAL;
144     if (req->simple)
145     return;
146    
147 nmav 1.6 req_write(req, HTTP_VERSION" 206 Partial content\r\n");
148 nmav 1.3 print_http_headers(req);
149    
150     if (!req->is_cgi) {
151     print_content_length(req);
152     print_content_range(req);
153     print_last_modified(req);
154     print_content_type(req);
155     req_write(req, "\r\n");
156     }
157     }
158    
159 nmav 1.1 /* R_MOVED_PERM: 301 */
160     void send_r_moved_perm(request * req, char *url)
161     {
162     SQUASH_KA(req);
163     req->response_status = R_MOVED_PERM;
164     if (!req->simple) {
165 nmav 1.6 req_write(req, HTTP_VERSION" 301 Moved Permanently\r\n");
166 nmav 1.1 print_http_headers(req);
167 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n");
168 nmav 1.1
169     req_write(req, "Location: ");
170     req_write_escape_http(req, url);
171     req_write(req, "\r\n\r\n");
172     }
173     if (req->method != M_HEAD) {
174     req_write(req,
175     "<HTML><HEAD><TITLE>301 Moved Permanently</TITLE></HEAD>\n"
176     "<BODY>\n<H1>301 Moved</H1>The document has moved\n"
177     "<A HREF=\"");
178     req_write_escape_html(req, url);
179     req_write(req, "\">here</A>.\n</BODY></HTML>\n");
180     }
181     req_flush(req);
182     }
183    
184     /* R_MOVED_TEMP: 302 */
185     void send_r_moved_temp(request * req, char *url, char *more_hdr)
186     {
187     SQUASH_KA(req);
188     req->response_status = R_MOVED_TEMP;
189     if (!req->simple) {
190 nmav 1.6 req_write(req, HTTP_VERSION" 302 Moved Temporarily\r\n");
191 nmav 1.1 print_http_headers(req);
192 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n");
193 nmav 1.1
194     req_write(req, "Location: ");
195     req_write_escape_http(req, url);
196     req_write(req, "\r\n");
197     req_write(req, more_hdr);
198     req_write(req, "\r\n\r\n");
199     }
200     if (req->method != M_HEAD) {
201     req_write(req,
202     "<HTML><HEAD><TITLE>302 Moved Temporarily</TITLE></HEAD>\n"
203     "<BODY>\n<H1>302 Moved</H1>The document has moved\n"
204     "<A HREF=\"");
205     req_write_escape_html(req, url);
206     req_write(req, "\">here</A>.\n</BODY></HTML>\n");
207     }
208     req_flush(req);
209     }
210    
211     /* R_NOT_MODIFIED: 304 */
212     void send_r_not_modified(request * req)
213     {
214     SQUASH_KA(req);
215     req->response_status = R_NOT_MODIFIED;
216 nmav 1.6 req_write(req, HTTP_VERSION" 304 Not Modified\r\n");
217 nmav 1.1 print_http_headers(req);
218     print_content_type(req);
219     req_write(req, "\r\n");
220     req_flush(req);
221     }
222    
223     /* R_BAD_REQUEST: 400 */
224     void send_r_bad_request(request * req)
225     {
226     SQUASH_KA(req);
227     req->response_status = R_BAD_REQUEST;
228     if (!req->simple) {
229 nmav 1.6 req_write(req, HTTP_VERSION" 400 Bad Request\r\n");
230 nmav 1.1 print_http_headers(req);
231 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
232 nmav 1.1 }
233     if (req->method != M_HEAD)
234     req_write(req,
235     "<HTML><HEAD><TITLE>400 Bad Request</TITLE></HEAD>\n"
236     "<BODY><H1>400 Bad Request</H1>\nYour client has issued "
237     "a malformed or illegal request.\n</BODY></HTML>\n");
238     req_flush(req);
239     }
240    
241     /* R_UNAUTHORIZED: 401 */
242     void send_r_unauthorized(request * req, char *realm_name)
243     {
244     SQUASH_KA(req);
245     req->response_status = R_UNAUTHORIZED;
246     if (!req->simple) {
247 nmav 1.6 req_write(req, HTTP_VERSION" 401 Unauthorized\r\n");
248 nmav 1.1 print_http_headers(req);
249     req_write(req, "WWW-Authenticate: Basic realm=\"");
250     req_write(req, realm_name);
251     req_write(req, "\"\r\n");
252 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
253 nmav 1.1 }
254     if (req->method != M_HEAD) {
255     req_write(req,
256     "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n"
257     "<BODY><H1>401 Unauthorized</H1>\nYour client does not "
258     "have permission to get URL ");
259     req_write_escape_html(req, req->request_uri);
260     req_write(req, " from this server.\n</BODY></HTML>\n");
261     }
262     req_flush(req);
263     }
264    
265     /* R_FORBIDDEN: 403 */
266     void send_r_forbidden(request * req)
267     {
268     SQUASH_KA(req);
269     req->response_status = R_FORBIDDEN;
270     if (!req->simple) {
271 nmav 1.6 req_write(req, HTTP_VERSION" 403 Forbidden\r\n");
272 nmav 1.1 print_http_headers(req);
273 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
274 nmav 1.1 }
275     if (req->method != M_HEAD) {
276     req_write(req, "<HTML><HEAD><TITLE>403 Forbidden</TITLE></HEAD>\n"
277     "<BODY><H1>403 Forbidden</H1>\nYour client does not "
278     "have permission to get URL ");
279     req_write_escape_html(req, req->request_uri);
280     req_write(req, " from this server.\n</BODY></HTML>\n");
281     }
282     req_flush(req);
283     }
284    
285     /* R_NOT_FOUND: 404 */
286     void send_r_not_found(request * req)
287     {
288     SQUASH_KA(req);
289     req->response_status = R_NOT_FOUND;
290     if (!req->simple) {
291 nmav 1.6 req_write(req, HTTP_VERSION" 404 Not Found\r\n");
292 nmav 1.1 print_http_headers(req);
293 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
294 nmav 1.1 }
295     if (req->method != M_HEAD) {
296     req_write(req, "<HTML><HEAD><TITLE>404 Not Found</TITLE></HEAD>\n"
297     "<BODY><H1>404 Not Found</H1>\nThe requested URL ");
298     req_write_escape_html(req, req->request_uri);
299     req_write(req, " was not found on this server.\n</BODY></HTML>\n");
300     }
301     req_flush(req);
302     }
303 nmav 1.3
304     /* R_RANGE_UNSATISFIABLE: 416 */
305     void send_r_range_unsatisfiable(request * req)
306     {
307     req->response_status = R_RANGE_UNSATISFIABLE;
308     if (req->simple)
309     return;
310    
311     if (!req->simple) {
312 nmav 1.6 req_write(req, HTTP_VERSION" 416 Range Not Satisfiable\r\n");
313 nmav 1.3 print_http_headers(req);
314 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
315 nmav 1.3 }
316     if (req->method != M_HEAD) {
317     char int1[22], int2[22];
318     char range[45];
319     req_write(req, "<HTML><HEAD><TITLE>416 Range Not Satisfiable</TITLE></HEAD>\n"
320     "<BODY><H1>416 Range Not Satisfiable</H1>\nThe requested range URL ");
321     req_write_escape_html(req, req->request_uri);
322     req_write( req, " had illegal range( ");
323    
324     simple_itoa( req->range_start, int1);
325     simple_itoa( req->range_stop, int2);
326     fprintf(stderr, "range: %d-%d\n", req->range_start, req->range_stop);
327     sprintf( range, "%s-%s", int1, int2);
328     req_write(req, range);
329     req_write(req, " ).\n</BODY></HTML>\n");
330     }
331     req_flush(req);
332     }
333    
334 nmav 1.1
335     /* R_ERROR: 500 */
336     void send_r_error(request * req)
337     {
338     SQUASH_KA(req);
339     req->response_status = R_ERROR;
340     if (!req->simple) {
341 nmav 1.6 req_write(req, HTTP_VERSION" 500 Server Error\r\n");
342 nmav 1.1 print_http_headers(req);
343 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
344 nmav 1.1 }
345     if (req->method != M_HEAD) {
346     req_write(req,
347     "<HTML><HEAD><TITLE>500 Server Error</TITLE></HEAD>\n"
348     "<BODY><H1>500 Server Error</H1>\nThe server encountered "
349     "an internal error and could not complete your request.\n"
350     "</BODY></HTML>\n");
351     }
352     req_flush(req);
353     }
354    
355     /* R_NOT_IMP: 501 */
356     void send_r_not_implemented(request * req)
357     {
358     SQUASH_KA(req);
359     req->response_status = R_NOT_IMP;
360     if (!req->simple) {
361 nmav 1.6 req_write(req, HTTP_VERSION" 501 Not Implemented\r\n");
362 nmav 1.1 print_http_headers(req);
363 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
364 nmav 1.1 }
365     if (req->method != M_HEAD) {
366     req_write(req,
367     "<HTML><HEAD><TITLE>501 Not Implemented</TITLE></HEAD>\n"
368     "<BODY><H1>501 Not Implemented</H1>\nPOST to non-script "
369     "is not supported in Boa.\n</BODY></HTML>\n");
370     }
371     req_flush(req);
372     }
373    
374     /* R_BAD_GATEWAY: 502 */
375     void send_r_bad_gateway(request * req)
376     {
377     SQUASH_KA(req);
378     req->response_status = R_BAD_GATEWAY;
379     if (!req->simple) {
380 nmav 1.6 req_write(req, HTTP_VERSION" 502 Bad Gateway" CRLF);
381 nmav 1.1 print_http_headers(req);
382 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML CRLF CRLF); /* terminate header */
383 nmav 1.1 }
384     if (req->method != M_HEAD) {
385     req_write(req,
386     "<HTML><HEAD><TITLE>502 Bad Gateway</TITLE></HEAD>\n"
387     "<BODY><H1>502 Bad Gateway</H1>\nThe CGI was "
388     "not CGI/1.1 compliant.\n" "</BODY></HTML>\n");
389     }
390     req_flush(req);
391     }
392    
393     /* R_SERVICE_UNAVAILABLE: 503 */
394     void send_r_service_unavailable(request * req) /* 503 */
395     {
396 nmav 1.2 static const char body[] =
397 nmav 1.1 "<HTML><HEAD><TITLE>503 Service Unavailable</TITLE></HEAD>\n"
398     "<BODY><H1>503 Service Unavailable</H1>\n"
399     "There are too many connections in use right now.\r\n"
400     "Please try again later.\r\n</BODY></HTML>\n";
401     static int _body_len;
402 nmav 1.2 static char body_len[22];
403 nmav 1.1
404     if (!_body_len)
405     _body_len = strlen(body);
406 nmav 1.2 if (!body_len[0])
407     simple_itoa( _body_len, body_len);
408 nmav 1.1
409     SQUASH_KA(req);
410     req->response_status = R_SERVICE_UNAV;
411     if (!req->simple) {
412 nmav 1.6 req_write(req, HTTP_VERSION" 503 Service Unavailable\r\n");
413 nmav 1.1 print_http_headers(req);
414     if (body_len) {
415     req_write(req, "Content-Length: ");
416     req_write(req, body_len);
417     req_write(req, "\r\n");
418     }
419 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header
420 nmav 1.1 */
421     }
422     if (req->method != M_HEAD) {
423     req_write(req, body);
424     }
425     req_flush(req);
426     }
427    
428    
429     /* R_NOT_IMP: 505 */
430     void send_r_bad_version(request * req)
431     {
432     SQUASH_KA(req);
433     req->response_status = R_BAD_VERSION;
434     if (!req->simple) {
435 nmav 1.6 req_write(req, HTTP_VERSION" 505 HTTP Version Not Supported\r\n");
436 nmav 1.1 print_http_headers(req);
437 nmav 1.6 req_write(req, "Content-Type: " TEXT_HTML "\r\n\r\n"); /* terminate header */
438 nmav 1.1 }
439     if (req->method != M_HEAD) {
440     req_write(req,
441     "<HTML><HEAD><TITLE>505 HTTP Version Not Supported</TITLE></HEAD>\n"
442     "<BODY><H1>505 HTTP Version Not Supported</H1>\nHTTP versions "
443     "other than 0.9 and 1.0 "
444     "are not supported in Boa.\n<p><p>Version encountered: ");
445     req_write(req, req->http_version);
446     req_write(req, "<p><p></BODY></HTML>\n");
447     }
448     req_flush(req);
449     }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26