mirror of
https://github.com/emikulic/darkhttpd.git
synced 2023-08-10 21:13:08 +03:00
. 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:
parent
eee798c571
commit
e74bb5a077
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user