mirror of
https://github.com/servalproject/serval-dna.git
synced 2024-12-19 21:27:57 +00:00
Improve HTTP Origin response headers
Re-introduce "Origin: null" handling, because actually it is in the spec.
This commit is contained in:
parent
cee5241951
commit
4564e955e3
@ -269,6 +269,7 @@ static void _mover_mem(char *dst, const char *src, size_t len)
|
||||
memmove(dst, src, len);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Allocate space from the start of the request buffer to hold the given substring plus a
|
||||
* terminating NUL.
|
||||
*
|
||||
@ -281,6 +282,7 @@ static int _reserve_substring(struct http_request *r, const char **resp, struct
|
||||
assert(strnchr(str.start, len, '\0') == NULL);
|
||||
return _reserve(r, resp, str.start, len, _mover_mem);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* The same as _reserve(), but takes a NUL-terminated string as a source argument instead of a
|
||||
* substring.
|
||||
@ -744,21 +746,18 @@ static int _parse_origin(struct http_request *r, struct http_origin *origin, siz
|
||||
{
|
||||
char *start = r->cursor;
|
||||
char *end = start + header_bytes;
|
||||
if (_skip_literal(r, "http://")) {
|
||||
origin->scheme = "http";
|
||||
} else if (_skip_literal(r, "https://")) {
|
||||
origin->scheme = "https";
|
||||
} else if (_skip_literal(r, "file://")) {
|
||||
origin->scheme = "file";
|
||||
} else {
|
||||
IDEBUGF(r->debug, "Ignoring HTTP Origin with unsupported URI scheme: %s", alloca_toprint(50, start, header_bytes));
|
||||
r->cursor = end;
|
||||
bzero(origin, sizeof *origin);
|
||||
if (_skip_literal(r, "null") && (r->cursor == end || _skip_space(r))) {
|
||||
origin->null = 1;
|
||||
return 1;
|
||||
}
|
||||
origin->hostname = "";
|
||||
origin->port = 0;
|
||||
r->cursor = start;
|
||||
struct substring scheme;
|
||||
struct substring hostname;
|
||||
if (_skip_word_printable(r, &hostname, '/') > 0) {
|
||||
if ( _skip_word_printable(r, &scheme, ':')
|
||||
&& _skip_literal(r, "://")
|
||||
&& _skip_word_printable(r, &hostname, '/')
|
||||
) {
|
||||
const char *port = hostname.end - 1;
|
||||
while (port > hostname.start && isdigit(*port))
|
||||
--port;
|
||||
@ -770,8 +769,15 @@ static int _parse_origin(struct http_request *r, struct http_origin *origin, siz
|
||||
}
|
||||
}
|
||||
assert(hostname.end > hostname.start);
|
||||
if (!_reserve_substring(r, &origin->hostname, hostname))
|
||||
return 0; // error
|
||||
strbuf sb = strbuf_local_buf(origin->scheme);
|
||||
strbuf_ncat(sb, scheme.start, scheme.end - scheme.start);
|
||||
strbuf sh = strbuf_local_buf(origin->hostname);
|
||||
strbuf_ncat(sh, hostname.start, hostname.end - hostname.start);
|
||||
if (strbuf_overrun(sb) || strbuf_overrun(sh)) {
|
||||
IDEBUGF(r->debug, "Ignoring HTTP Origin with over-long scheme: %s", alloca_toprint(50, start, header_bytes));
|
||||
r->cursor = end;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
_skip_literal(r, "/");
|
||||
return 1;
|
||||
@ -1103,7 +1109,7 @@ static int http_request_parse_header(struct http_request *r)
|
||||
}
|
||||
_rewind(r);
|
||||
if (_skip_literal_nocase(r, "Origin:")) {
|
||||
if (r->request_header.origin.scheme) {
|
||||
if (r->request_header.origin.null || r->request_header.origin.scheme[0]) {
|
||||
IDEBUGF(r->debug, "Skipping duplicate HTTP header Origin: %s", alloca_toprint(50, sol, r->end - sol));
|
||||
r->cursor = nextline;
|
||||
_commit(r);
|
||||
@ -2117,14 +2123,24 @@ static int _render_response(struct http_request *r)
|
||||
}
|
||||
if (hr.header.content_length != CONTENT_LENGTH_UNKNOWN)
|
||||
strbuf_sprintf(sb, "Content-Length: %"PRIhttp_size_t"\r\n", hr.header.content_length);
|
||||
|
||||
if (hr.header.allow_origin)
|
||||
strbuf_sprintf(sb, "Access-Control-Allow-Origin: %s\r\n", hr.header.allow_origin);
|
||||
if (hr.header.allow_origin.null || hr.header.allow_origin.scheme[0]) {
|
||||
strbuf_puts(sb, "Access-Control-Allow-Origin: ");
|
||||
if (hr.header.allow_origin.null) {
|
||||
strbuf_puts(sb, "null");
|
||||
} else {
|
||||
assert(hr.header.allow_origin.hostname[0]);
|
||||
strbuf_puts(sb, hr.header.allow_origin.scheme);
|
||||
strbuf_puts(sb, "://");
|
||||
strbuf_puts(sb, hr.header.allow_origin.hostname);
|
||||
if (hr.header.allow_origin.port)
|
||||
strbuf_sprintf(sb, ":%u", hr.header.allow_origin.port);
|
||||
}
|
||||
strbuf_puts(sb, "\r\n");
|
||||
}
|
||||
if (hr.header.allow_methods)
|
||||
strbuf_sprintf(sb, "Access-Control-Allow-Methods: %s\r\n", hr.header.allow_methods);
|
||||
if (hr.header.allow_headers)
|
||||
strbuf_sprintf(sb, "Access-Control-Allow-Headers: %s\r\n", hr.header.allow_headers);
|
||||
|
||||
const char *scheme = NULL;
|
||||
switch (hr.header.www_authenticate.scheme) {
|
||||
case NOAUTH: break;
|
||||
|
@ -88,8 +88,9 @@ struct http_www_authenticate {
|
||||
};
|
||||
|
||||
struct http_origin {
|
||||
const char *scheme;
|
||||
const char *hostname;
|
||||
uint8_t null;
|
||||
char scheme[10]; // enough for "https"
|
||||
char hostname[40]; // enough for "localhost"
|
||||
uint16_t port;
|
||||
};
|
||||
|
||||
@ -108,7 +109,7 @@ struct http_response_headers {
|
||||
http_size_t resource_length; // size of entire resource
|
||||
const char *content_type; // "type/subtype"
|
||||
const char *boundary;
|
||||
char allow_origin[24]; // max supported str (for now) "https://localhost:65537"
|
||||
struct http_origin allow_origin;
|
||||
const char *allow_methods;
|
||||
const char *allow_headers;
|
||||
struct http_www_authenticate www_authenticate;
|
||||
|
@ -136,6 +136,15 @@ test_CORS_Request(){
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/bundlelist.json"
|
||||
assertStdoutIs '200'
|
||||
assertGrep http.headers "^Access-Control-Allow-Origin: http://localhost:1234$CR\$"
|
||||
executeOk curl \
|
||||
--silent --fail --show-error --write-out '%{http_code}' \
|
||||
--output http.output \
|
||||
--dump-header http.headers \
|
||||
--header "Origin: null" \
|
||||
--request "OPTIONS" \
|
||||
"http://$addr_localhost:$PORTA/restful/rhizome/bundlelist.json"
|
||||
assertStdoutIs '200'
|
||||
assertGrep http.headers "^Access-Control-Allow-Origin: null$CR\$"
|
||||
executeOk curl \
|
||||
--silent --show-error --write-out '%{http_code}' \
|
||||
--output http.output \
|
||||
|
Loading…
Reference in New Issue
Block a user