ngx_int_t status;
njs_opaque_value_t request;
njs_opaque_value_t request_body;
+ njs_opaque_value_t response_body;
ngx_str_t redirect_uri;
ngx_array_t promise_callbacks;
} ngx_http_js_ctx_t;
{
.flags = NJS_EXTERN_PROPERTY,
.name.string = njs_str("requestBody"),
+ .u.property = {
+ .handler = ngx_http_js_ext_get_request_body,
+ .magic32 = NGX_JS_STRING,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_PROPERTY,
+ .name.string = njs_str("reqBody"),
.enumerable = 1,
.u.property = {
.handler = ngx_http_js_ext_get_request_body,
+ .magic32 = NGX_JS_BUFFER,
}
},
{
.flags = NJS_EXTERN_PROPERTY,
.name.string = njs_str("responseBody"),
+ .u.property = {
+ .handler = ngx_http_js_ext_get_response_body,
+ .magic32 = NGX_JS_STRING,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_PROPERTY,
+ .name.string = njs_str("resBody"),
.enumerable = 1,
.u.property = {
.handler = ngx_http_js_ext_get_response_body,
+ .magic32 = NGX_JS_BUFFER,
}
},
.u.object = {
.writable = 1,
.prop_handler = ngx_http_js_ext_variables,
+ .magic32 = NGX_JS_STRING,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_OBJECT,
+ .name.string = njs_str("vars"),
+ .u.object = {
+ .writable = 1,
+ .prop_handler = ngx_http_js_ext_variables,
+ .magic32 = NGX_JS_BUFFER,
}
},
request_body = (njs_value_t *) &ctx->request_body;
if (!njs_value_is_null(request_body)) {
- njs_value_assign(retval, request_body);
- return NJS_OK;
+ if ((njs_vm_prop_magic32(prop) == NGX_JS_BUFFER)
+ == (uint32_t) njs_value_is_buffer(request_body))
+ {
+ njs_value_assign(retval, request_body);
+ return NJS_OK;
+ }
}
if (r->request_body == NULL || r->request_body->bufs == NULL) {
done:
- ret = njs_vm_value_string_set(vm, request_body, body, len);
-
+ ret = ngx_js_prop(vm, njs_vm_prop_magic32(prop), request_body, body, len);
if (ret != NJS_OK) {
return NJS_ERROR;
}
return NJS_DECLINED;
}
- return njs_vm_value_string_set(vm, retval, vv->data, vv->len);
+ return ngx_js_prop(vm, njs_vm_prop_magic32(prop), retval, vv->data,
+ vv->len);
}
cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
{
size_t len;
u_char *p;
+ njs_int_t ret;
ngx_buf_t *b;
+ njs_value_t *response_body;
+ ngx_http_js_ctx_t *ctx;
ngx_http_request_t *r;
r = njs_vm_external(vm, value);
return NJS_DECLINED;
}
+ ctx = ngx_http_get_module_ctx(r, ngx_http_js_module);
+ response_body = (njs_value_t *) &ctx->response_body;
+
+ if (!njs_value_is_null(response_body)) {
+ if ((njs_vm_prop_magic32(prop) == NGX_JS_BUFFER)
+ == (uint32_t) njs_value_is_buffer(response_body))
+ {
+ njs_value_assign(retval, response_body);
+ return NJS_OK;
+ }
+ }
+
b = r->out ? r->out->buf : NULL;
if (b == NULL) {
len = b->last - b->pos;
- p = njs_vm_value_string_alloc(vm, retval, len);
+ p = ngx_pnalloc(r->pool, len);
if (p == NULL) {
+ njs_vm_memory_error(vm);
return NJS_ERROR;
}
ngx_memcpy(p, b->pos, len);
}
+ ret = ngx_js_prop(vm, njs_vm_prop_magic32(prop), response_body, p, len);
+ if (ret != NJS_OK) {
+ return NJS_ERROR;
+ }
+
+ njs_value_assign(retval, response_body);
+
return NJS_OK;
}
} ngx_stream_js_srv_conf_t;
+typedef struct {
+ njs_vm_event_t ev;
+ ngx_uint_t data_type;
+} ngx_stream_js_ev_t;
+
+
typedef struct {
njs_vm_t *vm;
ngx_log_t *log;
#define NGX_JS_EVENT_UPLOAD 0
#define NGX_JS_EVENT_DOWNLOAD 1
#define NGX_JS_EVENT_MAX 2
- njs_vm_event_t events[2];
+ ngx_stream_js_ev_t events[2];
unsigned from_upstream:1;
unsigned filter:1;
unsigned in_progress:1;
static void ngx_stream_js_cleanup_ctx(void *data);
static void ngx_stream_js_cleanup_vm(void *data);
static njs_int_t ngx_stream_js_buffer_arg(ngx_stream_session_t *s,
- njs_value_t *buffer);
+ njs_value_t *buffer, ngx_uint_t data_type);
static njs_int_t ngx_stream_js_flags_arg(ngx_stream_session_t *s,
njs_value_t *flags);
static njs_vm_event_t *ngx_stream_js_event(ngx_stream_session_t *s,
.u.object = {
.writable = 1,
.prop_handler = ngx_stream_js_ext_variables,
+ .magic32 = NGX_JS_STRING,
+ }
+ },
+
+ {
+ .flags = NJS_EXTERN_OBJECT,
+ .name.string = njs_str("vars"),
+ .u.object = {
+ .writable = 1,
+ .prop_handler = ngx_stream_js_ext_variables,
+ .magic32 = NGX_JS_BUFFER,
}
},
njs_int_t ret;
ngx_int_t rc;
ngx_connection_t *c;
+ ngx_stream_js_ev_t *event;
ngx_stream_js_ctx_t *ctx;
if (name->len == 0) {
}
}
- if (ctx->events[NGX_JS_EVENT_UPLOAD] != NULL) {
- ret = ngx_stream_js_buffer_arg(s, njs_value_arg(&ctx->args[1]));
+ event = &ctx->events[NGX_JS_EVENT_UPLOAD];
+
+ if (event->ev != NULL) {
+ ret = ngx_stream_js_buffer_arg(s, njs_value_arg(&ctx->args[1]),
+ event->data_type);
if (ret != NJS_OK) {
goto exception;
}
goto exception;
}
- njs_vm_post_event(ctx->vm, ctx->events[NGX_JS_EVENT_UPLOAD],
- njs_value_arg(&ctx->args[1]), 2);
+ njs_vm_post_event(ctx->vm, event->ev, njs_value_arg(&ctx->args[1]), 2);
rc = njs_vm_run(ctx->vm);
if (rc == NJS_ERROR) {
if (njs_vm_pending(ctx->vm)) {
ctx->in_progress = 1;
- rc = ctx->events[NGX_JS_EVENT_UPLOAD] ? NGX_AGAIN : NGX_DONE;
+ rc = ctx->events[NGX_JS_EVENT_UPLOAD].ev ? NGX_AGAIN : NGX_DONE;
} else {
ctx->in_progress = 0;
#define ngx_stream_event(from_upstream) \
- (from_upstream ? ctx->events[NGX_JS_EVENT_DOWNLOAD] \
- : ctx->events[NGX_JS_EVENT_UPLOAD])
+ (from_upstream ? &ctx->events[NGX_JS_EVENT_DOWNLOAD] \
+ : &ctx->events[NGX_JS_EVENT_UPLOAD])
static ngx_int_t
ngx_int_t rc;
ngx_chain_t *out, *cl;
ngx_connection_t *c;
+ ngx_stream_js_ev_t *event;
ngx_stream_js_ctx_t *ctx;
ngx_stream_js_srv_conf_t *jscf;
while (in) {
ctx->buf = in->buf;
- if (ngx_stream_event(from_upstream) != NULL) {
- ret = ngx_stream_js_buffer_arg(s, njs_value_arg(&ctx->args[1]));
+ event = ngx_stream_event(from_upstream);
+
+ if (event->ev != NULL) {
+ ret = ngx_stream_js_buffer_arg(s, njs_value_arg(&ctx->args[1]),
+ event->data_type);
if (ret != NJS_OK) {
goto exception;
}
goto exception;
}
- njs_vm_post_event(ctx->vm, ngx_stream_event(from_upstream),
+ njs_vm_post_event(ctx->vm, event->ev,
njs_value_arg(&ctx->args[1]), 2);
rc = njs_vm_run(ctx->vm);
ngx_uint_t i;
for (i = 0; i < NGX_JS_EVENT_MAX; i++) {
- if (ctx->events[i] != NULL) {
- njs_vm_del_event(ctx->vm, ctx->events[i]);
- ctx->events[i] = NULL;
+ if (ctx->events[i].ev != NULL) {
+ njs_vm_del_event(ctx->vm, ctx->events[i].ev);
+ ctx->events[i].ev = NULL;
}
}
}
static njs_int_t
-ngx_stream_js_buffer_arg(ngx_stream_session_t *s, njs_value_t *buffer)
+ngx_stream_js_buffer_arg(ngx_stream_session_t *s, njs_value_t *buffer,
+ ngx_uint_t data_type)
{
size_t len;
u_char *p;
len = b ? b->last - b->pos : 0;
- p = njs_vm_value_string_alloc(ctx->vm, buffer, len);
+ p = ngx_pnalloc(c->pool, len);
if (p == NULL) {
+ njs_vm_memory_error(ctx->vm);
return NJS_ERROR;
}
ngx_memcpy(p, b->pos, len);
}
- return NJS_OK;
+ return ngx_js_prop(ctx->vm, data_type, buffer, p, len);
}
-
static njs_int_t
ngx_stream_js_flags_arg(ngx_stream_session_t *s, njs_value_t *flags)
{
static njs_vm_event_t *
ngx_stream_js_event(ngx_stream_session_t *s, njs_str_t *event)
{
- ngx_uint_t i, n;
+ ngx_uint_t i, n, type;
ngx_stream_js_ctx_t *ctx;
- static const njs_str_t events[] = {
- njs_str("upload"),
- njs_str("download")
+ static const struct {
+ ngx_str_t name;
+ ngx_uint_t data_type;
+ ngx_uint_t id;
+ } events[] = {
+ {
+ ngx_string("upload"),
+ NGX_JS_STRING,
+ NGX_JS_EVENT_UPLOAD,
+ },
+
+ {
+ ngx_string("download"),
+ NGX_JS_STRING,
+ NGX_JS_EVENT_DOWNLOAD,
+ },
+
+ {
+ ngx_string("upstream"),
+ NGX_JS_BUFFER,
+ NGX_JS_EVENT_UPLOAD,
+ },
+
+ {
+ ngx_string("downstream"),
+ NGX_JS_BUFFER,
+ NGX_JS_EVENT_DOWNLOAD,
+ },
};
ctx = ngx_stream_get_module_ctx(s, ngx_stream_js_module);
n = sizeof(events) / sizeof(events[0]);
while (i < n) {
- if (event->length == events[i].length
- && ngx_memcmp(event->start, events[i].start, event->length) == 0)
+ if (event->length == events[i].name.len
+ && ngx_memcmp(event->start, events[i].name.data, event->length)
+ == 0)
{
break;
}
return NULL;
}
- if (i == 0) {
- return &ctx->events[NGX_JS_EVENT_UPLOAD];
+ ctx->events[events[i].id].data_type = events[i].data_type;
+
+ for (n = 0; n < NGX_JS_EVENT_MAX; n++) {
+ type = ctx->events[n].data_type;
+ if (type != NGX_JS_UNSET && type != events[i].data_type) {
+ njs_vm_error(ctx->vm, "mixing string and buffer events"
+ " is not allowed");
+ return NULL;
+ }
}
- return &ctx->events[NGX_JS_EVENT_DOWNLOAD];
+ return &ctx->events[events[i].id].ev;
}
return NJS_DECLINED;
}
- return njs_vm_value_string_set(vm, retval, vv->data, vv->len);
+ return ngx_js_prop(vm, njs_vm_prop_magic32(prop), retval, vv->data,
+ vv->len);
}
cmcf = ngx_stream_get_module_main_conf(s, ngx_stream_core_module);