. Added redirect().

. Moved 404 reply up to stat() section.
. Redirect /dir to /dir/
. Separate permissions (403 Forbidden) from other fopen() failures
  (500 Internal Server Error)
This commit is contained in:
Emil Mikulic 2003-11-24 11:44:22 +00:00
parent eee798c571
commit e74bb5a077
1 changed files with 61 additions and 11 deletions

View File

@ -1221,6 +1221,48 @@ static void default_reply(struct connection *conn,
/* ---------------------------------------------------------------------------
* Redirection.
*/
static void redirect(struct connection *conn, const char *format, ...)
{
char *where, date[DATE_LEN];
va_list va;
va_start(va, format);
xvasprintf(&where, format, va);
va_end(va);
/* Only really need to calculate the date once. */
(void)rfc1123_date(date, time(NULL));
conn->reply_length = xasprintf(&(conn->reply),
"<html><head><title>301 Moved Permanently</title></head><body>\n"
"<h1>Moved Permanently</h1>\n"
"Moved to: <a href=\"%s\">%s</a>\n" /* where x 2 */
"<hr>\n"
"Generated by %s on %s\n"
"</body></html>\n",
where, where, pkgname, date);
conn->header_length = xasprintf(&(conn->header),
"HTTP/1.1 301 Moved Permanently\r\n"
"Date: %s\r\n"
"Server: %s\r\n"
"Location: %s\r\n"
"%s" /* keep-alive */
"Content-Length: %d\r\n"
"Content-Type: text/html\r\n"
"\r\n",
date, pkgname, where, keep_alive(conn), conn->reply_length);
free(where);
conn->reply_type = REPLY_GENERATED;
conn->http_code = 301;
}
/* ---------------------------------------------------------------------------
* Parses a single HTTP request field. Returns string from end of [field] to
* first \r, \n or end of request string. Returns NULL if [field] can't be
@ -1426,14 +1468,23 @@ static void process_get(struct connection *conn)
*/
if (stat(target, &filestat) == -1)
{
default_reply(conn, 500, "Internal Server Error",
"stat() failed: %s.", strerror(errno));
if (errno == ENOENT)
default_reply(conn, 404, "Not Found",
"The URI you requested (%s) was not found.", conn->uri);
else
default_reply(conn, 500, "Internal Server Error",
"stat(%s) failed: %s.", conn->uri, strerror(errno));
return;
}
/* make sure it's a regular file */
if (!S_ISREG(filestat.st_mode))
/*(filestat.st_mode & S_IFMT) != S_IFREG)*/
if (S_ISDIR(filestat.st_mode))
{
redirect(conn, "%s/", conn->uri);
return;
}
else if (!S_ISREG(filestat.st_mode))
{
default_reply(conn, 403, "Forbidden", "Not a regular file.");
return;
@ -1445,19 +1496,18 @@ static void process_get(struct connection *conn)
if (conn->reply_file == NULL)
{
/* fopen() failed */
if (errno == ENOENT)
default_reply(conn, 404, "Not Found",
"The URI you requested (%s) was not found.", conn->uri);
else
if (errno == EACCES)
default_reply(conn, 403, "Forbidden",
"The URI you requested (%s) cannot be returned.<br>\n"
"%s.", /* reason why */
"You don't have permission to access (%s).", conn->uri);
else
default_reply(conn, 500, "Internal Server Error",
"The URI you requested (%s) cannot be returned: %s.",
conn->uri, strerror(errno));
return;
}
/* get information on the file */
/* get information on the file, again, just in case */
if (fstat(fileno(conn->reply_file), &filestat) == -1)
{
default_reply(conn, 500, "Internal Server Error",