Unit application library.
Library now used in all language modules. Old 'nxt_app_*' code removed. See src/test/nxt_unit_app_test.c for usage sample.
This commit is contained in:
191
src/test/nxt_unit_app_test.c
Normal file
191
src/test/nxt_unit_app_test.c
Normal file
@@ -0,0 +1,191 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) NGINX, Inc.
|
||||
*/
|
||||
|
||||
#include <nxt_unit.h>
|
||||
#include <nxt_unit_request.h>
|
||||
#include <nxt_clang.h>
|
||||
|
||||
|
||||
#define CONTENT_TYPE "Content-Type"
|
||||
#define TEXT_PLAIN "text/plain"
|
||||
#define HELLO_WORLD "Hello world!\n"
|
||||
|
||||
#define NEW_LINE "\n"
|
||||
|
||||
#define REQUEST_DATA "Request data:\n"
|
||||
#define METHOD " Method: "
|
||||
#define PROTOCOL " Protocol: "
|
||||
#define REMOTE_ADDR " Remote addr: "
|
||||
#define LOCAL_ADDR " Local addr: "
|
||||
#define TARGET " Target: "
|
||||
#define PATH " Path: "
|
||||
#define QUERY " Query: "
|
||||
#define FIELDS " Fields:\n"
|
||||
#define FIELD_PAD " "
|
||||
#define FIELD_SEP ": "
|
||||
#define BODY " Body:\n"
|
||||
|
||||
|
||||
static inline char *
|
||||
copy(char *p, const void *src, uint32_t len)
|
||||
{
|
||||
memcpy(p, src, len);
|
||||
|
||||
return p + len;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
greeting_app_request_handler(nxt_unit_request_info_t *req)
|
||||
{
|
||||
int rc;
|
||||
char *p;
|
||||
ssize_t res;
|
||||
uint32_t i;
|
||||
nxt_unit_buf_t *buf;
|
||||
nxt_unit_field_t *f;
|
||||
nxt_unit_request_t *r;
|
||||
|
||||
rc = nxt_unit_response_init(req, 200 /* Status code. */,
|
||||
1 /* Number of response headers. */,
|
||||
nxt_length(CONTENT_TYPE)
|
||||
+ nxt_length(TEXT_PLAIN)
|
||||
+ nxt_length(HELLO_WORLD));
|
||||
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = nxt_unit_response_add_field(req,
|
||||
CONTENT_TYPE, nxt_length(CONTENT_TYPE),
|
||||
TEXT_PLAIN, nxt_length(TEXT_PLAIN));
|
||||
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = nxt_unit_response_add_content(req, HELLO_WORLD,
|
||||
nxt_length(HELLO_WORLD));
|
||||
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
rc = nxt_unit_response_send(req);
|
||||
if (nxt_slow_path(rc != NXT_UNIT_OK)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = req->request;
|
||||
|
||||
buf = nxt_unit_response_buf_alloc(req, (req->request_buf->end
|
||||
- req->request_buf->start)
|
||||
+ nxt_length(REQUEST_DATA)
|
||||
+ nxt_length(METHOD)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(PROTOCOL)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(REMOTE_ADDR)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(LOCAL_ADDR)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(TARGET)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(PATH)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(QUERY)
|
||||
+ nxt_length(NEW_LINE)
|
||||
+ nxt_length(FIELDS)
|
||||
+ r->fields_count * (
|
||||
nxt_length(FIELD_PAD)
|
||||
+ nxt_length(FIELD_SEP))
|
||||
+ nxt_length(BODY));
|
||||
if (nxt_slow_path(buf == NULL)) {
|
||||
rc = NXT_UNIT_ERROR;
|
||||
|
||||
goto fail;
|
||||
}
|
||||
|
||||
p = buf->free;
|
||||
|
||||
p = copy(p, REQUEST_DATA, nxt_length(REQUEST_DATA));
|
||||
|
||||
p = copy(p, METHOD, nxt_length(METHOD));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->method), r->method_length);
|
||||
*p++ = '\n';
|
||||
|
||||
p = copy(p, PROTOCOL, nxt_length(PROTOCOL));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->version), r->version_length);
|
||||
*p++ = '\n';
|
||||
|
||||
p = copy(p, REMOTE_ADDR, nxt_length(REMOTE_ADDR));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->remote), r->remote_length);
|
||||
*p++ = '\n';
|
||||
|
||||
p = copy(p, LOCAL_ADDR, nxt_length(LOCAL_ADDR));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->local), r->local_length);
|
||||
*p++ = '\n';
|
||||
|
||||
p = copy(p, TARGET, nxt_length(TARGET));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->target), r->target_length);
|
||||
*p++ = '\n';
|
||||
|
||||
p = copy(p, PATH, nxt_length(PATH));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->path), r->path_length);
|
||||
*p++ = '\n';
|
||||
|
||||
if (r->query.offset) {
|
||||
p = copy(p, QUERY, nxt_length(QUERY));
|
||||
p = copy(p, nxt_unit_sptr_get(&r->query), r->query_length);
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
p = copy(p, FIELDS, nxt_length(FIELDS));
|
||||
|
||||
for (i = 0; i < r->fields_count; i++) {
|
||||
f = r->fields + i;
|
||||
|
||||
p = copy(p, FIELD_PAD, nxt_length(FIELD_PAD));
|
||||
p = copy(p, nxt_unit_sptr_get(&f->name), f->name_length);
|
||||
p = copy(p, FIELD_SEP, nxt_length(FIELD_SEP));
|
||||
p = copy(p, nxt_unit_sptr_get(&f->value), f->value_length);
|
||||
*p++ = '\n';
|
||||
}
|
||||
|
||||
if (r->content_length > 0) {
|
||||
p = copy(p, BODY, nxt_length(BODY));
|
||||
|
||||
res = nxt_unit_request_read(req, buf->free, buf->end - buf->free);
|
||||
buf->free += res;
|
||||
|
||||
}
|
||||
|
||||
buf->free = p;
|
||||
|
||||
rc = nxt_unit_buf_send(buf);
|
||||
|
||||
fail:
|
||||
|
||||
nxt_unit_request_done(req, rc);
|
||||
}
|
||||
|
||||
int
|
||||
main()
|
||||
{
|
||||
nxt_unit_ctx_t *ctx;
|
||||
nxt_unit_init_t init;
|
||||
|
||||
memset(&init, 0, sizeof(nxt_unit_init_t));
|
||||
|
||||
init.callbacks.request_handler = greeting_app_request_handler;
|
||||
|
||||
ctx = nxt_unit_init(&init);
|
||||
if (ctx == NULL) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
nxt_unit_run(ctx);
|
||||
|
||||
nxt_unit_done(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user