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
|
* 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
|
* 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)
|
if (stat(target, &filestat) == -1)
|
||||||
{
|
{
|
||||||
|
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",
|
default_reply(conn, 500, "Internal Server Error",
|
||||||
"stat() failed: %s.", strerror(errno));
|
"stat(%s) failed: %s.", conn->uri, strerror(errno));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make sure it's a regular file */
|
/* make sure it's a regular file */
|
||||||
if (!S_ISREG(filestat.st_mode))
|
if (S_ISDIR(filestat.st_mode))
|
||||||
/*(filestat.st_mode & S_IFMT) != S_IFREG)*/
|
{
|
||||||
|
redirect(conn, "%s/", conn->uri);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!S_ISREG(filestat.st_mode))
|
||||||
{
|
{
|
||||||
default_reply(conn, 403, "Forbidden", "Not a regular file.");
|
default_reply(conn, 403, "Forbidden", "Not a regular file.");
|
||||||
return;
|
return;
|
||||||
@ -1445,19 +1496,18 @@ static void process_get(struct connection *conn)
|
|||||||
if (conn->reply_file == NULL)
|
if (conn->reply_file == NULL)
|
||||||
{
|
{
|
||||||
/* fopen() failed */
|
/* fopen() failed */
|
||||||
if (errno == ENOENT)
|
if (errno == EACCES)
|
||||||
default_reply(conn, 404, "Not Found",
|
|
||||||
"The URI you requested (%s) was not found.", conn->uri);
|
|
||||||
else
|
|
||||||
default_reply(conn, 403, "Forbidden",
|
default_reply(conn, 403, "Forbidden",
|
||||||
"The URI you requested (%s) cannot be returned.<br>\n"
|
"You don't have permission to access (%s).", conn->uri);
|
||||||
"%s.", /* reason why */
|
else
|
||||||
|
default_reply(conn, 500, "Internal Server Error",
|
||||||
|
"The URI you requested (%s) cannot be returned: %s.",
|
||||||
conn->uri, strerror(errno));
|
conn->uri, strerror(errno));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get information on the file */
|
/* get information on the file, again, just in case */
|
||||||
if (fstat(fileno(conn->reply_file), &filestat) == -1)
|
if (fstat(fileno(conn->reply_file), &filestat) == -1)
|
||||||
{
|
{
|
||||||
default_reply(conn, 500, "Internal Server Error",
|
default_reply(conn, 500, "Internal Server Error",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user