1 2 /* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6 #include <nxt_unit.h> 7 #include <nxt_unit_request.h> 8 #include <nxt_clang.h> 9 10 11 #define CONTENT_TYPE "Content-Type" 12 #define TEXT_PLAIN "text/plain" 13 #define HELLO_WORLD "Hello world!\n" 14 15 #define NEW_LINE "\n" 16 17 #define REQUEST_DATA "Request data:\n" 18 #define METHOD " Method: " 19 #define PROTOCOL " Protocol: " 20 #define REMOTE_ADDR " Remote addr: " 21 #define LOCAL_ADDR " Local addr: " 22 #define TARGET " Target: " 23 #define PATH " Path: " 24 #define QUERY " Query: " 25 #define FIELDS " Fields:\n" 26 #define FIELD_PAD " " 27 #define FIELD_SEP ": " 28 #define BODY " Body:\n" 29 30 31 static inline char * 32 copy(char *p, const void *src, uint32_t len) 33 { 34 memcpy(p, src, len); 35 36 return p + len; 37 } 38 39 40 static void 41 greeting_app_request_handler(nxt_unit_request_info_t *req) 42 { 43 int rc; 44 char *p; 45 ssize_t res; 46 uint32_t i; 47 nxt_unit_buf_t *buf; 48 nxt_unit_field_t *f; 49 nxt_unit_request_t *r; 50 51 rc = nxt_unit_response_init(req, 200 /* Status code. */, 52 1 /* Number of response headers. */, 53 nxt_length(CONTENT_TYPE) 54 + nxt_length(TEXT_PLAIN) 55 + nxt_length(HELLO_WORLD)); 56 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 57 goto fail; 58 } 59 60 rc = nxt_unit_response_add_field(req, 61 CONTENT_TYPE, nxt_length(CONTENT_TYPE), 62 TEXT_PLAIN, nxt_length(TEXT_PLAIN)); 63 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 64 goto fail; 65 } 66 67 rc = nxt_unit_response_add_content(req, HELLO_WORLD, 68 nxt_length(HELLO_WORLD)); 69 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 70 goto fail; 71 } 72 73 rc = nxt_unit_response_send(req); 74 if (nxt_slow_path(rc != NXT_UNIT_OK)) { 75 goto fail; 76 } 77 78 r = req->request; 79 80 buf = nxt_unit_response_buf_alloc(req, (req->request_buf->end 81 - req->request_buf->start) 82 + nxt_length(REQUEST_DATA) 83 + nxt_length(METHOD) 84 + nxt_length(NEW_LINE) 85 + nxt_length(PROTOCOL) 86 + nxt_length(NEW_LINE) 87 + nxt_length(REMOTE_ADDR) 88 + nxt_length(NEW_LINE) 89 + nxt_length(LOCAL_ADDR) 90 + nxt_length(NEW_LINE) 91 + nxt_length(TARGET) 92 + nxt_length(NEW_LINE) 93 + nxt_length(PATH) 94 + nxt_length(NEW_LINE) 95 + nxt_length(QUERY) 96 + nxt_length(NEW_LINE) 97 + nxt_length(FIELDS) 98 + r->fields_count * ( 99 nxt_length(FIELD_PAD) 100 + nxt_length(FIELD_SEP)) 101 + nxt_length(BODY)); 102 if (nxt_slow_path(buf == NULL)) { 103 rc = NXT_UNIT_ERROR; 104 105 goto fail; 106 } 107 108 p = buf->free; 109 110 p = copy(p, REQUEST_DATA, nxt_length(REQUEST_DATA)); 111 112 p = copy(p, METHOD, nxt_length(METHOD)); 113 p = copy(p, nxt_unit_sptr_get(&r->method), r->method_length); 114 *p++ = '\n'; 115 116 p = copy(p, PROTOCOL, nxt_length(PROTOCOL)); 117 p = copy(p, nxt_unit_sptr_get(&r->version), r->version_length); 118 *p++ = '\n'; 119 120 p = copy(p, REMOTE_ADDR, nxt_length(REMOTE_ADDR)); 121 p = copy(p, nxt_unit_sptr_get(&r->remote), r->remote_length); 122 *p++ = '\n'; 123 124 p = copy(p, LOCAL_ADDR, nxt_length(LOCAL_ADDR)); 125 p = copy(p, nxt_unit_sptr_get(&r->local), r->local_length); 126 *p++ = '\n'; 127 128 p = copy(p, TARGET, nxt_length(TARGET)); 129 p = copy(p, nxt_unit_sptr_get(&r->target), r->target_length); 130 *p++ = '\n'; 131 132 p = copy(p, PATH, nxt_length(PATH)); 133 p = copy(p, nxt_unit_sptr_get(&r->path), r->path_length); 134 *p++ = '\n'; 135 136 if (r->query.offset) { 137 p = copy(p, QUERY, nxt_length(QUERY)); 138 p = copy(p, nxt_unit_sptr_get(&r->query), r->query_length); 139 *p++ = '\n'; 140 } 141 142 p = copy(p, FIELDS, nxt_length(FIELDS)); 143 144 for (i = 0; i < r->fields_count; i++) { 145 f = r->fields + i; 146 147 p = copy(p, FIELD_PAD, nxt_length(FIELD_PAD)); 148 p = copy(p, nxt_unit_sptr_get(&f->name), f->name_length); 149 p = copy(p, FIELD_SEP, nxt_length(FIELD_SEP)); 150 p = copy(p, nxt_unit_sptr_get(&f->value), f->value_length); 151 *p++ = '\n'; 152 } 153 154 if (r->content_length > 0) { 155 p = copy(p, BODY, nxt_length(BODY)); 156 157 res = nxt_unit_request_read(req, buf->free, buf->end - buf->free); 158 buf->free += res; 159 160 } 161 162 buf->free = p; 163 164 rc = nxt_unit_buf_send(buf); 165 166 fail: 167 168 nxt_unit_request_done(req, rc); 169 } 170 171 int 172 main() 173 { 174 nxt_unit_ctx_t *ctx; 175 nxt_unit_init_t init; 176 177 memset(&init, 0, sizeof(nxt_unit_init_t)); 178 179 init.callbacks.request_handler = greeting_app_request_handler; 180 181 ctx = nxt_unit_init(&init); 182 if (ctx == NULL) { 183 return 1; 184 } 185 186 nxt_unit_run(ctx); 187 188 nxt_unit_done(ctx); 189 190 return 0; 191 } 192