Browse Source

1) tnt_eval has been removed, since it does not work well. It was replaced by ngx_lua and so on, that means this module is optimized for an other nginx's modules like ngx_lua, ngx_perl and so on. 2) tnt_pure_result is back. Reply can be filtered by ngx_lua or ngx_perl. 3) Updated tests. 4) Updated README.

tags/v2.4.6-rc1
dedok 2 years ago
parent
commit
3af386f686

+ 1
- 1
AUTHORS View File

@@ -4,7 +4,7 @@ many contributions from the community.
Below follows a list of people, who contributed their code.

Vasily Soshnikov, Andrew Drozdow, E. Blih, Konstantin Osipov, Valery Kholodkov,
Yichun Zhang (eval module, valgrind suppess, debug.h), Alex Turenko
Yichun Zhang (valgrind suppess, debug.h), Alex Turenko

NOTE: If you can commit a change to this list, please do not hesitate
to add your name to it.

+ 2
- 0
Makefile View File

@@ -64,6 +64,8 @@ configure-debug:
--prefix=$(PREFIX_PATH) \
--with-http_addition_module \
--add-module=$(MODULE_PATH) \
--add-module=$(MODULE_PATH)/../ngx_devel_kit \
--add-module=$(MODULE_PATH)/../lua-nginx-module \
--with-debug

configure-for-testing: configure-debug

+ 71
- 74
README.md View File

@@ -42,8 +42,7 @@ Tarantool - https://hub.docker.com/r/tarantool/tarantool
* [JSON](#json)
* [Directives](#directives)
* [tnt_pass](#tnt_pass)
* [tnt_eval](#tnt_eval)
* [tnt_eval_buffer_size](#tnt_eval_buffer_size)
* [HTTP headers and status](#HTTP headers and status)
* [tnt_http_methods](#tnt_http_methods)
* [tnt_http_rest_methods](#tnt_http_rest_methods)
* [tnt_pass_http_request](#tnt_pass_http_request)
@@ -211,7 +210,7 @@ end
[ { "result": JSON_RESULT_OBJECT, "id":UINT, "error": { "message": STR, "code": INT } }, ...N ]
"result" - DEPRECATED in 2.4.0+
"result"
Version 2.4.0+ output a raw result, i.e. "JSON_RESULT_OBJECT".
@@ -253,11 +252,11 @@ end
rpc call 1:
--> { "method": "echo", "params": [42, 23], "id": 1 }
<-- [42, 23]
<-- { "id": 1, "result": [42, 23]
rpc call 2:
--> { "method": "echo", "params": [ [ {"hello": "world"} ], "!" ], "id": 2 }
<-- [ {"hello": "world"} ], "!" ]
<-- { "id": 2, "result": [ {"hello": "world"} ], "!" ]}
rpc call of a non-existent method:
--> { "method": "echo_2", "id": 1 }
@@ -273,8 +272,8 @@ end
{ "method": "echo", "params": [ [ {"hello": "world"} ], "!" ], "id": 2 }
]
<-- [
[42, 23],
[{"hello": "world"} ], "!" ],
{ "id": 1, "result": [42, 23]},
{ "id": 2, "result" : [{"hello": "world"} ], "!" ]},
]
rpc call Batch of a non-existent method:
@@ -284,7 +283,7 @@ end
]
<-- [
{ "error": {"code": -32601, "message": "Method not found"}, "id": 1 },
[ {"hello": "world"} ], "!" ]
{"id": 2, "result": [ {"hello": "world"} ], "!" ]}
]
rpc call Batch with invalid JSON:
@@ -327,27 +326,18 @@ Specify the Tarantool server backend.
[Back to content](#content)
tnt_eval
--------
**syntax:** *tnt_eval $HTTP_STATUS_VAR_NAME $HTTP_BODY_VAR_NAME*
HTTP headers and status
-----------------------
**default:** *no*
**context:** *location*
This directive put execution of tnt_pass into the nginx REWRITE PHASE.
That exactly this mean? That means that you can have a access to the body (in for of
JSON), http codes and http headers which have been passed from the Tarantool
to the nginx inside nginx config. This very useful for setting custom HTTP
statuses, headers and for post-processing of the original body.
Sometimes you have to set status or headers which came from the Tarantool.
For this you have to use something like [ngx_lua](https://github.com/openresty/lua-nginx-module)
or [ngx_perl](http://nginx.org/en/docs/http/ngx_http_perl_module.html) and so on.
Even more, you can use this for using this module with OpenResty, Nginx Script,
Nginx Perl and so on.
Also using the methods you can transform result from the `Tarantool` into
something else
NOTICE!
Here is an example with `ngx_lua`:
1) This directive expects that tarantool returns special object with meta
information about an HTTP status and an HTTP headers.
Example
@@ -358,7 +348,7 @@ Example
-- First arg. if __ngx exists and tnt_eval is used, then it will be
-- readed by nginx
{
__ngx = {
ngx = {
200, -- set status HTTP 200
{ ["X-Tarantool"] = "FROM_TNT" } -- set headers
}
@@ -373,60 +363,67 @@ Example
upstream tnt_upstream {
127.0.0.1:9999;
keepalive 10000;
}
location = /tnt {
tnt_eval_buffer_size 1m;
tnt_eval $tnt_http_status $tnt_body {
tnt_method foo;
tnt_pass 127.0.0.1:9999;
}
if ($tnt_http_status = 404) {
return 404 $tnt_body;
}
if ($tnt_body ~= 'Tarantool') {
return 200 '<html><h1>Found Tarantool!</h1></html>';
}
return 200 $tnt_body;
location /tnt_proxy {
tnt_method tnt_proxy;
tnt_buffer_size 100k;
tnt_pass_http_request on parse_args;
tnt_pass tnt_upstream;
}
location = /tnt/with_echo_module {
tnt_eval_buffer_size 1m;
tnt_eval $tnt_http_status $tnt_body {
tnt_method foo;
tnt_pass 127.0.0.1:9999;
location /api {
lua_need_request_body on;
rewrite_by_lua '
local cjson = require("cjson")
local map = {
GET = ngx.HTTP_GET,
POST = ngx.HTTP_POST,
PUT = ngx.HTTP_PUT,
-- ...
}
local res = ngx.location.capture("/tnt_proxy", {
args = ngx.var.args,
method = map[ngx.var.request_method],
body = ngx.body
})
if res.status == ngx.HTTP_OK then
local answ = cjson.decode(res.body)
-- Read reply
local result = answ["result"]
if result ~= nil then
ngx.status = result[1]["ngx"][1]
for k, v in pairs(result[1]["ngx"][2]) do
ngx.header[k] = v
end
table.remove(result, 1)
ngx.say(cjson.encode(result))
else
ngx.status = 502
ngx.say(res.body)
end
-- Finalize execution
ngx.exit(ngx.OK)
else
ngx.status = 502
ngx.say("Tarantool does not work")
end
';
}
echo $tnt_body;
}
# ...
# Also those variables are available in any nginx's languages;
```
2) '$'-prefix is required, means that tnt_eval http_code body { ... } will rise an error,
it should be tnt_eval $http_status $body { ... }.
[Back to content](#content)
tnt_eval_buffer_size
--------------------
**syntax:** *tnt_eval_buffer_size size*
**default:** *PAGE_SIZE x 16*
**context:** *main, server, location*
Specify the size of the buffer used for `tnt_eval`.
[Back to content](#content)
tnt_http_methods
@@ -703,7 +700,7 @@ The 0 value turns off this limitation.
[Back to content](#content)
tnt_pure_result - DEPRECATED in 2.4.0+
tnt_pure_result
--------------------------------------
**syntax:** *tnt_pure_result [on|off]*
@@ -714,7 +711,7 @@ tnt_pure_result - DEPRECATED in 2.4.0+
Whether to wrap tnt response or not.
When this option is off:
```
{"id":0, "result": [[ 1 ]]}
{"id":0, "result": [ 1 ]}
```
When this option is on:
```

+ 32
- 35
config View File

@@ -1,42 +1,47 @@
ngx_addon_name="ngx_http_tnt_module"

__libs=" \
$ngx_addon_dir/third_party/yajl/build/yajl-2.1.0/lib/libyajl_s.a \
$ngx_addon_dir/third_party/msgpuck/libmsgpuck.a \
"
libs="-lyajl -lmsgpuck"

__module_src_dir="$ngx_addon_dir/src"
test -f $ngx_addon_dir/third_party/yajl/build/yajl-2.1.0/lib/libyajl_s.a &&
test -f $ngx_addon_dir/third_party/msgpuck/libmsgpuck.a && {
libs=" \
$ngx_addon_dir/third_party/yajl/build/yajl-2.1.0/lib/libyajl_s.a \
$ngx_addon_dir/third_party/msgpuck/libmsgpuck.a \
"
}

__include_paths=" \
module_src_dir="$ngx_addon_dir/src"

include_paths=" \
$ngx_addon_dir/src \
$ngx_addon_dir/third_party \
$ngx_addon_dir/third_party/msgpuck \
$ngx_addon_dir/third_party/yajl/build/yajl-2.1.0/include \
"

__sources=" \
$__module_src_dir/json_encoders.c \
$__module_src_dir/tp_transcode.c \
$__module_src_dir/ngx_http_tnt_module.c \
$__module_src_dir/ngx_http_tnt_handlers.c \
sources=" \
$module_src_dir/json_encoders.c \
$module_src_dir/tp_transcode.c \
$module_src_dir/ngx_http_tnt_module.c \
$module_src_dir/ngx_http_tnt_handlers.c \
"

__headers=" \
$__module_src_dir/debug.h \
$__module_src_dir/tp_ext.h \
$__module_src_dir/json_encoders.h \
$__module_src_dir/tp_transcode.h \
$__module_src_dir/ngx_http_tnt_handlers.h \
headers=" \
$module_src_dir/debug.h \
$module_src_dir/tp_ext.h \
$module_src_dir/json_encoders.h \
$module_src_dir/tp_transcode.h \
$module_src_dir/ngx_http_tnt_handlers.h \
"

__old_style_build=yes
old_style_build=yes
if test -n "$ngx_module_link"; then
__old_style_build=no
old_style_build=no
fi

#
# Old-style build [[
if test "$__old_style_build" = "yes"; then
if test "$old_style_build" = "yes"; then

CORE_INCS=" \
$CORE_INCS \
@@ -46,7 +51,7 @@ if test "$__old_style_build" = "yes"; then
CORE_LIBS=" \
$CORE_LIBS \
$ngx_feature_libs \
$__libs \
$libs \
"

HTTP_MODULES=" \
@@ -56,10 +61,10 @@ if test "$__old_style_build" = "yes"; then

NGX_ADDON_SRCS=" \
$NGX_ADDON_SRCS \
$__sources \
$sources \
"

for path in $__include_paths; do
for path in $include_paths; do
CFLAGS="$CFLAGS -I$path"
done
# ]]
@@ -69,18 +74,10 @@ else

ngx_module_type=HTTP
ngx_module_name=$ngx_addon_name
ngx_module_incs=$__include_paths
ngx_module_deps=$__headers
ngx_module_srcs=$__sources
ngx_module_libs=$__libs
. auto/module

ngx_module_type=HTTP_AUX_FILTER
ngx_module_name=ngx_http_tnt_eval_module
ngx_module_incs=$__include_paths
ngx_module_deps=$__headers
ngx_module_srcs=$__module_src_dir/ngx_http_tnt_eval_module.c
ngx_module_libs=
ngx_module_incs=$include_paths
ngx_module_deps=$headers
ngx_module_srcs=$sources
ngx_module_libs=$libs
. auto/module

# ]]

+ 0
- 1024
src/ngx_http_tnt_eval_module.c
File diff suppressed because it is too large
View File


+ 7
- 1
src/ngx_http_tnt_handlers.h View File

@@ -108,6 +108,11 @@ typedef struct {
*/
ngx_uint_t http_methods;

/** If it is set, then the client will recv. a pure result, e.g. {}
* otherwise {"result":[], "id": NUM}id
*/
ngx_uint_t pure_result;

ngx_array_t *headers_source;

ngx_http_tnt_headers_t headers;
@@ -220,7 +225,8 @@ ngx_http_tnt_overhead(void)
"'code':-XXXXX,"
"'message':''"
"},"
"[[]]"
"{ 'result': [[]],"
"'id': 1867996680 }"
"}");
}


+ 14
- 1
src/ngx_http_tnt_module.c View File

@@ -30,9 +30,10 @@
* please see AUTHORS file.
*/

#include <debug.h>

#include <ngx_config.h>

#include <debug.h>
#include <ngx_http_tnt_version.h>
#include <ngx_http_tnt_handlers.h>

@@ -214,6 +215,13 @@ static ngx_command_t ngx_http_tnt_commands[] = {
offsetof(ngx_http_tnt_loc_conf_t, http_rest_methods),
&ngx_http_tnt_methods },

{ ngx_string("tnt_pure_result"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
ngx_conf_set_bitmask_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_tnt_loc_conf_t, pure_result),
&ngx_http_tnt_pass_http_request_masks },

{ ngx_string("tnt_http_methods"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
ngx_conf_set_bitmask_slot,
@@ -454,6 +462,9 @@ ngx_http_tnt_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
(NGX_HTTP_POST
|NGX_HTTP_DELETE));

ngx_conf_merge_bitmask_value(conf->pure_result, prev->pure_result,
NGX_TNT_CONF_OFF);

if (conf->headers_source == NULL) {
conf->headers = prev->headers;
conf->headers_source = prev->headers_source;
@@ -567,6 +578,8 @@ ngx_http_tnt_send_reply(ngx_http_request_t *r,
return NGX_ERROR;
}

tp_reply_to_json_set_options(&tc, tlcf->pure_result == NGX_TNT_CONF_ON);

rc = tp_transcode(&tc, (char *)ctx->tp_cache->start,
ctx->tp_cache->end - ctx->tp_cache->start);
if (rc != TP_TRANSCODE_ERROR) {

+ 1
- 1
src/ngx_http_tnt_version.h View File

@@ -33,6 +33,6 @@
#ifndef NGX_HTTP_TNT_VERSION_H
#define NGX_HTTP_TNT_VERSION_H 1

#define NGX_HTTP_TNT_MODULE_VERSION_STRING "v2.4.5-beta"
#define NGX_HTTP_TNT_MODULE_VERSION_STRING "v2.4.6-rc1"

#endif

+ 31
- 1
src/tp_transcode.c View File

@@ -847,6 +847,7 @@ query2tp_complete(void *ctx, size_t *cmpl_msg_size)
*/

typedef struct tp2json {

struct tpresponse r;

char *output;
@@ -858,6 +859,12 @@ typedef struct tp2json {
tp_transcode_t *tc;

int state;

/* Encode tarantool message w/o protocol.message
* i.e. with protocol: {id:, result:TNT_RESULT, ...}, w/o TNT_RESULT
*/
bool pure_result;

} tp2json_t;

static inline int
@@ -887,6 +894,10 @@ tp2json_create(tp_transcode_t *tc, char *output, size_t output_size)

memset(ctx, 0, sizeof(tp2json_t));

/* By memset
ctx->pure_result = false;
*/

ctx->pos = ctx->output = output;
ctx->end = output + output_size;
ctx->tc = tc;
@@ -1096,6 +1107,12 @@ tp_reply2json_transcode(void *ctx_, const char *in, size_t in_size)

} else {

if (!ctx->pure_result) {
ctx->pos += snprintf(ctx->output, ctx->end - ctx->output,
"{\"id\":%zu,\"result\":", (size_t) tp_getreqid(&ctx->r));
}


const char *it = ctx->r.data;
rc = tp2json_transcode_internal(ctx, &it, ctx->r.data_end);
if (unlikely(rc == TP_TRANSCODE_ERROR))
@@ -1103,7 +1120,11 @@ tp_reply2json_transcode(void *ctx_, const char *in, size_t in_size)

}

if (ctx->r.error) {
if (!ctx->pure_result ||
/* NOTE https://github.com/tarantool/nginx_upstream_module/issues/44
*/
ctx->r.error)
{
*ctx->pos = '}';
++ctx->pos;
}
@@ -1299,6 +1320,15 @@ tp_transcode_bind_data(tp_transcode_t *t,
t->data.len = data_end - data_beg;
}

void
tp_reply_to_json_set_options(tp_transcode_t *t, bool pure_result)
{
assert(t);
assert(t->codec.ctx);
tp2json_t *ctx = t->codec.ctx;
ctx->pure_result = pure_result;
}

bool
tp_dump(char *output, size_t output_size,
const char *input, size_t input_size)

+ 2
- 4
src/tp_transcode.h View File

@@ -181,12 +181,10 @@ void tp_transcode_bind_data(tp_transcode_t *t,
/**
*/
void
tp_reply_to_json_set_options(tp_transcode_t *t,
bool pure_result,
int multireturn_skip_count);
tp_reply_to_json_set_options(tp_transcode_t *t, bool pure_result);

/**
* WARNING! tp_dump() - is for debug
* WARNING! tp_dump() is for debug!
*
* Dump Tarantool message in JSON
* Returns true, false

+ 21
- 23
test/basic_features.py View File

@@ -57,7 +57,8 @@ def get_id_i(o, i):
return o[i]['id']

def get_result(o):
return o[0]
assert('result' in o), "expected 'result'"
return o['result'][0]

#
def batch_cases():
@@ -79,8 +80,8 @@ def batch_cases():

assert(rc == 200), 'expected 200'
assert(len(res) == 2), 'expected 2 elements, got %i' % len(res)
assert(res[0][0][0][1] == '101234567891234567')
assert(res[1][0][0][1] == '101234567891234567')
assert(res[0]['result'][0][0][1] == '101234567891234567')
assert(res[1]['result'][0][0][1] == '101234567891234567')

##
batch = []
@@ -97,12 +98,12 @@ def batch_cases():
assert(len(res) == len(batch)),\
'expected %i elements, got %i' % (len(batch), len(res))
for i in range(0, len(res)):
rr = res[i][0]
#id = get_id_i(res, i)
rr = res[i]['result'][0]
id = get_id_i(res, i)
assert(rr[0] == batch[i]['params'][0]),\
"expected %s, got %s" % (batch[i]['params'][0], rr[0])
#assert(id == batch[i]['id']),\
# "expected id %s, got %s" % (batch[i]['id'], id)
assert(id == batch[i]['id']),\
"expected id %s, got %s" % (batch[i]['id'], id)

##
(rc, res) = request([
@@ -125,21 +126,18 @@ def batch_cases():
])
assert(rc == 200), 'expected 200'

## This test is broken, since we don't have ID, should it be fixed? [[[
if False:
for rr in res:
if rr['id'] == 3:
assert('error' in rr or 'message' in rr), \
'expected %s returns error/message, got %s' % (rr['id'], rr)
elif rr['id'] == 2:
rr_ = get_result(rr)
assert(rr_[1] == '101234567891234567')
elif rr['id'] == 1:
rr_ = get_result(rr)
assert(rr_ == [{"first":1}, {"second":2}])
else:
assert False, "unexpected id %s" % rr['id']
# ]]]
for rr in res:
if rr['id'] == 3:
assert('error' in rr or 'message' in rr), \
'expected %s returns error/message, got %s' % (rr['id'], rr)
elif rr['id'] == 2:
rr_ = get_result(rr)[0]
assert(rr_[1] == '101234567891234567')
elif rr['id'] == 1:
rr_ = get_result(rr)
assert(rr_ == [{"first":1}, {"second":2}])
else:
assert False, "unexpected id %s" % rr['id']

(rc, res) = request_raw('[{"method":"call", "params":["name", __wrong__], ' +
'"id":1}, {"method":"call", "params":["name"], "id":2}]');
@@ -173,7 +171,7 @@ for i in range(100):
'params': bigarray,
'id': 1
})
assert(res[0][0] == 1), 'expected 1'
assert(res['result'][0][0] == 1), 'expected 1'
print ('[+] Big array OK')

#

+ 1
- 1
test/http_utils.py View File

@@ -182,7 +182,7 @@ def get(url, data, headers):
return (False, e)

def get_result(o):
return o[0]
return o['result'][0]

def assert_if_not_error(s, code = None):
assert('error' in s), 'expected error'

+ 4
- 46
test/lua.py View File

@@ -78,53 +78,11 @@ methods = [
prev_result = None

for method in methods:

for code in http_codes:

curl = BASE_URL + '/eval_basic?status_code=' + str(code)

curl = BASE_URL + '/lua?status_code=' + str(code)
(rcode, result) = method[0](curl, code, {'X-From': 'eval_basic'})
# Python does not work if server returns some codes!
if rcode == True:
continue

if VERBOSE:
print ('===============')
print ('req = ', curl, method[1])
print ('rcore = ', rcode)
print ('expected code', code)
print ('curr = ', result)
if prev_result:
print ('prev = ', prev_result[1])

if method[1] != 'GET':
assert(rcode == code), 'expected ' + str(code)

if prev_result:
# Here is we don't test those fields [[[
prev_result[1]['args']['status_code'] = str(code)
prev_result[1]['uri'] = result[1]['uri']
prev_result[1]['method'] = result[1]['method']
prev_result[1]['headers'] = None
result[1]['headers'] = None
# ]]]

if prev_result[1] != result[1]:
print ('==== NOT EQUAL ====')
print (prev_result[1])
print (result[1])

assert(prev_result[1] == result[1])
assert(prev_result[2] == result[2])

prev_result = result

print('[+] OK')


# =============
#
print('[+] Test headers')
loc = BASE_URL + '/eval_headers'
result = post_success(loc, {'params': []}, {'in_h': 1})
continue;
assert(code == rcode)
print('[+] OK')

+ 55
- 120
test/ngx_confs/tnt_server_test.conf View File

@@ -201,112 +201,61 @@ http {
tnt_pass tnt;
}

location /eval_basic {

tnt_eval_buffer_size 1m;

tnt_eval $tnt_status $tnt_res {
tnt_buffer_size 1m;
tnt_out_multiplier 10;
tnt_pass_http_request on parse_args;
tnt_http_rest_methods all;
tnt_method test_eval;
tnt_pass tnt;
}

add_header 'X-t' $tnt_status;

if ($tnt_status = 201){
return 201 $tnt_res;
}
if ($tnt_status = 202){
return 202 $tnt_res;
}
if ($tnt_status = 204){
return 204 $tnt_res;
}
if ($tnt_status = 206){
return 206 $tnt_res;
}
if ($tnt_status = 300){
return 300 $tnt_res;
}
if ($tnt_status = 301){
return 301 $tnt_res;
}
if ($tnt_status = 302){
return 302 $tnt_res;
}
if ($tnt_status = 303){
return 303 $tnt_res;
}
if ($tnt_status = 304){
return 304 $tnt_res;
}
if ($tnt_status = 307){
return 307 $tnt_res;
}
if ($tnt_status = 400){
return 400 $tnt_res;
}
if ($tnt_status = 401){
return 401 $tnt_res;
}
if ($tnt_status = 403){
return 403 $tnt_res;
}
if ($tnt_status = 404){
return 404 $tnt_res;
}
if ($tnt_status = 405){
return 405 $tnt_res;
}
if ($tnt_status = 408){
return 408 $tnt_res;
}
if ($tnt_status = 409){
return 409 $tnt_res;
}
if ($tnt_status = 411){
return 411 $tnt_res;
}
if ($tnt_status = 412){
return 412 $tnt_res;
}
if ($tnt_status = 413){
return 413 $tnt_res;
}
if ($tnt_status = 414){
return 414 $tnt_res;
}
if ($tnt_status = 415){
return 415 $tnt_res;
}
if ($tnt_status = 416){
return 416 $tnt_res;
}
if ($tnt_status = 421){
return 421 $tnt_res;
}
if ($tnt_status = 500){
return 500 $tnt_res;
}
if ($tnt_status = 501){
return 501 $tnt_res;
}
if ($tnt_status = 502){
return 502 $tnt_res;
}
if ($tnt_status = 503){
return 503 $tnt_res;
}
if ($tnt_status = 504){
return 504 $tnt_res;
}
if ($tnt_status = 507){
return 507 $tnt_res;
}
return 200 $tnt_res;
location /tnt_proxy {
tnt_method tnt_proxy;
tnt_buffer_size 1m;
tnt_out_multiplier 10;
tnt_pass_http_request on parse_args;
tnt_pass tnt;
}

location /lua {

lua_need_request_body on;

rewrite_by_lua '

local cjson = require("cjson")

local map = {
GET = ngx.HTTP_GET,
POST = ngx.HTTP_POST,
PUT = ngx.HTTP_PUT,
-- ...
}

local res = ngx.location.capture("/tnt_proxy", {
args = ngx.var.args,
method = map[ngx.var.request_method],
body = ngx.body
})

if res.status == ngx.HTTP_OK then
local answ = cjson.decode(res.body)

-- Read reply
local result = answ["result"]

if result ~= nil then
ngx.status = result[1]["ngx"][1]
for k, v in pairs(result[1]["ngx"][2]) do
ngx.header[k] = v
end

table.remove(result, 1)
ngx.say(cjson.encode(result))
else
ngx.status = 502
ngx.say(res.body)
end

-- Finalize execution
ngx.exit(ngx.OK)
else
ngx.status = 502
ngx.say("Tarantool does not work")
end
';
}

location /echo_big {
@@ -317,19 +266,5 @@ http {
tnt_http_methods all;
tnt_pass tnt;
}

location /eval_headers {
tnt_eval_buffer_size 2m;
tnt_eval $tnt_status $tnt_res {
tnt_buffer_size 2m;
tnt_pass_http_request on parse_args;
tnt_http_rest_methods all;
tnt_method test_eval_headers;
tnt_pass tnt;
}
add_header 'X-t' $tnt_status;
return 200 $tnt_res;
}

}
}

+ 1
- 1
test/parallel_clients.sh View File

@@ -5,7 +5,7 @@ for i in {1..10}; do
./test/v20_features.py &
./test/v23_features.py &
./test/v24_features.py &
./test/eval_basic.py &
./test/lua.py &
done

for i in `jobs -p`; do

+ 4
- 4
test/run_all.sh View File

@@ -22,8 +22,8 @@ for i in {1..10}; do
$WORK_DIR/v24_features.py 1> /dev/null || (
echo "[-] $WORK_DIR/v24_features.py failed" && exit 1
)
$WORK_DIR/eval_basic.py 1> /dev/null || (
echo "[-] $WORK_DIR/eval_basic.py failed" && exit 1
$WORK_DIR/lua.py 1> /dev/null || (
echo "[-] $WORK_DIR/lua.py failed" && exit 1
)
done

@@ -45,8 +45,8 @@ for i in {1..3}; do
echo "[-] $WORK_DIR/v24_features.py failed" && exit 1
)` &
clients_pids="$clients_pids $!"
`$WORK_DIR/eval_basic.py 1> /dev/null || (
echo "[-] $WORK_DIR/eval_basic.py failed" && exit 1
`$WORK_DIR/lua.py 1> /dev/null || (
echo "[-] $WORK_DIR/lua.py failed" && exit 1
)` &
clients_pids="$clients_pids $!"
done

+ 10
- 26
test/test.lua View File

@@ -21,7 +21,8 @@ function rest_api_get(a, b)
end

function echo_big(...)
return ...
local a = {...}
return a
end

function ret_4096()
@@ -102,8 +103,8 @@ function insert(request, a1, a2)
return { request, a1, a2 }
end

function update(request)
return request
function update(request, ...)
return request, ...
end
-- ]]

@@ -141,39 +142,22 @@ function test_headers_out(req)
return true
end

function test_eval(req, ...)
function tnt_proxy(req, ...)

local out = {...}
for i = 0, 18012 do
out[i] = i;
end

return
{
__ngx = {
ngx = {
tonumber(req.args.status_code) or 200,
{ ["X-Tarantool"] = "FROM_TNT" }
}
},
req,
out
end

function test_eval_headers(req, ...)

local headers = {}

for i = 1, 10 do
headers['H' .. tostring(i)] = tostring(i)
end

return
{
__ngx = {
200,
headers
}
},
req,
...
req
-- out
end

-- CFG

+ 3
- 5
test/v20_features.py View File

@@ -85,22 +85,20 @@ assert(code == 500), 'expected 500'

print ('[+] Test "large request"')

BASE_URL = "http://0.0.0.0:8081/issue_59"
err_msg = { 'error': { 'message':
"Request too large, consider increasing your " +
"server's setting 'client_body_buffer_size'",
'code': -32001 } }

preset_method_location = BASE_URL + '/rest_api_parse_query_args'
preset_method_location = BASE_URL + '/issue_59/rest_api_parse_query_args'

obj = {}
for i in range(1, 30000):
for i in range(1, 40000):
obj[str(i) + 'some_key_name'] = [ i, { 'n': i,
'some_key_name': [[1,2,3],[4]]}]
for i in range(1, 10):
code, result = post(preset_method_location, { 'params': [obj] }, {})
assert(code == 400), 'expected 400'
assert(result == err_msg), 'expected error msg (too large)'
assert(code == 500), 'expected 500'

expected = obj[str(i) + 'some_key_name']
result = post_success(preset_method_location, { 'params': expected }, {})

+ 3
- 3
test/v23_features.py View File

@@ -84,7 +84,7 @@ preset_method_location = BASE_URL + '/tnt'
rc, resp = request_raw(preset_method_location, data, {})
params = json.loads(data)['params']
assert(rc == 200), 'expected 200, got ' + str(rc)
assert(params == resp[0]), 'not equal'
assert(params == resp['result'][0]), 'not equal'

# ===========
#
@@ -144,9 +144,9 @@ preset_method_location = BASE_URL + '/issue_58'
put_success(preset_method_location, {'id':1}, None)
delete_success(preset_method_location, {'params':[]}, None)
delete_success(preset_method_location, None, None)

(rc, result) = request(preset_method_location, [{'id': 1}, {'id': 2}])
assert(result[0] == result[1])
assert(result[0]['id'] == 1)
assert(result[1]['id'] == 2)

data = {"id":0,"params":[
{

+ 0
- 1
test/v24_features.py View File

@@ -84,4 +84,3 @@ for i in range(100000):
data['params'][0]['array'].append(i)
(code, ret) = post(BASE_URL + '/echo_big', data, None)
assert(code == 200), 'expected 200'
assert(ret[1] == data['params'][0])

Loading…
Cancel
Save