mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-10 04:19:58 +00:00
Allow serving of static http content from [etc]/static/
This commit is contained in:
parent
a23c56626d
commit
ce21c64809
74
httpd.c
74
httpd.c
@ -33,6 +33,7 @@ static HTTP_HANDLER root_page;
|
||||
static HTTP_HANDLER fav_icon_header;
|
||||
static HTTP_HANDLER interface_page;
|
||||
static HTTP_HANDLER neighbour_page;
|
||||
static HTTP_HANDLER static_page;
|
||||
|
||||
HTTP_HANDLER restful_rhizome_bundlelist_json;
|
||||
HTTP_HANDLER restful_rhizome_newsince;
|
||||
@ -67,6 +68,7 @@ struct http_handler paths[]={
|
||||
{"/rhizome/enquiry", rhizome_direct_enquiry},
|
||||
{"/rhizome/manifestbyprefix/", manifest_by_prefix_page},
|
||||
{"/rhizome/", rhizome_direct_dispatch},
|
||||
{"/static/", static_page},
|
||||
{"/interface/", interface_page},
|
||||
{"/neighbour/", neighbour_page},
|
||||
{"/favicon.ico", fav_icon_header},
|
||||
@ -488,6 +490,23 @@ int http_response_form_part(httpd_request *r, const char *what, const char *part
|
||||
return 403;
|
||||
}
|
||||
|
||||
int http_response_init_content_range(httpd_request *r, size_t resource_length)
|
||||
{
|
||||
r->http.response.header.resource_length = resource_length;
|
||||
if (r->http.request_header.content_range_count == 1) {
|
||||
struct http_range closed;
|
||||
unsigned n = http_range_close(&closed, r->http.request_header.content_ranges, 1, resource_length);
|
||||
if (n == 0 || http_range_bytes(&closed, 1) == 0)
|
||||
return 416; // Request Range Not Satisfiable
|
||||
r->http.response.header.content_range_start = closed.first;
|
||||
r->http.response.header.content_length = closed.last - closed.first + 1;
|
||||
}else{
|
||||
r->http.response.header.content_range_start = 0;
|
||||
r->http.response.header.content_length = resource_length;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int root_page(httpd_request *r, const char *remainder)
|
||||
{
|
||||
if (*remainder)
|
||||
@ -571,3 +590,58 @@ static int interface_page(httpd_request *r, const char *remainder)
|
||||
http_request_response_static(&r->http, 200, CONTENT_TYPE_HTML, buf, strbuf_len(b));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void finalise_union_close_file(httpd_request *r)
|
||||
{
|
||||
if (r->u.file.fd==-1)
|
||||
return;
|
||||
close(r->u.file.fd);
|
||||
r->u.file.fd=-1;
|
||||
}
|
||||
|
||||
static int static_file_generator(struct http_request *hr, unsigned char *buf, size_t bufsz, struct http_content_generator_result *result)
|
||||
{
|
||||
struct httpd_request *r=(struct httpd_request *)hr;
|
||||
uint64_t remain = r->http.response.header.content_length + r->http.response.header.content_range_start - r->u.file.offset;
|
||||
if (bufsz < remain)
|
||||
remain = bufsz;
|
||||
ssize_t bytes = read(r->u.file.fd, buf, remain);
|
||||
if (bytes == -1)
|
||||
return -1;
|
||||
r->u.file.offset+=bytes;
|
||||
result->generated = bytes;
|
||||
return (r->u.file.offset >= r->http.response.header.content_length + r->http.response.header.content_range_start)?0:1;
|
||||
}
|
||||
|
||||
static int static_page(httpd_request *r, const char *remainder)
|
||||
{
|
||||
if (r->http.verb != HTTP_VERB_GET)
|
||||
return 405;
|
||||
char path[PATH_MAX];
|
||||
|
||||
if (!*remainder)
|
||||
remainder="index.html";
|
||||
if (FORMF_SERVAL_ETC_PATH(path, "static/%s", remainder)==0)
|
||||
return 500;
|
||||
struct stat stat;
|
||||
if (lstat(path, &stat))
|
||||
return 404;
|
||||
|
||||
r->u.file.fd = open(path, O_RDONLY);
|
||||
if (r->u.file.fd==-1)
|
||||
return 404;
|
||||
|
||||
r->finalise_union=finalise_union_close_file;
|
||||
|
||||
// TODO find extension and set content type properly
|
||||
http_response_init_content_range(r, stat.st_size);
|
||||
if (r->http.response.header.content_range_start){
|
||||
if (lseek64(r->u.file.fd, r->http.response.header.content_range_start, SEEK_SET)){
|
||||
WARNF_perror("lseek(%s)", path);
|
||||
return 500;
|
||||
}
|
||||
}
|
||||
r->u.file.offset=r->http.response.header.content_range_start;
|
||||
http_request_response_generated(&r->http, 200, CONTENT_TYPE_HTML, static_file_generator);
|
||||
return 1;
|
||||
}
|
||||
|
9
httpd.h
9
httpd.h
@ -194,7 +194,13 @@ typedef struct httpd_request
|
||||
struct form_buf_malloc message;
|
||||
}
|
||||
sendmsg;
|
||||
|
||||
|
||||
|
||||
struct {
|
||||
int fd;
|
||||
size_t offset;
|
||||
}
|
||||
file;
|
||||
} u;
|
||||
|
||||
} httpd_request;
|
||||
@ -208,6 +214,7 @@ int authorize_restful(struct http_request *r);
|
||||
int http_response_content_type(httpd_request *r, const char *what, const struct mime_content_type *ct);
|
||||
int http_response_content_disposition(httpd_request *r, const char *what, const char *type);
|
||||
int http_response_form_part(httpd_request *r, const char *what, const char *partname, const char *text, size_t textlen);
|
||||
int http_response_init_content_range(httpd_request *r, size_t resource_length);
|
||||
int accumulate_text(httpd_request *r, const char *partname, char *textbuf, size_t textsiz, size_t *textlenp, const char *buf, size_t len);
|
||||
|
||||
int rhizome_response_content_init_filehash(httpd_request *r, const rhizome_filehash_t *hash);
|
||||
|
@ -795,22 +795,10 @@ static int rhizome_response_content_init_read_state(httpd_request *r)
|
||||
return 404;
|
||||
}
|
||||
assert(r->u.read_state.length != RHIZOME_SIZE_UNSET);
|
||||
r->http.response.header.resource_length = r->u.read_state.length;
|
||||
if (r->http.request_header.content_range_count > 0) {
|
||||
assert(r->http.request_header.content_range_count == 1);
|
||||
struct http_range closed;
|
||||
unsigned n = http_range_close(&closed, r->http.request_header.content_ranges, 1, r->u.read_state.length);
|
||||
if (n == 0 || http_range_bytes(&closed, 1) == 0)
|
||||
return 416; // Request Range Not Satisfiable
|
||||
r->http.response.header.content_range_start = closed.first;
|
||||
r->http.response.header.content_length = closed.last - closed.first + 1;
|
||||
r->u.read_state.offset = closed.first;
|
||||
} else {
|
||||
r->http.response.header.content_range_start = 0;
|
||||
r->http.response.header.content_length = r->http.response.header.resource_length;
|
||||
r->u.read_state.offset = 0;
|
||||
}
|
||||
return 0;
|
||||
int ret = http_response_init_content_range(r, r->u.read_state.length);
|
||||
if (ret==0)
|
||||
r->u.read_state.offset = r->http.response.header.content_range_start;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int rhizome_response_content_init_filehash(httpd_request *r, const rhizome_filehash_t *hash)
|
||||
|
Loading…
x
Reference in New Issue
Block a user