forked from cory/tildefriends
Use picohttpparser for responses, too.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4362 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
b6dffa8e66
commit
1c52446331
22
core/http.js
22
core/http.js
@ -31,7 +31,7 @@ function parseResponse(data) {
|
|||||||
export function fetch(url, options, allowed_hosts) {
|
export function fetch(url, options, allowed_hosts) {
|
||||||
let parsed = parseUrl(url);
|
let parsed = parseUrl(url);
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
if (allowed_hosts.indexOf(parsed.host) == -1) {
|
if ((allowed_hosts ?? []).indexOf(parsed.host) == -1) {
|
||||||
throw new Error(`fetch() request to host ${parsed.host} is not allowed.`);
|
throw new Error(`fetch() request to host ${parsed.host} is not allowed.`);
|
||||||
}
|
}
|
||||||
let socket = new Socket();
|
let socket = new Socket();
|
||||||
@ -45,6 +45,26 @@ export function fetch(url, options, allowed_hosts) {
|
|||||||
newBuffer.set(data, buffer.length);
|
newBuffer.set(data, buffer.length);
|
||||||
buffer = newBuffer;
|
buffer = newBuffer;
|
||||||
} else {
|
} else {
|
||||||
|
let result = parseHttpResponse(buffer);
|
||||||
|
if (!result) {
|
||||||
|
reject(new Exception('Parse failed.'));
|
||||||
|
}
|
||||||
|
if (typeof result == 'number') {
|
||||||
|
if (result == -2) {
|
||||||
|
reject('Incomplete request.');
|
||||||
|
} else {
|
||||||
|
reject('Bad request.');
|
||||||
|
}
|
||||||
|
} else if (typeof result == 'object') {
|
||||||
|
resolve({
|
||||||
|
body: buffer.slice(result.bytes_parsed),
|
||||||
|
status: result.status,
|
||||||
|
message: result.message,
|
||||||
|
headers: result.headers,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
reject(new Exception('Unexpected parse result.'));
|
||||||
|
}
|
||||||
resolve(parseResponse(utf8Decode(buffer)));
|
resolve(parseResponse(utf8Decode(buffer)));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -473,7 +473,7 @@ function handleConnection(client) {
|
|||||||
|
|
||||||
if (parsing_header)
|
if (parsing_header)
|
||||||
{
|
{
|
||||||
let result = parseHttp(inputBuffer, inputBuffer.length - data.length);
|
let result = parseHttpRequest(inputBuffer, inputBuffer.length - data.length);
|
||||||
if (result) {
|
if (result) {
|
||||||
if (typeof result === 'number') {
|
if (typeof result === 'number') {
|
||||||
if (result == -2) {
|
if (result == -2) {
|
||||||
|
@ -240,7 +240,7 @@ static JSValue _util_setTimeout(JSContext* context, JSValueConst this_val, int a
|
|||||||
return JS_NULL;
|
return JS_NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue _util_parseHttp(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
static JSValue _util_parseHttpRequest(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
{
|
{
|
||||||
JSValue result = JS_UNDEFINED;
|
JSValue result = JS_UNDEFINED;
|
||||||
const char* method = NULL;
|
const char* method = NULL;
|
||||||
@ -269,7 +269,7 @@ static JSValue _util_parseHttp(JSContext* context, JSValueConst this_val, int ar
|
|||||||
|
|
||||||
if (array)
|
if (array)
|
||||||
{
|
{
|
||||||
int parse_result = phr_parse_request((const char*)array, length, &method, &method_length, &path, &path_length, &minor_version, headers, &header_count, 0);
|
int parse_result = phr_parse_request((const char*)array, length, &method, &method_length, &path, &path_length, &minor_version, headers, &header_count, previous_length);
|
||||||
if (parse_result > 0)
|
if (parse_result > 0)
|
||||||
{
|
{
|
||||||
result = JS_NewObject(context);
|
result = JS_NewObject(context);
|
||||||
@ -298,6 +298,66 @@ static JSValue _util_parseHttp(JSContext* context, JSValueConst this_val, int ar
|
|||||||
|
|
||||||
JS_FreeValue(context, buffer);
|
JS_FreeValue(context, buffer);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue _util_parseHttpResponse(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)
|
||||||
|
{
|
||||||
|
JSValue result = JS_UNDEFINED;
|
||||||
|
int status = 0;
|
||||||
|
int minor_version = 0;
|
||||||
|
const char* message = NULL;
|
||||||
|
size_t message_length = 0;
|
||||||
|
struct phr_header headers[100];
|
||||||
|
size_t header_count = sizeof(headers) / sizeof(*headers);
|
||||||
|
int previous_length = 0;
|
||||||
|
JS_ToInt32(context, &previous_length, argv[1]);
|
||||||
|
|
||||||
|
JSValue buffer = JS_UNDEFINED;
|
||||||
|
size_t length;
|
||||||
|
uint8_t* array = tf_util_try_get_array_buffer(context, &length, argv[0]);
|
||||||
|
if (!array)
|
||||||
|
{
|
||||||
|
size_t offset;
|
||||||
|
size_t element_size;
|
||||||
|
buffer = tf_util_try_get_typed_array_buffer(context, argv[0], &offset, &length, &element_size);
|
||||||
|
if (!JS_IsException(buffer))
|
||||||
|
{
|
||||||
|
array = tf_util_try_get_array_buffer(context, &length, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (array)
|
||||||
|
{
|
||||||
|
int parse_result = phr_parse_response((const char*)array, length, &minor_version, &status, &message, &message_length, headers, &header_count, previous_length);
|
||||||
|
if (parse_result > 0)
|
||||||
|
{
|
||||||
|
result = JS_NewObject(context);
|
||||||
|
JS_SetPropertyStr(context, result, "bytes_parsed", JS_NewInt32(context, parse_result));
|
||||||
|
JS_SetPropertyStr(context, result, "minor_version", JS_NewInt32(context, minor_version));
|
||||||
|
JS_SetPropertyStr(context, result, "status", JS_NewInt32(context, status));
|
||||||
|
JS_SetPropertyStr(context, result, "message", JS_NewStringLen(context, message, message_length));
|
||||||
|
JSValue header_object = JS_NewObject(context);
|
||||||
|
for (int i = 0; i < (int)header_count; i++)
|
||||||
|
{
|
||||||
|
char name[256];
|
||||||
|
snprintf(name, sizeof(name), "%.*s", (int)headers[i].name_len, headers[i].name);
|
||||||
|
JS_SetPropertyStr(context, header_object, name, JS_NewStringLen(context, headers[i].value, headers[i].value_len));
|
||||||
|
}
|
||||||
|
JS_SetPropertyStr(context, result, "headers", header_object);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = JS_NewInt32(context, parse_result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = JS_ThrowTypeError(context, "Could not convert argument to array.");
|
||||||
|
}
|
||||||
|
|
||||||
|
JS_FreeValue(context, buffer);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -372,7 +432,8 @@ void tf_util_register(JSContext* context)
|
|||||||
JS_SetPropertyStr(context, global, "base64Encode", JS_NewCFunction(context, _util_base64_encode, "base64Encode", 1));
|
JS_SetPropertyStr(context, global, "base64Encode", JS_NewCFunction(context, _util_base64_encode, "base64Encode", 1));
|
||||||
JS_SetPropertyStr(context, global, "print", JS_NewCFunction(context, _util_print, "print", 1));
|
JS_SetPropertyStr(context, global, "print", JS_NewCFunction(context, _util_print, "print", 1));
|
||||||
JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2));
|
JS_SetPropertyStr(context, global, "setTimeout", JS_NewCFunction(context, _util_setTimeout, "setTimeout", 2));
|
||||||
JS_SetPropertyStr(context, global, "parseHttp", JS_NewCFunction(context, _util_parseHttp, "parseHttp", 2));
|
JS_SetPropertyStr(context, global, "parseHttpRequest", JS_NewCFunction(context, _util_parseHttpRequest, "parseHttpRequest", 2));
|
||||||
|
JS_SetPropertyStr(context, global, "parseHttpResponse", JS_NewCFunction(context, _util_parseHttpResponse, "parseHttpResponse", 2));
|
||||||
JS_SetPropertyStr(context, global, "sha1Digest", JS_NewCFunction(context, _util_sha1_digest, "sha1Digest", 1));
|
JS_SetPropertyStr(context, global, "sha1Digest", JS_NewCFunction(context, _util_sha1_digest, "sha1Digest", 1));
|
||||||
JS_SetPropertyStr(context, global, "maskBytes", JS_NewCFunction(context, _util_mask_bytes, "maskBytes", 2));
|
JS_SetPropertyStr(context, global, "maskBytes", JS_NewCFunction(context, _util_mask_bytes, "maskBytes", 2));
|
||||||
JS_FreeValue(context, global);
|
JS_FreeValue(context, global);
|
||||||
|
Loading…
Reference in New Issue
Block a user