Add to git.
[rws.git] / errors.c
1 /* Deliver errors back to the user.
2  * - by Richard W.M. Jones <rich@annexia.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  *
18  * $Id: errors.c,v 1.5 2002/12/01 14:58:01 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <pool.h>
24
25 #include <pthr_pseudothread.h>
26 #include <pthr_http.h>
27 #include <pthr_iolib.h>
28
29 #include "process_rq.h"
30 #include "cfg.h"
31 #include "errors.h"
32
33 int
34 bad_request_error (process_rq p, const char *text)
35 {
36   http_response http_response;
37   int close;
38   const char *maintainer;
39
40   maintainer = cfg_get_string (p->host, p->alias,
41                                "maintainer", "(no maintainer)"); /* XXX */
42
43   http_response = new_http_response (p->pool, p->http_request, p->io,
44                                      500, "Internal server error");
45   http_response_send_headers (http_response,
46                               /* Content type. */
47                               "Content-Type", "text/html",
48                               NO_CACHE_HEADERS,
49                               /* End of headers. */
50                               NULL);
51   close = http_response_end_headers (http_response);
52
53   if (http_request_is_HEAD (p->http_request)) return close;
54
55   /* XXX Escaping. */
56   io_fprintf (p->io,
57               "<html><head><title>Internal server error</title></head>" CRLF
58               "<body bgcolor=\"#ffffff\">" CRLF
59               "<h1>500 Internal server error</h1>" CRLF
60               "There was an error serving this request:" CRLF
61               "<pre>" CRLF
62               "%s" CRLF
63               "</pre>" CRLF
64               "<hr>" CRLF
65               "<address>%s</address>" CRLF
66               "</body></html>" CRLF,
67               text, maintainer);
68
69   /* It's always a good idea to force the connection to close after an
70    * error. This is particularly important with monolith applications
71    * after they have thrown an exception.
72    */
73   /* return close; */
74   return 1;
75 }
76
77 int
78 file_not_found_error (process_rq p)
79 {
80   http_response http_response;
81   int close;
82   const char *maintainer;
83
84   maintainer = cfg_get_string (p->host, p->alias,
85                                "maintainer", "(no maintainer)");
86
87   http_response = new_http_response (p->pool, p->http_request, p->io,
88                                      404, "File or directory not found");
89   http_response_send_headers (http_response,
90                               /* Content type. */
91                               "Content-Type", "text/html",
92                               NO_CACHE_HEADERS,
93                               /* End of headers. */
94                               NULL);
95   close = http_response_end_headers (http_response);
96
97   if (http_request_is_HEAD (p->http_request)) return close;
98
99   io_fprintf (p->io,
100               "<html><head><title>File or directory not found</title></head>" CRLF
101               "<body bgcolor=\"#ffffff\">" CRLF
102               "<h1>404 File or directory not found</h1>" CRLF
103               "The file you requested was not found on this server." CRLF
104               "<hr>" CRLF
105               "<address>%s</address>" CRLF
106               "</body></html>" CRLF,
107               maintainer);
108
109   return close;
110 }
111
112 int
113 moved_permanently (process_rq p, const char *location)
114 {
115   http_response http_response;
116   int close;
117
118   http_response = new_http_response (p->pool, p->http_request, p->io,
119                                      301, "Moved permanently");
120   http_response_send_headers (http_response,
121                               /* Content length. */
122                               "Content-Length", "0",
123                               /* Location. */
124                               "Location", location,
125                               /* End of headers. */
126                               NULL);
127   close = http_response_end_headers (http_response);
128
129   if (http_request_is_HEAD (p->http_request)) return close;
130
131   return close;
132 }