mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-26 22:23:17 -05:00
[httpd] Serve index.html if requested source is a directory
Defaults to an index.html file instead of redirecting to admin.html. It will not redirect to index.html, but instead serve the file (if exists) directly. This allows nicer uris in the webinterface. We will still redirect to admin.html if no index.html is found for requests to http://ip:port/
This commit is contained in:
parent
8012be596e
commit
a764fb3c52
104
src/httpd.c
104
src/httpd.c
@ -255,12 +255,25 @@ httpd_fixup_uri(struct evhttp_request *req)
|
||||
|
||||
/* --------------------------- REQUEST HELPERS ------------------------------ */
|
||||
|
||||
|
||||
|
||||
void
|
||||
httpd_redirect_to_admin(struct evhttp_request *req)
|
||||
{
|
||||
struct evkeyvalq *headers;
|
||||
|
||||
headers = evhttp_request_get_output_headers(req);
|
||||
evhttp_add_header(headers, "Location", "/admin.html");
|
||||
|
||||
httpd_send_reply(req, HTTP_MOVETEMP, "Moved", NULL, HTTPD_SEND_NO_GZIP);
|
||||
}
|
||||
|
||||
static void
|
||||
serve_file(struct evhttp_request *req, const char *uri)
|
||||
{
|
||||
char *ext;
|
||||
char path[PATH_MAX];
|
||||
char *deref;
|
||||
char deref[PATH_MAX];
|
||||
char *ctype;
|
||||
struct evbuffer *evbuf;
|
||||
struct evkeyvalq *input_headers;
|
||||
@ -272,6 +285,7 @@ serve_file(struct evhttp_request *req, const char *uri)
|
||||
const char *modified_since;
|
||||
char last_modified[1000];
|
||||
struct tm *tm_modified;
|
||||
bool slashed;
|
||||
int ret;
|
||||
|
||||
/* Check authentication */
|
||||
@ -298,16 +312,9 @@ serve_file(struct evhttp_request *req, const char *uri)
|
||||
return;
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
if (S_ISLNK(sb.st_mode))
|
||||
{
|
||||
httpd_redirect_to_index(req, uri);
|
||||
|
||||
return;
|
||||
}
|
||||
else if (S_ISLNK(sb.st_mode))
|
||||
{
|
||||
deref = realpath(path, NULL);
|
||||
if (!deref)
|
||||
if (!realpath(path, deref))
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Could not dereference %s: %s\n", path, strerror(errno));
|
||||
|
||||
@ -322,12 +329,10 @@ serve_file(struct evhttp_request *req, const char *uri)
|
||||
|
||||
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
|
||||
|
||||
free(deref);
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(path, deref);
|
||||
free(deref);
|
||||
|
||||
ret = stat(path, &sb);
|
||||
if (ret < 0)
|
||||
@ -338,13 +343,38 @@ serve_file(struct evhttp_request *req, const char *uri)
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
{
|
||||
httpd_redirect_to_index(req, uri);
|
||||
if (S_ISDIR(sb.st_mode))
|
||||
{
|
||||
slashed = (path[strlen(path) - 1] == '/');
|
||||
|
||||
ret = snprintf(deref, sizeof(deref), "%s%sindex.html", path, (slashed) ? "" : "/");
|
||||
if ((ret < 0) || (ret >= sizeof(deref)))
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Redirection URL exceeds buffer length\n");
|
||||
|
||||
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(path, deref);
|
||||
|
||||
ret = stat(path, &sb);
|
||||
if (ret < 0)
|
||||
{
|
||||
if (strcmp(uri, "/") == 0)
|
||||
{
|
||||
httpd_redirect_to_admin(req);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Could not stat() %s: %s\n", path, strerror(errno));
|
||||
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (path_is_legal(path) != 0)
|
||||
@ -732,12 +762,17 @@ httpd_gen_cb(struct evhttp_request *req, void *arg)
|
||||
}
|
||||
|
||||
parsed = httpd_uri_parse(uri);
|
||||
if (!parsed || !parsed->path || (strcmp(parsed->path, "/") == 0))
|
||||
if (!parsed || !parsed->path)
|
||||
{
|
||||
httpd_redirect_to_admin(req);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(parsed->path, "/") == 0)
|
||||
{
|
||||
goto serve_file;
|
||||
}
|
||||
|
||||
/* Dispatch protocol-specific handlers */
|
||||
if (dacp_is_request(parsed->path))
|
||||
{
|
||||
@ -773,6 +808,7 @@ httpd_gen_cb(struct evhttp_request *req, void *arg)
|
||||
DPRINTF(E_DBG, L_HTTPD, "HTTP request: '%s'\n", parsed->uri);
|
||||
|
||||
/* Serve web interface files */
|
||||
serve_file:
|
||||
serve_file(req, parsed->path);
|
||||
|
||||
out:
|
||||
@ -1379,42 +1415,6 @@ httpd_send_error(struct evhttp_request* req, int error, const char* reason)
|
||||
evbuffer_free(evbuf);
|
||||
}
|
||||
|
||||
void
|
||||
httpd_redirect_to_admin(struct evhttp_request *req)
|
||||
{
|
||||
struct evkeyvalq *headers;
|
||||
|
||||
headers = evhttp_request_get_output_headers(req);
|
||||
evhttp_add_header(headers, "Location", "/admin.html");
|
||||
|
||||
httpd_send_reply(req, HTTP_MOVETEMP, "Moved", NULL, HTTPD_SEND_NO_GZIP);
|
||||
}
|
||||
|
||||
void
|
||||
httpd_redirect_to_index(struct evhttp_request *req, const char *uri)
|
||||
{
|
||||
struct evkeyvalq *headers;
|
||||
char buf[256];
|
||||
int slashed;
|
||||
int ret;
|
||||
|
||||
slashed = (uri[strlen(uri) - 1] == '/');
|
||||
|
||||
ret = snprintf(buf, sizeof(buf), "%s%sindex.html", uri, (slashed) ? "" : "/");
|
||||
if ((ret < 0) || (ret >= sizeof(buf)))
|
||||
{
|
||||
DPRINTF(E_LOG, L_HTTPD, "Redirection URL exceeds buffer length\n");
|
||||
|
||||
httpd_send_error(req, HTTP_NOTFOUND, "Not Found");
|
||||
return;
|
||||
}
|
||||
|
||||
headers = evhttp_request_get_output_headers(req);
|
||||
evhttp_add_header(headers, "Location", buf);
|
||||
|
||||
httpd_send_reply(req, HTTP_MOVETEMP, "Moved", NULL, HTTPD_SEND_NO_GZIP);
|
||||
}
|
||||
|
||||
bool
|
||||
httpd_admin_check_auth(struct evhttp_request *req)
|
||||
{
|
||||
|
@ -145,11 +145,6 @@ httpd_send_error(struct evhttp_request *req, int error, const char *reason);
|
||||
void
|
||||
httpd_redirect_to_admin(struct evhttp_request *req);
|
||||
|
||||
/*
|
||||
* Redirects to [uri]/index.html
|
||||
*/
|
||||
void
|
||||
httpd_redirect_to_index(struct evhttp_request *req, const char *uri);
|
||||
|
||||
bool
|
||||
httpd_admin_check_auth(struct evhttp_request *req);
|
||||
|
Loading…
x
Reference in New Issue
Block a user