Skip to content

Commit

Permalink
Modules: added ngx.fetch().
Browse files Browse the repository at this point in the history
This is an initial implementation of Fetch API.

The following init options are supported:
body, headers, buffer_size (nginx specific), max_response_body_size
(nginx specific), method.

The following properties and methods of Response object are implemented:
arrayBuffer(), bodyUsed, json(), headers, ok, redirect, status, statusText,
text(), type, url.

The following properties and methods of Header object are implemented:
get(), getAll(), has().

Notable limitations: only http:// scheme is supported, redirects
are not handled.

In collaboration with 洪志道 (Hong Zhi Dao).
  • Loading branch information
xeioex committed Jan 21, 2021
1 parent 300c851 commit 73c75e4
Show file tree
Hide file tree
Showing 7 changed files with 2,377 additions and 11 deletions.
3 changes: 2 additions & 1 deletion nginx/config
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
ngx_addon_name="ngx_js_module"

NJS_DEPS="$ngx_addon_dir/ngx_js.h"
NJS_SRCS="$ngx_addon_dir/ngx_js.c"
NJS_SRCS="$ngx_addon_dir/ngx_js.c \
$ngx_addon_dir/ngx_js_fetch.c"

if [ $HTTP != NO ]; then
ngx_module_type=HTTP
Expand Down
63 changes: 56 additions & 7 deletions nginx/ngx_http_js_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,13 @@ static njs_host_event_t ngx_http_js_set_timer(njs_external_ptr_t external,
static void ngx_http_js_clear_timer(njs_external_ptr_t external,
njs_host_event_t event);
static void ngx_http_js_timer_handler(ngx_event_t *ev);
static ngx_pool_t *ngx_http_js_pool(njs_vm_t *vm, ngx_http_request_t *r);
static ngx_resolver_t *ngx_http_js_resolver(njs_vm_t *vm,
ngx_http_request_t *r);
static ngx_msec_t ngx_http_js_resolver_timeout(njs_vm_t *vm,
ngx_http_request_t *r);
static void ngx_http_js_handle_vm_event(ngx_http_request_t *r,
njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs);
static void ngx_http_js_handle_event(ngx_http_request_t *r,
njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs);

Expand Down Expand Up @@ -576,11 +583,15 @@ static njs_vm_ops_t ngx_http_js_ops = {

static uintptr_t ngx_http_js_uptr[] = {
offsetof(ngx_http_request_t, connection),
(uintptr_t) ngx_http_js_pool,
(uintptr_t) ngx_http_js_resolver,
(uintptr_t) ngx_http_js_resolver_timeout,
(uintptr_t) ngx_http_js_handle_event,
};


static njs_vm_meta_t ngx_http_js_metas = {
.size = 1,
.size = 5,
.values = ngx_http_js_uptr
};

Expand Down Expand Up @@ -2754,7 +2765,7 @@ ngx_http_js_subrequest_done(ngx_http_request_t *r, void *data, ngx_int_t rc)
return NGX_ERROR;
}

ngx_http_js_handle_event(r->parent, vm_event, njs_value_arg(&reply), 1);
ngx_http_js_handle_vm_event(r->parent, vm_event, njs_value_arg(&reply), 1);

return NGX_OK;
}
Expand Down Expand Up @@ -2895,24 +2906,48 @@ ngx_http_js_clear_timer(njs_external_ptr_t external, njs_host_event_t event)
static void
ngx_http_js_timer_handler(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_js_event_t *js_event;

js_event = (ngx_http_js_event_t *) ev->data;

r = js_event->request;

c = r->connection;

ngx_http_js_handle_event(r, js_event->vm_event, NULL, 0);
}


static ngx_pool_t *
ngx_http_js_pool(njs_vm_t *vm, ngx_http_request_t *r)
{
return r->pool;
}

ngx_http_run_posted_requests(c);

static ngx_resolver_t *
ngx_http_js_resolver(njs_vm_t *vm, ngx_http_request_t *r)
{
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

return clcf->resolver;
}


static ngx_msec_t
ngx_http_js_resolver_timeout(njs_vm_t *vm, ngx_http_request_t *r)
{
ngx_http_core_loc_conf_t *clcf;

clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);

return clcf->resolver_timeout;
}


static void
ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event,
ngx_http_js_handle_vm_event(ngx_http_request_t *r, njs_vm_event_t vm_event,
njs_value_t *args, njs_uint_t nargs)
{
njs_int_t rc;
Expand All @@ -2925,6 +2960,10 @@ ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event,

rc = njs_vm_run(ctx->vm);

ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
"http js post event handler rc: %i event: %p",
(ngx_int_t) rc, vm_event);

if (rc == NJS_ERROR) {
njs_vm_retval_string(ctx->vm, &exception);

Expand All @@ -2940,6 +2979,16 @@ ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event,
}


static void
ngx_http_js_handle_event(ngx_http_request_t *r, njs_vm_event_t vm_event,
njs_value_t *args, njs_uint_t nargs)
{
ngx_http_js_handle_vm_event(r, vm_event, args, nargs);

ngx_http_run_posted_requests(r->connection);
}


static char *
ngx_http_js_init_main_conf(ngx_conf_t *cf, void *conf)
{
Expand Down
28 changes: 28 additions & 0 deletions nginx/ngx_js.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_js.h"
#include "ngx_js_fetch.h"


static njs_external_t ngx_js_ext_core[] = {
Expand Down Expand Up @@ -50,6 +51,17 @@ static njs_external_t ngx_js_ext_core[] = {
.magic32 = NGX_LOG_ERR,
}
},

{
.flags = NJS_EXTERN_METHOD,
.name.string = njs_str("fetch"),
.writable = 1,
.configurable = 1,
.enumerable = 1,
.u.method = {
.native = ngx_js_ext_fetch,
}
},
};


Expand Down Expand Up @@ -117,10 +129,16 @@ ngx_js_string(njs_vm_t *vm, njs_value_t *value, njs_str_t *str)
ngx_int_t
ngx_js_core_init(njs_vm_t *vm, ngx_log_t *log)
{
ngx_int_t rc;
njs_int_t ret, proto_id;
njs_str_t name;
njs_opaque_value_t value;

rc = ngx_js_fetch_init(vm, log);
if (rc != NGX_OK) {
return NGX_ERROR;
}

proto_id = njs_vm_external_prototype(vm, ngx_js_ext_core,
njs_nitems(ngx_js_ext_core));
if (proto_id < 0) {
Expand Down Expand Up @@ -177,6 +195,16 @@ ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop,
}


njs_int_t
ngx_js_ext_boolean(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval)
{
njs_value_boolean_set(retval, njs_vm_prop_magic32(prop));

return NJS_OK;
}


njs_int_t
ngx_js_ext_log(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
njs_index_t level)
Expand Down
24 changes: 22 additions & 2 deletions nginx/ngx_js.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,28 @@
#define NGX_JS_BUFFER 2

#define NGX_JS_PROTO_MAIN 0
#define NGX_JS_PROTO_RESPONSE 1


#define ngx_external_connection(vm, ext) \
(*((ngx_connection_t **) ((u_char *) ext + njs_vm_meta(vm, 0))))
typedef ngx_pool_t *(*ngx_external_pool_pt)(njs_vm_t *vm, njs_external_ptr_t e);
typedef void (*ngx_js_event_handler_pt)(njs_external_ptr_t e,
njs_vm_event_t vm_event, njs_value_t *args, njs_uint_t nargs);
typedef ngx_resolver_t *(*ngx_external_resolver_pt)(njs_vm_t *vm,
njs_external_ptr_t e);
typedef ngx_msec_t (*ngx_external_resolver_timeout_pt)(njs_vm_t *vm,
njs_external_ptr_t e);


#define ngx_external_connection(vm, e) \
(*((ngx_connection_t **) ((u_char *) (e) + njs_vm_meta(vm, 0))))
#define ngx_external_pool(vm, e) \
((ngx_external_pool_pt) njs_vm_meta(vm, 1))(vm, e)
#define ngx_external_resolver(vm, e) \
((ngx_external_resolver_pt) njs_vm_meta(vm, 2))(vm, e)
#define ngx_external_resolver_timeout(vm, e) \
((ngx_external_resolver_timeout_pt) njs_vm_meta(vm, 3))(vm, e)
#define ngx_external_event_handler(vm, e) \
((ngx_js_event_handler_pt) njs_vm_meta(vm, 4))


#define ngx_js_prop(vm, type, value, start, len) \
Expand All @@ -41,6 +59,8 @@ njs_int_t ngx_js_ext_string(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
njs_int_t ngx_js_ext_constant(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval);
njs_int_t ngx_js_ext_boolean(njs_vm_t *vm, njs_object_prop_t *prop,
njs_value_t *value, njs_value_t *setval, njs_value_t *retval);

ngx_int_t ngx_js_core_init(njs_vm_t *vm, ngx_log_t *log);

Expand Down
Loading

0 comments on commit 73c75e4

Please sign in to comment.