Implement HEAD support
This commit is contained in:
parent
1d2ce3f9c2
commit
472b4ddbf1
56
main.c
56
main.c
|
@ -980,6 +980,61 @@ end:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int getnode_head(const struct http_payload *const p,
|
||||
struct http_response *const r, void *const user)
|
||||
{
|
||||
struct auth *const a = user;
|
||||
|
||||
if (auth_cookie(a, &p->cookie))
|
||||
{
|
||||
fprintf(stderr, "%s: auth_cookie failed\n", __func__);
|
||||
return page_forbidden(r);
|
||||
}
|
||||
|
||||
const char *const username = p->cookie.field,
|
||||
*const resource = p->resource + strlen("/user/");
|
||||
|
||||
if (path_invalid(resource))
|
||||
{
|
||||
fprintf(stderr, "%s: illegal relative path %s\n", __func__, resource);
|
||||
return page_forbidden(r);
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
struct dynstr dir, root, d;
|
||||
const char *const adir = auth_dir(a),
|
||||
*const sep = p->resource[strlen(p->resource) - 1] != '/' ? "/" : "";
|
||||
|
||||
dynstr_init(&dir);
|
||||
dynstr_init(&d);
|
||||
dynstr_init(&root);
|
||||
|
||||
if (!adir)
|
||||
{
|
||||
fprintf(stderr, "%s: auth_dir failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (dynstr_append(&dir, "%s%s", p->resource, sep))
|
||||
{
|
||||
fprintf(stderr, "%s: dynstr_append dird failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
else if (dynstr_append(&root, "%s/user/%s/", adir, username)
|
||||
|| dynstr_append(&d, "%s%s", root.str, resource))
|
||||
{
|
||||
fprintf(stderr, "%s: dynstr_append failed\n", __func__);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = page_head_resource(r, d.str);
|
||||
|
||||
end:
|
||||
dynstr_free(&dir);
|
||||
dynstr_free(&d);
|
||||
dynstr_free(&root);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int move_file(const char *const old, const char *const new)
|
||||
{
|
||||
int ret = -1;
|
||||
|
@ -1924,6 +1979,7 @@ static int add_urls(struct handler *const h, void *const user)
|
|||
{.url = "/index.html", .op = HTTP_OP_GET, .f = serve_index},
|
||||
{.url = "/style.css", .op = HTTP_OP_GET, .f = serve_style},
|
||||
{.url = "/user/*", .op = HTTP_OP_GET, .f = getnode},
|
||||
{.url = "/user/*", .op = HTTP_OP_HEAD, .f = getnode_head},
|
||||
{.url = "/login", .op = HTTP_OP_POST, .f = login},
|
||||
{.url = "/logout", .op = HTTP_OP_POST, .f = logout},
|
||||
{.url = "/public/*", .op = HTTP_OP_GET, .f = getpublic},
|
||||
|
|
33
page.c
33
page.c
|
@ -2199,3 +2199,36 @@ end:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int page_head_resource(struct http_response *const r, const char *const res)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
if (stat(res, &sb))
|
||||
{
|
||||
if (errno == ENOENT || errno == ENOTDIR)
|
||||
return page_not_found(r);
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "%s: stat(2) %s: %s\n",
|
||||
__func__, res, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
const mode_t m = sb.st_mode;
|
||||
|
||||
if (!S_ISDIR(m) && !S_ISREG(m))
|
||||
{
|
||||
fprintf(stderr, "%s: unexpected st_mode %jd\n", __func__, (intmax_t)m);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*r = (const struct http_response)
|
||||
{
|
||||
.status = HTTP_STATUS_OK,
|
||||
.n = sb.st_size
|
||||
};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
1
page.h
1
page.h
|
@ -43,6 +43,7 @@ int page_failed_login(struct http_response *r);
|
|||
int page_forbidden(struct http_response *r);
|
||||
int page_bad_request(struct http_response *r);
|
||||
int page_resource(const struct page_resource *r);
|
||||
int page_head_resource(struct http_response *r, const char *res);
|
||||
int page_public(struct http_response *r, const char *res);
|
||||
int page_share(struct http_response *r, const char *path);
|
||||
int page_quota_exceeded(struct http_response *r, unsigned long long len,
|
||||
|
|
Loading…
Reference in New Issue