nxt_application.c (430:3a24c399394f) nxt_application.c (431:5817734dd9b9)
1
2/*
3 * Copyright (C) Max Romanov
4 * Copyright (C) Igor Sysoev
5 * Copyright (C) Valentin V. Bartenev
6 * Copyright (C) NGINX, Inc.
7 */
8
9#include <nxt_main.h>
10#include <nxt_runtime.h>
11#include <nxt_application.h>
12#include <nxt_main_process.h>
1
2/*
3 * Copyright (C) Max Romanov
4 * Copyright (C) Igor Sysoev
5 * Copyright (C) Valentin V. Bartenev
6 * Copyright (C) NGINX, Inc.
7 */
8
9#include <nxt_main.h>
10#include <nxt_runtime.h>
11#include <nxt_application.h>
12#include <nxt_main_process.h>
13#include <nxt_router.h>
14#include <nxt_http.h>
13
14#include <glob.h>
15
16
17typedef struct {
18 nxt_app_type_t type;
19 nxt_str_t version;
20 nxt_str_t file;
21} nxt_module_t;
22
23
24static nxt_buf_t *nxt_discovery_modules(nxt_task_t *task, const char *path);
25static nxt_int_t nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp,
26 nxt_array_t *modules, const char *name);
27static nxt_app_module_t *nxt_app_module_load(nxt_task_t *task,
28 const char *name);
29static nxt_app_type_t nxt_app_parse_type(u_char *p, size_t length);
30
15
16#include <glob.h>
17
18
19typedef struct {
20 nxt_app_type_t type;
21 nxt_str_t version;
22 nxt_str_t file;
23} nxt_module_t;
24
25
26static nxt_buf_t *nxt_discovery_modules(nxt_task_t *task, const char *path);
27static nxt_int_t nxt_discovery_module(nxt_task_t *task, nxt_mp_t *mp,
28 nxt_array_t *modules, const char *name);
29static nxt_app_module_t *nxt_app_module_load(nxt_task_t *task,
30 const char *name);
31static nxt_app_type_t nxt_app_parse_type(u_char *p, size_t length);
32
31static nxt_int_t nxt_app_request_content_length(void *ctx,
32 nxt_http_field_t *field, uintptr_t data);
33static nxt_int_t nxt_app_request_content_type(void *ctx,
34 nxt_http_field_t *field, uintptr_t data);
35static nxt_int_t nxt_app_request_cookie(void *ctx, nxt_http_field_t *field,
36 uintptr_t data);
37static nxt_int_t nxt_app_request_host(void *ctx, nxt_http_field_t *field,
38 uintptr_t data);
39
33
34static void nxt_app_http_release(nxt_task_t *task, void *obj, void *data);
40
35
41static nxt_http_field_proc_t nxt_app_request_fields[] = {
42 { nxt_string("Content-Length"), &nxt_app_request_content_length, 0 },
43 { nxt_string("Content-Type"), &nxt_app_request_content_type, 0 },
44 { nxt_string("Cookie"), &nxt_app_request_cookie, 0 },
45 { nxt_string("Host"), &nxt_app_request_host, 0 },
46};
47
36
48
49static uint32_t compat[] = {
50 NXT_VERNUM, NXT_DEBUG,
51};
52
53
37static uint32_t compat[] = {
38 NXT_VERNUM, NXT_DEBUG,
39};
40
41
54static nxt_lvlhsh_t nxt_app_request_fields_hash;
55
56static nxt_thread_mutex_t nxt_app_mutex;
57static nxt_thread_cond_t nxt_app_cond;
58
59static nxt_application_module_t *nxt_app;
60
61
62nxt_int_t
63nxt_discovery_start(nxt_task_t *task, void *data)

--- 303 unchanged lines hidden (view full) ---

367
368 nxt_log(task, NXT_LOG_CRIT, "dlopen(\"%s\"), failed: \"%s\"",
369 name, dlerror());
370
371 return NULL;
372}
373
374
42static nxt_thread_mutex_t nxt_app_mutex;
43static nxt_thread_cond_t nxt_app_cond;
44
45static nxt_application_module_t *nxt_app;
46
47
48nxt_int_t
49nxt_discovery_start(nxt_task_t *task, void *data)

--- 303 unchanged lines hidden (view full) ---

353
354 nxt_log(task, NXT_LOG_CRIT, "dlopen(\"%s\"), failed: \"%s\"",
355 name, dlerror());
356
357 return NULL;
358}
359
360
375nxt_int_t
376nxt_app_http_init(nxt_task_t *task, nxt_runtime_t *rt)
377{
378 return nxt_http_fields_hash(&nxt_app_request_fields_hash, rt->mem_pool,
379 nxt_app_request_fields,
380 nxt_nitems(nxt_app_request_fields));
381}
382
383
384void
385nxt_app_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
386{
387 if (nxt_app->atexit != NULL) {
388 nxt_app->atexit(task);
389 }
390
391 nxt_worker_process_quit_handler(task, msg);

--- 307 unchanged lines hidden (view full) ---

699 ret = nxt_app_msg_read_size_(task, msg, size);
700
701 nxt_debug(task, "nxt_read_size: %d", (int) *size);
702
703 return ret;
704}
705
706
361void
362nxt_app_quit_handler(nxt_task_t *task, nxt_port_recv_msg_t *msg)
363{
364 if (nxt_app->atexit != NULL) {
365 nxt_app->atexit(task);
366 }
367
368 nxt_worker_process_quit_handler(task, msg);

--- 307 unchanged lines hidden (view full) ---

676 ret = nxt_app_msg_read_size_(task, msg, size);
677
678 nxt_debug(task, "nxt_read_size: %d", (int) *size);
679
680 return ret;
681}
682
683
707static nxt_int_t
708nxt_app_request_content_length(void *ctx, nxt_http_field_t *field,
709 uintptr_t data)
684nxt_int_t
685nxt_app_http_req_done(nxt_task_t *task, nxt_app_parse_ctx_t *ar)
710{
686{
711 nxt_app_parse_ctx_t *c;
712 nxt_app_request_header_t *h;
687 ar->timer.handler = nxt_app_http_release;
688 nxt_timer_add(task->thread->engine, &ar->timer, 0);
713
689
714 c = ctx;
715 h = &c->r.header;
716
717 h->content_length.length = field->value_length;
718 h->content_length.start = field->value;
719
720 h->parsed_content_length = nxt_off_t_parse(field->value,
721 field->value_length);
722
723 return NXT_OK;
724}
725
726
690 return NXT_OK;
691}
692
693
727static nxt_int_t
728nxt_app_request_content_type(void *ctx, nxt_http_field_t *field,
729 uintptr_t data)
694static void
695nxt_app_http_release(nxt_task_t *task, void *obj, void *data)
730{
696{
731 nxt_app_parse_ctx_t *c;
732 nxt_app_request_header_t *h;
697 nxt_timer_t *timer;
698 nxt_app_parse_ctx_t *ar;
733
699
734 c = ctx;
735 h = &c->r.header;
700 timer = obj;
736
701
737 h->content_type.length = field->value_length;
738 h->content_type.start = field->value;
702 nxt_debug(task, "http app release");
739
703
740 return NXT_OK;
741}
704 ar = nxt_timer_data(timer, nxt_app_parse_ctx_t, timer);
742
705
743
744static nxt_int_t
745nxt_app_request_cookie(void *ctx, nxt_http_field_t *field, uintptr_t data)
746{
747 nxt_app_parse_ctx_t *c;
748 nxt_app_request_header_t *h;
749
750 c = ctx;
751 h = &c->r.header;
752
753 h->cookie.length = field->value_length;
754 h->cookie.start = field->value;
755
756 return NXT_OK;
706 nxt_mp_release(ar->request->mem_pool);
757}
758
759
707}
708
709
760static nxt_int_t
761nxt_app_request_host(void *ctx, nxt_http_field_t *field, uintptr_t data)
762{
763 nxt_app_parse_ctx_t *c;
764 nxt_app_request_header_t *h;
765
766 c = ctx;
767 h = &c->r.header;
768
769 h->host.length = field->value_length;
770 h->host.start = field->value;
771
772 return NXT_OK;
773}
774
775
776nxt_app_parse_ctx_t *
777nxt_app_http_req_init(nxt_task_t *task)
778{
779 nxt_mp_t *mp;
780 nxt_int_t rc;
781 nxt_app_parse_ctx_t *ctx;
782
783 mp = nxt_mp_create(1024, 128, 256, 32);
784 if (nxt_slow_path(mp == NULL)) {
785 return NULL;
786 }
787
788 ctx = nxt_mp_zget(mp, sizeof(nxt_app_parse_ctx_t));
789 if (nxt_slow_path(ctx == NULL)) {
790 nxt_mp_destroy(mp);
791 return NULL;
792 }
793
794 ctx->mem_pool = mp;
795
796 rc = nxt_http_parse_request_init(&ctx->parser, mp);
797 if (nxt_slow_path(rc != NXT_OK)) {
798 nxt_mp_destroy(mp);
799 return NULL;
800 }
801
802 return ctx;
803}
804
805
806nxt_int_t
710nxt_int_t
807nxt_app_http_req_header_parse(nxt_task_t *task, nxt_app_parse_ctx_t *ctx,
808 nxt_buf_t *buf)
809{
810 nxt_int_t rc;
811 nxt_app_request_body_t *b;
812 nxt_http_request_parse_t *p;
813 nxt_app_request_header_t *h;
814
815 p = &ctx->parser;
816 b = &ctx->r.body;
817 h = &ctx->r.header;
818
819 nxt_assert(h->done == 0);
820
821 rc = nxt_http_parse_request(p, &buf->mem);
822
823 if (nxt_slow_path(rc != NXT_DONE)) {
824 return rc;
825 }
826
827 rc = nxt_http_fields_process(p->fields, &nxt_app_request_fields_hash, ctx);
828
829 if (nxt_slow_path(rc != NXT_OK)) {
830 return rc;
831 }
832
833 h->fields = p->fields;
834 h->done = 1;
835
836 h->version.start = p->version.str;
837 h->version.length = sizeof(p->version.str);
838
839 h->method = p->method;
840
841 h->target.start = p->target_start;
842 h->target.length = p->target_end - p->target_start;
843
844 h->path = p->path;
845 h->query = p->args;
846
847 if (h->parsed_content_length == 0) {
848 b->done = 1;
849
850 }
851
852 if (buf->mem.free == buf->mem.pos) {
853 return NXT_DONE;
854 }
855
856 b->buf = buf;
857 b->done = nxt_buf_mem_used_size(&buf->mem) >=
858 h->parsed_content_length;
859
860 if (b->done == 1) {
861 b->preread_size = nxt_buf_mem_used_size(&buf->mem);
862 }
863
864 return NXT_DONE;
865}
866
867
868nxt_int_t
869nxt_app_http_req_body_read(nxt_task_t *task, nxt_app_parse_ctx_t *ctx,
870 nxt_buf_t *buf)
871{
872 nxt_app_request_body_t *b;
873 nxt_app_request_header_t *h;
874
875 b = &ctx->r.body;
876 h = &ctx->r.header;
877
878 nxt_assert(h->done == 1);
879 nxt_assert(b->done == 0);
880
881 b->done = nxt_buf_mem_used_size(&buf->mem) + b->preread_size >=
882 (size_t) h->parsed_content_length;
883
884 if (b->done == 1) {
885 b->preread_size += nxt_buf_mem_used_size(&buf->mem);
886 }
887
888 return b->done == 1 ? NXT_DONE : NXT_AGAIN;
889}
890
891
892nxt_int_t
893nxt_app_http_req_done(nxt_task_t *task, nxt_app_parse_ctx_t *ctx)
894{
895 nxt_mp_release(ctx->mem_pool);
896
897 return NXT_OK;
898}
899
900
901nxt_int_t
902nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg, nxt_bool_t last)
903{
904 nxt_int_t rc;
905 nxt_buf_t *b;
906
907 rc = NXT_OK;
908
909 if (nxt_slow_path(last == 1)) {

--- 144 unchanged lines hidden ---
711nxt_app_msg_flush(nxt_task_t *task, nxt_app_wmsg_t *msg, nxt_bool_t last)
712{
713 nxt_int_t rc;
714 nxt_buf_t *b;
715
716 rc = NXT_OK;
717
718 if (nxt_slow_path(last == 1)) {

--- 144 unchanged lines hidden ---