1 /* HTTP response codes */
4 #define _GNU_SOURCE /* Needed for asprintf() */
13 #include "cache/cache.h"
14 #include "intl/gettext/libintl.h"
15 #include "network/connection.h"
16 #include "protocol/http/codes.h"
17 #include "protocol/uri.h"
18 #include "session/session.h"
19 #include "session/task.h"
20 #include "terminal/terminal.h"
21 #include "terminal/window.h"
22 #include "util/snprintf.h"
23 #include "viewer/text/draw.h"
28 const unsigned char *str
;
31 /* Source: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html */
32 static const struct http_code http_code
[] = {
34 { 101, "Switching Protocols" },
38 { 203, "Non-Authoritative Information" },
39 { 204, "No Content" },
40 { 205, "Reset Content" },
41 { 206, "Partial Content" },
42 { 300, "Multiple Choices" },
43 { 301, "Moved Permanently" },
46 { 304, "Not Modified" },
49 { 307, "Temporary Redirect" },
50 { 400, "Bad Request" },
51 { 401, "Unauthorized" },
52 { 402, "Payment Required" },
55 { 405, "Method Not Allowed" },
56 { 406, "Not Acceptable" },
57 { 407, "Proxy Authentication Required" },
58 { 408, "Request Timeout" },
61 { 411, "Length Required" },
62 { 412, "Precondition Failed" },
63 { 413, "Request Entity Too Large" },
64 { 414, "Request-URI Too Long" },
65 { 415, "Unsupported Media Type" },
66 { 416, "Requested Range Not Satisfiable" },
67 { 417, "Expectation Failed" },
68 { 500, "Internal Server Error" },
69 { 501, "Not Implemented" },
70 { 502, "Bad Gateway" },
71 { 503, "Service Unavailable" },
72 { 504, "Gateway Timeout" },
73 { 505, "HTTP Version Not Supported" },
77 compare_http_codes(const void *key
, const void *element
)
79 int first
= (long) key
;
80 int second
= ((const struct http_code
*) element
)->num
;
82 return first
- second
;
85 static const unsigned char *
86 http_code_to_string(int code
)
88 const struct http_code
*element
89 = bsearch((void *) (long) code
, http_code
,
90 sizeof_array(http_code
),
94 if (element
) return element
->str
;
100 /* TODO: Some short intermediate document for the 3xx messages? --pasky */
101 static unsigned char *
102 get_http_error_document(struct terminal
*term
, struct uri
*uri
, int code
)
104 const unsigned char *codestr
= http_code_to_string(code
);
105 unsigned char *title
= asprintfa(_("HTTP error %03d", term
), code
);
106 struct string string
;
108 if (!codestr
) codestr
= "Unknown error";
110 if (!init_string(&string
)) {
115 add_format_to_string(&string
,
117 " <head><title>%s</title></head>\n"
119 " <h1 align=\"left\">%s: %s</h1>\n"
124 , title
, title
, codestr
);
127 add_format_to_string(&string
, _(
128 " An error occurred on the server while fetching the document you\n"
129 " requested. However, the server did not send back any explanation of what\n"
130 " happened, so it is unknown what went wrong. Please contact the web\n"
131 " server administrator about this, if you believe that this error should\n"
132 " not occur since it is not a nice behaviour from the web server at all\n"
133 " and indicates that there is some much deeper problem with the web server\n"
137 add_format_to_string(&string
,
140 " URI: <a href=\"%s\">%s</a>\n", struri(uri
), struri(uri
));
142 add_format_to_string(&string
,
152 return string
.source
;
155 struct http_error_info
{
161 show_http_error_document(struct session
*ses
, void *data
)
163 struct http_error_info
*info
= data
;
164 struct terminal
*term
= ses
->tab
->term
;
165 struct cache_entry
*cached
= find_in_cache(info
->uri
);
166 struct cache_entry
*cache
= cached
? cached
: get_cache_entry(info
->uri
);
167 unsigned char *str
= NULL
;
169 if (cache
) str
= get_http_error_document(term
, info
->uri
, info
->code
);
172 /* The codepage that _("foo", term) used when it was
173 * called by get_http_error_document. */
174 const int gettext_codepage
= get_terminal_codepage(term
);
176 if (cached
) delete_entry_content(cache
);
178 /* If we run out of memory here, it's perhaps better
179 * to display a malformatted error message than none
181 mem_free_set(&cache
->content_type
, stracpy("text/html"));
182 mem_free_set(&cache
->head
,
183 straconcat("\r\nContent-Type: text/html; charset=",
184 get_cp_mime_name(gettext_codepage
),
185 "\r\n", (unsigned char *) NULL
));
186 add_fragment(cache
, 0, str
, strlen(str
));
189 draw_formatted(ses
, 1);
198 http_error_document(struct connection
*conn
, int code
)
200 struct http_error_info
*info
;
202 assert(conn
&& conn
->uri
);
204 info
= mem_calloc(1, sizeof(*info
));
208 info
->uri
= get_uri_reference(conn
->uri
);
210 add_questions_entry(show_http_error_document
, info
);