xref: /unit/src/nxt_php_sapi.c (revision 142)
10Sigor@sysoev.ru 
20Sigor@sysoev.ru /*
386Smax.romanov@nginx.com  * Copyright (C) Max Romanov
40Sigor@sysoev.ru  * Copyright (C) Valentin V. Bartenev
50Sigor@sysoev.ru  * Copyright (C) NGINX, Inc.
60Sigor@sysoev.ru  */
70Sigor@sysoev.ru 
80Sigor@sysoev.ru #include "php.h"
90Sigor@sysoev.ru #include "SAPI.h"
100Sigor@sysoev.ru #include "php_main.h"
110Sigor@sysoev.ru #include "php_variables.h"
120Sigor@sysoev.ru 
130Sigor@sysoev.ru #include <nxt_main.h>
140Sigor@sysoev.ru #include <nxt_application.h>
150Sigor@sysoev.ru 
160Sigor@sysoev.ru 
17*142Smax.romanov@nginx.com static nxt_int_t nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf);
180Sigor@sysoev.ru 
1986Smax.romanov@nginx.com static nxt_int_t nxt_php_prepare_msg(nxt_task_t *task,
2086Smax.romanov@nginx.com                       nxt_app_request_t *r, nxt_app_wmsg_t *wmsg);
210Sigor@sysoev.ru 
2286Smax.romanov@nginx.com static nxt_int_t nxt_php_run(nxt_task_t *task,
2386Smax.romanov@nginx.com                       nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg);
240Sigor@sysoev.ru 
2586Smax.romanov@nginx.com #if PHP_MAJOR_VERSION >= 7
2686Smax.romanov@nginx.com #   define NXT_PHP7 1
2786Smax.romanov@nginx.com #   if PHP_MINOR_VERSION >= 1
2886Smax.romanov@nginx.com #       define NXT_HAVE_PHP_LOG_MESSAGE_WITH_SYSLOG_TYPE 1
2986Smax.romanov@nginx.com #   else
3086Smax.romanov@nginx.com #       define NXT_HAVE_PHP_INTERRUPTS 1
3186Smax.romanov@nginx.com #   endif
3286Smax.romanov@nginx.com #   define NXT_HAVE_PHP_IGNORE_CWD 1
3386Smax.romanov@nginx.com #else
3486Smax.romanov@nginx.com #   define NXT_HAVE_PHP_INTERRUPTS 1
3586Smax.romanov@nginx.com #   if PHP_MINOR_VERSION >= 4
3686Smax.romanov@nginx.com #       define NXT_HAVE_PHP_IGNORE_CWD 1
3786Smax.romanov@nginx.com #   endif
3886Smax.romanov@nginx.com #endif
390Sigor@sysoev.ru 
400Sigor@sysoev.ru static int nxt_php_startup(sapi_module_struct *sapi_module);
410Sigor@sysoev.ru static int nxt_php_send_headers(sapi_headers_struct *sapi_headers);
420Sigor@sysoev.ru static char *nxt_php_read_cookies(void);
430Sigor@sysoev.ru static void nxt_php_register_variables(zval *track_vars_array);
4486Smax.romanov@nginx.com static void nxt_php_log_message(char *message
4586Smax.romanov@nginx.com #ifdef NXT_HAVE_PHP_LOG_MESSAGE_WITH_SYSLOG_TYPE
4686Smax.romanov@nginx.com                                 , int syslog_type_int
4786Smax.romanov@nginx.com #endif
4886Smax.romanov@nginx.com );
490Sigor@sysoev.ru 
500Sigor@sysoev.ru #ifdef NXT_PHP7
510Sigor@sysoev.ru static size_t nxt_php_unbuffered_write(const char *str,
520Sigor@sysoev.ru     size_t str_length TSRMLS_DC);
530Sigor@sysoev.ru static size_t nxt_php_read_post(char *buffer, size_t count_bytes TSRMLS_DC);
540Sigor@sysoev.ru #else
550Sigor@sysoev.ru static int nxt_php_unbuffered_write(const char *str, uint str_length TSRMLS_DC);
560Sigor@sysoev.ru static int nxt_php_read_post(char *buffer, uint count_bytes TSRMLS_DC);
570Sigor@sysoev.ru #endif
580Sigor@sysoev.ru 
59114Smax.romanov@nginx.com static void nxt_php_flush(void *server_context);
60114Smax.romanov@nginx.com 
6186Smax.romanov@nginx.com extern nxt_int_t nxt_php_sapi_init(nxt_thread_t *thr, nxt_runtime_t *rt);
6286Smax.romanov@nginx.com 
630Sigor@sysoev.ru 
640Sigor@sysoev.ru static sapi_module_struct  nxt_php_sapi_module =
650Sigor@sysoev.ru {
660Sigor@sysoev.ru     (char *) "cli-server",
679Sigor@sysoev.ru     (char *) "nginext",
680Sigor@sysoev.ru 
690Sigor@sysoev.ru     nxt_php_startup,             /* startup */
700Sigor@sysoev.ru     php_module_shutdown_wrapper, /* shutdown */
710Sigor@sysoev.ru 
720Sigor@sysoev.ru     NULL,                        /* activate */
730Sigor@sysoev.ru     NULL,                        /* deactivate */
740Sigor@sysoev.ru 
750Sigor@sysoev.ru     nxt_php_unbuffered_write,    /* unbuffered write */
76114Smax.romanov@nginx.com     nxt_php_flush,               /* flush */
770Sigor@sysoev.ru     NULL,                        /* get uid */
780Sigor@sysoev.ru     NULL,                        /* getenv */
790Sigor@sysoev.ru 
800Sigor@sysoev.ru     php_error,                   /* error handler */
810Sigor@sysoev.ru 
820Sigor@sysoev.ru     NULL,                        /* header handler */
830Sigor@sysoev.ru     nxt_php_send_headers,        /* send headers handler */
840Sigor@sysoev.ru     NULL,                        /* send header handler */
850Sigor@sysoev.ru 
860Sigor@sysoev.ru     nxt_php_read_post,           /* read POST data */
870Sigor@sysoev.ru     nxt_php_read_cookies,        /* read Cookies */
880Sigor@sysoev.ru 
890Sigor@sysoev.ru     nxt_php_register_variables,  /* register server variables */
900Sigor@sysoev.ru     nxt_php_log_message,         /* log message */
9186Smax.romanov@nginx.com     NULL,                        /* get request time */
9286Smax.romanov@nginx.com     NULL,                        /* terminate process */
930Sigor@sysoev.ru 
9486Smax.romanov@nginx.com     NULL,                        /* php_ini_path_override */
9586Smax.romanov@nginx.com #ifdef NXT_HAVE_PHP_INTERRUPTS
9686Smax.romanov@nginx.com     NULL,                        /* block_interruptions */
9786Smax.romanov@nginx.com     NULL,                        /* unblock_interruptions */
9886Smax.romanov@nginx.com #endif
9986Smax.romanov@nginx.com     NULL,                        /* default_post_reader */
10086Smax.romanov@nginx.com     NULL,                        /* treat_data */
10186Smax.romanov@nginx.com     NULL,                        /* executable_location */
10286Smax.romanov@nginx.com 
10386Smax.romanov@nginx.com     0,                           /* php_ini_ignore */
10486Smax.romanov@nginx.com #ifdef NXT_HAVE_PHP_IGNORE_CWD
10586Smax.romanov@nginx.com     0,                           /* php_ini_ignore_cwd */
10686Smax.romanov@nginx.com #endif
10786Smax.romanov@nginx.com     NULL,                        /* get_fd */
10886Smax.romanov@nginx.com 
10986Smax.romanov@nginx.com     NULL,                        /* force_http_10 */
11086Smax.romanov@nginx.com 
11186Smax.romanov@nginx.com     NULL,                        /* get_target_uid */
11286Smax.romanov@nginx.com     NULL,                        /* get_target_gid */
11386Smax.romanov@nginx.com 
11486Smax.romanov@nginx.com     NULL,                        /* input_filter */
11586Smax.romanov@nginx.com 
11686Smax.romanov@nginx.com     NULL,                        /* ini_defaults */
11786Smax.romanov@nginx.com     0,                           /* phpinfo_as_text */
11886Smax.romanov@nginx.com 
11986Smax.romanov@nginx.com     NULL,                        /* ini_entries */
12086Smax.romanov@nginx.com     NULL,                        /* additional_functions */
12186Smax.romanov@nginx.com     NULL                         /* input_filter_init */
1220Sigor@sysoev.ru };
1230Sigor@sysoev.ru 
12486Smax.romanov@nginx.com typedef struct {
12586Smax.romanov@nginx.com     nxt_task_t           *task;
12686Smax.romanov@nginx.com     nxt_app_rmsg_t       *rmsg;
12786Smax.romanov@nginx.com     nxt_app_request_t    r;
12886Smax.romanov@nginx.com     nxt_str_t            script;
12986Smax.romanov@nginx.com     nxt_app_wmsg_t       *wmsg;
13086Smax.romanov@nginx.com     nxt_mp_t             *mem_pool;
13186Smax.romanov@nginx.com } nxt_php_run_ctx_t;
13286Smax.romanov@nginx.com 
13386Smax.romanov@nginx.com nxt_inline nxt_int_t nxt_php_write(nxt_php_run_ctx_t *ctx,
13486Smax.romanov@nginx.com                       const u_char *data, size_t len,
13586Smax.romanov@nginx.com                       nxt_bool_t flush, nxt_bool_t last);
13686Smax.romanov@nginx.com 
1370Sigor@sysoev.ru 
1380Sigor@sysoev.ru static nxt_str_t nxt_php_path;
1390Sigor@sysoev.ru static nxt_str_t nxt_php_root;
1400Sigor@sysoev.ru static nxt_str_t nxt_php_script;
141*142Smax.romanov@nginx.com static nxt_str_t nxt_php_index = nxt_string("index.php");
142*142Smax.romanov@nginx.com 
143*142Smax.romanov@nginx.com static void
144*142Smax.romanov@nginx.com nxt_php_strdup(nxt_str_t *dst, nxt_str_t *src)
145*142Smax.romanov@nginx.com {
146*142Smax.romanov@nginx.com     dst->start = malloc(src->length + 1);
147*142Smax.romanov@nginx.com     nxt_memcpy(dst->start, src->start, src->length);
148*142Smax.romanov@nginx.com     dst->start[src->length] = '\0';
149*142Smax.romanov@nginx.com 
150*142Smax.romanov@nginx.com     dst->length = src->length;
151*142Smax.romanov@nginx.com }
152*142Smax.romanov@nginx.com 
153*142Smax.romanov@nginx.com static void
154*142Smax.romanov@nginx.com nxt_php_str_trim_trail(nxt_str_t *str, u_char t)
155*142Smax.romanov@nginx.com {
156*142Smax.romanov@nginx.com     while (str->length > 0 && str->start[str->length - 1] == t) {
157*142Smax.romanov@nginx.com         str->length--;
158*142Smax.romanov@nginx.com     }
159*142Smax.romanov@nginx.com 
160*142Smax.romanov@nginx.com     str->start[str->length] = '\0';
161*142Smax.romanov@nginx.com }
162*142Smax.romanov@nginx.com 
163*142Smax.romanov@nginx.com 
164*142Smax.romanov@nginx.com static void
165*142Smax.romanov@nginx.com nxt_php_str_trim_lead(nxt_str_t *str, u_char t)
166*142Smax.romanov@nginx.com {
167*142Smax.romanov@nginx.com     while (str->length > 0 && str->start[0] == t) {
168*142Smax.romanov@nginx.com         str->length--;
169*142Smax.romanov@nginx.com         str->start++;
170*142Smax.romanov@nginx.com     }
171*142Smax.romanov@nginx.com }
1720Sigor@sysoev.ru 
1730Sigor@sysoev.ru 
17486Smax.romanov@nginx.com nxt_application_module_t  nxt_php_module = {
17586Smax.romanov@nginx.com     nxt_php_init,
17686Smax.romanov@nginx.com     nxt_php_prepare_msg,
17786Smax.romanov@nginx.com     nxt_php_run
17886Smax.romanov@nginx.com };
1790Sigor@sysoev.ru 
1800Sigor@sysoev.ru 
18186Smax.romanov@nginx.com nxt_int_t
18286Smax.romanov@nginx.com nxt_php_sapi_init(nxt_thread_t *thr, nxt_runtime_t *rt)
1830Sigor@sysoev.ru {
184*142Smax.romanov@nginx.com     nxt_app_modules[NXT_APP_PHP] = &nxt_php_module;
18586Smax.romanov@nginx.com 
186*142Smax.romanov@nginx.com #if PHP_MAJOR_VERSION == 5
187*142Smax.romanov@nginx.com     nxt_app_modules[NXT_APP_PHP5] = &nxt_php_module;
188*142Smax.romanov@nginx.com #endif
18986Smax.romanov@nginx.com 
190*142Smax.romanov@nginx.com #if PHP_MAJOR_VERSION == 7
191*142Smax.romanov@nginx.com     nxt_app_modules[NXT_APP_PHP7] = &nxt_php_module;
192*142Smax.romanov@nginx.com #endif
1930Sigor@sysoev.ru 
194*142Smax.romanov@nginx.com     return NXT_OK;
1950Sigor@sysoev.ru }
1960Sigor@sysoev.ru 
1970Sigor@sysoev.ru 
19886Smax.romanov@nginx.com static nxt_int_t
199*142Smax.romanov@nginx.com nxt_php_init(nxt_task_t *task, nxt_common_app_conf_t *conf)
2000Sigor@sysoev.ru {
201*142Smax.romanov@nginx.com     nxt_str_t           *root, *path, *script, *index;
202*142Smax.romanov@nginx.com     nxt_php_app_conf_t  *c;
203*142Smax.romanov@nginx.com 
204*142Smax.romanov@nginx.com     c = &conf->u.php;
205*142Smax.romanov@nginx.com 
206*142Smax.romanov@nginx.com     if (c->root.length == 0) {
207*142Smax.romanov@nginx.com         nxt_log_emerg(task->log, "php root is empty");
208*142Smax.romanov@nginx.com         return NXT_ERROR;
209*142Smax.romanov@nginx.com     }
210*142Smax.romanov@nginx.com 
211*142Smax.romanov@nginx.com     root = &nxt_php_root;
212*142Smax.romanov@nginx.com     path = &nxt_php_path;
213*142Smax.romanov@nginx.com     script = &nxt_php_script;
214*142Smax.romanov@nginx.com     index = &nxt_php_index;
215*142Smax.romanov@nginx.com 
216*142Smax.romanov@nginx.com     nxt_php_strdup(root, &c->root);
217*142Smax.romanov@nginx.com 
218*142Smax.romanov@nginx.com     nxt_php_str_trim_trail(root, '/');
219*142Smax.romanov@nginx.com 
220*142Smax.romanov@nginx.com     if (c->script.length > 0) {
221*142Smax.romanov@nginx.com         nxt_php_str_trim_lead(&c->script, '/');
222*142Smax.romanov@nginx.com 
223*142Smax.romanov@nginx.com         path->length = root->length + c->script.length + 1;
224*142Smax.romanov@nginx.com         path->start = malloc(path->length + 1);
225*142Smax.romanov@nginx.com 
226*142Smax.romanov@nginx.com         nxt_memcpy(path->start, root->start, root->length);
227*142Smax.romanov@nginx.com         path->start[root->length] = '/';
228*142Smax.romanov@nginx.com 
229*142Smax.romanov@nginx.com         nxt_memcpy(path->start + root->length + 1,
230*142Smax.romanov@nginx.com                    c->script.start, c->script.length);
231*142Smax.romanov@nginx.com 
232*142Smax.romanov@nginx.com         path->start[path->length] = '\0';
233*142Smax.romanov@nginx.com 
234*142Smax.romanov@nginx.com 
235*142Smax.romanov@nginx.com         script->length = c->script.length + 1;
236*142Smax.romanov@nginx.com         script->start = malloc(script->length + 1);
237*142Smax.romanov@nginx.com         script->start[0] = '/';
238*142Smax.romanov@nginx.com         nxt_memcpy(script->start + 1, c->script.start, c->script.length);
239*142Smax.romanov@nginx.com         script->start[script->length] = '\0';
240*142Smax.romanov@nginx.com 
241*142Smax.romanov@nginx.com         nxt_log_error(NXT_LOG_INFO, task->log,
242*142Smax.romanov@nginx.com                       "(ABS_MODE) php script \"%V\" root: \"%V\"",
243*142Smax.romanov@nginx.com                       script, root);
244*142Smax.romanov@nginx.com     } else {
245*142Smax.romanov@nginx.com         nxt_log_error(NXT_LOG_INFO, task->log,
246*142Smax.romanov@nginx.com                       "(non ABS_MODE) php root: \"%V\"", root);
247*142Smax.romanov@nginx.com     }
248*142Smax.romanov@nginx.com 
249*142Smax.romanov@nginx.com     if (c->index.length > 0) {
250*142Smax.romanov@nginx.com         nxt_php_strdup(index, &c->index);
251*142Smax.romanov@nginx.com     }
252*142Smax.romanov@nginx.com 
253*142Smax.romanov@nginx.com     sapi_startup(&nxt_php_sapi_module);
254*142Smax.romanov@nginx.com     nxt_php_startup(&nxt_php_sapi_module);
255*142Smax.romanov@nginx.com 
2560Sigor@sysoev.ru     return NXT_OK;
2570Sigor@sysoev.ru }
2580Sigor@sysoev.ru 
2590Sigor@sysoev.ru 
26086Smax.romanov@nginx.com static nxt_int_t
26186Smax.romanov@nginx.com nxt_php_read_request(nxt_task_t *task, nxt_app_rmsg_t *rmsg,
26286Smax.romanov@nginx.com     nxt_php_run_ctx_t *ctx)
2630Sigor@sysoev.ru {
26486Smax.romanov@nginx.com     u_char                    *p;
26586Smax.romanov@nginx.com     size_t                    s;
266114Smax.romanov@nginx.com     nxt_int_t                 rc;
26794Smax.romanov@nginx.com     nxt_str_t                 script_name;
26886Smax.romanov@nginx.com     nxt_app_request_header_t  *h;
2690Sigor@sysoev.ru 
27086Smax.romanov@nginx.com     h = &ctx->r.header;
2710Sigor@sysoev.ru 
272114Smax.romanov@nginx.com #define RC(S)                                                                 \
273114Smax.romanov@nginx.com     do {                                                                      \
274114Smax.romanov@nginx.com         rc = (S);                                                             \
275114Smax.romanov@nginx.com         if (nxt_slow_path(rc != NXT_OK)) {                                    \
276114Smax.romanov@nginx.com             goto fail;                                                        \
277114Smax.romanov@nginx.com         }                                                                     \
278114Smax.romanov@nginx.com     } while(0)
2790Sigor@sysoev.ru 
280114Smax.romanov@nginx.com #define NXT_READ(dst)                                                         \
281114Smax.romanov@nginx.com     RC(nxt_app_msg_read_str(task, rmsg, (dst)))
282114Smax.romanov@nginx.com 
283114Smax.romanov@nginx.com     NXT_READ(&h->method);
284114Smax.romanov@nginx.com     NXT_READ(&h->target);
285114Smax.romanov@nginx.com     NXT_READ(&h->path);
286114Smax.romanov@nginx.com 
287114Smax.romanov@nginx.com     RC(nxt_app_msg_read_size(task, rmsg, &s));
28886Smax.romanov@nginx.com     if (s > 0) {
28986Smax.romanov@nginx.com         s--;
290112Smax.romanov@nginx.com         h->query.start = h->target.start + s;
291112Smax.romanov@nginx.com         h->query.length = h->target.length - s;
2920Sigor@sysoev.ru 
293112Smax.romanov@nginx.com         if (h->path.start == NULL) {
294112Smax.romanov@nginx.com             h->path.start = h->target.start;
295112Smax.romanov@nginx.com             h->path.length = s - 1;
29686Smax.romanov@nginx.com         }
2970Sigor@sysoev.ru     }
2980Sigor@sysoev.ru 
299112Smax.romanov@nginx.com     if (h->path.start == NULL) {
300112Smax.romanov@nginx.com         h->path = h->target;
301112Smax.romanov@nginx.com     }
302112Smax.romanov@nginx.com 
30386Smax.romanov@nginx.com     if (nxt_php_path.start == NULL) {
304112Smax.romanov@nginx.com         if (h->path.start[h->path.length - 1] == '/') {
305*142Smax.romanov@nginx.com             script_name = nxt_php_index;
30694Smax.romanov@nginx.com         } else {
30794Smax.romanov@nginx.com             script_name.length = 0;
30894Smax.romanov@nginx.com         }
30994Smax.romanov@nginx.com 
310112Smax.romanov@nginx.com         ctx->script.length = nxt_php_root.length + h->path.length +
31194Smax.romanov@nginx.com                              script_name.length;
31286Smax.romanov@nginx.com         ctx->script.start = nxt_mp_nget(ctx->mem_pool,
31386Smax.romanov@nginx.com             ctx->script.length + 1);
31486Smax.romanov@nginx.com 
31586Smax.romanov@nginx.com         p = ctx->script.start;
31686Smax.romanov@nginx.com 
31786Smax.romanov@nginx.com         nxt_memcpy(p, nxt_php_root.start, nxt_php_root.length);
31886Smax.romanov@nginx.com         p += nxt_php_root.length;
31994Smax.romanov@nginx.com 
320112Smax.romanov@nginx.com         nxt_memcpy(p, h->path.start, h->path.length);
321112Smax.romanov@nginx.com         p += h->path.length;
32294Smax.romanov@nginx.com 
32394Smax.romanov@nginx.com         if (script_name.length > 0) {
32494Smax.romanov@nginx.com             nxt_memcpy(p, script_name.start, script_name.length);
32594Smax.romanov@nginx.com             p += script_name.length;
32694Smax.romanov@nginx.com         }
32794Smax.romanov@nginx.com 
32894Smax.romanov@nginx.com         p[0] = '\0';
32986Smax.romanov@nginx.com     } else {
33086Smax.romanov@nginx.com         ctx->script = nxt_php_path;
33186Smax.romanov@nginx.com     }
33286Smax.romanov@nginx.com 
333114Smax.romanov@nginx.com     NXT_READ(&h->version);
334114Smax.romanov@nginx.com 
335114Smax.romanov@nginx.com     NXT_READ(&ctx->r.remote);
33686Smax.romanov@nginx.com 
337114Smax.romanov@nginx.com     NXT_READ(&h->host);
338114Smax.romanov@nginx.com     NXT_READ(&h->cookie);
339114Smax.romanov@nginx.com     NXT_READ(&h->content_type);
340114Smax.romanov@nginx.com     NXT_READ(&h->content_length);
34186Smax.romanov@nginx.com 
342114Smax.romanov@nginx.com     RC(nxt_app_msg_read_size(task, rmsg, &s));
34386Smax.romanov@nginx.com     h->parsed_content_length = s;
34486Smax.romanov@nginx.com 
345114Smax.romanov@nginx.com     NXT_READ(&ctx->r.body.preread);
346114Smax.romanov@nginx.com 
347114Smax.romanov@nginx.com #undef NXT_READ
348114Smax.romanov@nginx.com #undef RC
34994Smax.romanov@nginx.com 
35086Smax.romanov@nginx.com     /* Further headers read moved to nxt_php_register_variables. */
3510Sigor@sysoev.ru     return NXT_OK;
352114Smax.romanov@nginx.com 
353114Smax.romanov@nginx.com fail:
354114Smax.romanov@nginx.com 
355114Smax.romanov@nginx.com     return rc;
3560Sigor@sysoev.ru }
3570Sigor@sysoev.ru 
3580Sigor@sysoev.ru 
35986Smax.romanov@nginx.com static nxt_int_t
36086Smax.romanov@nginx.com nxt_php_prepare_msg(nxt_task_t *task, nxt_app_request_t *r,
36186Smax.romanov@nginx.com     nxt_app_wmsg_t *wmsg)
36286Smax.romanov@nginx.com {
36386Smax.romanov@nginx.com     nxt_int_t                 rc;
36486Smax.romanov@nginx.com     nxt_http_field_t          *field;
36586Smax.romanov@nginx.com     nxt_app_request_header_t  *h;
36686Smax.romanov@nginx.com 
36786Smax.romanov@nginx.com     static const nxt_str_t prefix = nxt_string("HTTP_");
36886Smax.romanov@nginx.com     static const nxt_str_t eof = nxt_null_string;
36986Smax.romanov@nginx.com 
37086Smax.romanov@nginx.com     h = &r->header;
3710Sigor@sysoev.ru 
37286Smax.romanov@nginx.com #define RC(S)                                                                 \
37386Smax.romanov@nginx.com     do {                                                                      \
37486Smax.romanov@nginx.com         rc = (S);                                                             \
37586Smax.romanov@nginx.com         if (nxt_slow_path(rc != NXT_OK)) {                                    \
37686Smax.romanov@nginx.com             goto fail;                                                        \
37786Smax.romanov@nginx.com         }                                                                     \
37886Smax.romanov@nginx.com     } while(0)
37986Smax.romanov@nginx.com 
38086Smax.romanov@nginx.com #define NXT_WRITE(N)                                                          \
38186Smax.romanov@nginx.com     RC(nxt_app_msg_write_str(task, wmsg, N))
38286Smax.romanov@nginx.com 
38386Smax.romanov@nginx.com     /* TODO error handle, async mmap buffer assignment */
38486Smax.romanov@nginx.com 
38586Smax.romanov@nginx.com     NXT_WRITE(&h->method);
386112Smax.romanov@nginx.com     NXT_WRITE(&h->target);
387112Smax.romanov@nginx.com     if (h->path.start == h->target.start) {
388112Smax.romanov@nginx.com         NXT_WRITE(&eof);
389112Smax.romanov@nginx.com     } else {
390112Smax.romanov@nginx.com         NXT_WRITE(&h->path);
391112Smax.romanov@nginx.com     }
3920Sigor@sysoev.ru 
39386Smax.romanov@nginx.com     if (h->query.start != NULL) {
39486Smax.romanov@nginx.com         RC(nxt_app_msg_write_size(task, wmsg,
395112Smax.romanov@nginx.com                                   h->query.start - h->target.start + 1));
39686Smax.romanov@nginx.com     } else {
39786Smax.romanov@nginx.com         RC(nxt_app_msg_write_size(task, wmsg, 0));
39886Smax.romanov@nginx.com     }
39986Smax.romanov@nginx.com 
40086Smax.romanov@nginx.com     NXT_WRITE(&h->version);
40186Smax.romanov@nginx.com 
40286Smax.romanov@nginx.com     // PHP_SELF
40386Smax.romanov@nginx.com     // SCRIPT_NAME
40486Smax.romanov@nginx.com     // SCRIPT_FILENAME
40586Smax.romanov@nginx.com     // DOCUMENT_ROOT
40686Smax.romanov@nginx.com 
407114Smax.romanov@nginx.com     NXT_WRITE(&r->remote);
408114Smax.romanov@nginx.com 
409114Smax.romanov@nginx.com     NXT_WRITE(&h->host);
41086Smax.romanov@nginx.com     NXT_WRITE(&h->cookie);
41186Smax.romanov@nginx.com     NXT_WRITE(&h->content_type);
41286Smax.romanov@nginx.com     NXT_WRITE(&h->content_length);
41386Smax.romanov@nginx.com 
41486Smax.romanov@nginx.com     RC(nxt_app_msg_write_size(task, wmsg, h->parsed_content_length));
41586Smax.romanov@nginx.com 
41694Smax.romanov@nginx.com     NXT_WRITE(&r->body.preread);
41794Smax.romanov@nginx.com 
41886Smax.romanov@nginx.com     nxt_list_each(field, h->fields) {
41986Smax.romanov@nginx.com         RC(nxt_app_msg_write_prefixed_upcase(task, wmsg,
42086Smax.romanov@nginx.com                                              &prefix, &field->name));
42186Smax.romanov@nginx.com         NXT_WRITE(&field->value);
42286Smax.romanov@nginx.com 
42386Smax.romanov@nginx.com     } nxt_list_loop;
42486Smax.romanov@nginx.com 
42586Smax.romanov@nginx.com     /* end-of-headers mark */
42686Smax.romanov@nginx.com     NXT_WRITE(&eof);
42786Smax.romanov@nginx.com 
42886Smax.romanov@nginx.com #undef NXT_WRITE
42986Smax.romanov@nginx.com #undef RC
43086Smax.romanov@nginx.com 
43186Smax.romanov@nginx.com     return NXT_OK;
43286Smax.romanov@nginx.com 
43386Smax.romanov@nginx.com fail:
43486Smax.romanov@nginx.com 
43586Smax.romanov@nginx.com     return NXT_ERROR;
43686Smax.romanov@nginx.com }
4370Sigor@sysoev.ru 
4380Sigor@sysoev.ru 
43986Smax.romanov@nginx.com static nxt_int_t
44086Smax.romanov@nginx.com nxt_php_run(nxt_task_t *task,
44186Smax.romanov@nginx.com     nxt_app_rmsg_t *rmsg, nxt_app_wmsg_t *wmsg)
4420Sigor@sysoev.ru {
443114Smax.romanov@nginx.com     nxt_int_t                 rc;
44486Smax.romanov@nginx.com     zend_file_handle          file_handle;
44586Smax.romanov@nginx.com     nxt_php_run_ctx_t         run_ctx;
44686Smax.romanov@nginx.com     nxt_app_request_header_t  *h;
4470Sigor@sysoev.ru 
44886Smax.romanov@nginx.com     if (nxt_php_root.length == 0) {
4490Sigor@sysoev.ru         return NXT_ERROR;
4500Sigor@sysoev.ru     }
4510Sigor@sysoev.ru 
45286Smax.romanov@nginx.com     nxt_memzero(&run_ctx, sizeof(run_ctx));
45386Smax.romanov@nginx.com 
45486Smax.romanov@nginx.com     run_ctx.task = task;
45586Smax.romanov@nginx.com     run_ctx.rmsg = rmsg;
45686Smax.romanov@nginx.com     run_ctx.wmsg = wmsg;
45786Smax.romanov@nginx.com 
45886Smax.romanov@nginx.com     run_ctx.mem_pool = nxt_mp_create(1024, 128, 256, 32);
4590Sigor@sysoev.ru 
46086Smax.romanov@nginx.com     h = &run_ctx.r.header;
46186Smax.romanov@nginx.com 
462114Smax.romanov@nginx.com     rc = nxt_php_read_request(task, rmsg, &run_ctx);
463114Smax.romanov@nginx.com 
464114Smax.romanov@nginx.com     if (nxt_slow_path(rc != NXT_OK)) {
465114Smax.romanov@nginx.com         goto fail;
466114Smax.romanov@nginx.com     }
46786Smax.romanov@nginx.com 
46886Smax.romanov@nginx.com     SG(server_context) = &run_ctx;
469112Smax.romanov@nginx.com     SG(request_info).request_uri = (char *) h->target.start;
47086Smax.romanov@nginx.com     SG(request_info).request_method = (char *) h->method.start;
4710Sigor@sysoev.ru 
4720Sigor@sysoev.ru     SG(request_info).proto_num = 1001;
4730Sigor@sysoev.ru 
47486Smax.romanov@nginx.com     SG(request_info).query_string = (char *) h->query.start;
47586Smax.romanov@nginx.com     SG(request_info).content_length = h->parsed_content_length;
4760Sigor@sysoev.ru 
47786Smax.romanov@nginx.com     if (h->content_type.start != NULL) {
47886Smax.romanov@nginx.com         SG(request_info).content_type = (char *) h->content_type.start;
4790Sigor@sysoev.ru     }
4800Sigor@sysoev.ru 
4810Sigor@sysoev.ru     SG(sapi_headers).http_response_code = 200;
4820Sigor@sysoev.ru 
4830Sigor@sysoev.ru     SG(request_info).path_translated = NULL;
4840Sigor@sysoev.ru 
4850Sigor@sysoev.ru     file_handle.type = ZEND_HANDLE_FILENAME;
48686Smax.romanov@nginx.com     file_handle.filename = (char *) run_ctx.script.start;
4870Sigor@sysoev.ru     file_handle.free_filename = 0;
4880Sigor@sysoev.ru     file_handle.opened_path = NULL;
4890Sigor@sysoev.ru 
490*142Smax.romanov@nginx.com     nxt_debug(task, "handle.filename = '%s'", run_ctx.script.start);
491*142Smax.romanov@nginx.com 
49286Smax.romanov@nginx.com     if (nxt_php_path.start != NULL) {
49386Smax.romanov@nginx.com         nxt_debug(task, "run script %V in absolute mode", &nxt_php_path);
49486Smax.romanov@nginx.com     } else {
49586Smax.romanov@nginx.com         nxt_debug(task, "run script %V", &run_ctx.script);
49686Smax.romanov@nginx.com     }
4970Sigor@sysoev.ru 
4980Sigor@sysoev.ru     if (nxt_slow_path(php_request_startup() == FAILURE)) {
499*142Smax.romanov@nginx.com         nxt_debug(task, "php_request_startup() failed");
50086Smax.romanov@nginx.com         goto fail;
5010Sigor@sysoev.ru     }
5020Sigor@sysoev.ru 
5030Sigor@sysoev.ru     php_execute_script(&file_handle TSRMLS_CC);
5040Sigor@sysoev.ru     php_request_shutdown(NULL);
5050Sigor@sysoev.ru 
50686Smax.romanov@nginx.com     nxt_app_msg_flush(task, wmsg, 1);
50786Smax.romanov@nginx.com 
50886Smax.romanov@nginx.com     nxt_mp_destroy(run_ctx.mem_pool);
50986Smax.romanov@nginx.com 
5100Sigor@sysoev.ru     return NXT_OK;
51186Smax.romanov@nginx.com 
51286Smax.romanov@nginx.com fail:
51386Smax.romanov@nginx.com 
51486Smax.romanov@nginx.com     nxt_mp_destroy(run_ctx.mem_pool);
51586Smax.romanov@nginx.com 
51686Smax.romanov@nginx.com     return NXT_ERROR;
51786Smax.romanov@nginx.com }
51886Smax.romanov@nginx.com 
51986Smax.romanov@nginx.com 
52086Smax.romanov@nginx.com nxt_inline nxt_int_t
52186Smax.romanov@nginx.com nxt_php_write(nxt_php_run_ctx_t *ctx, const u_char *data, size_t len,
52286Smax.romanov@nginx.com     nxt_bool_t flush, nxt_bool_t last)
52386Smax.romanov@nginx.com {
52486Smax.romanov@nginx.com     nxt_int_t  rc;
52586Smax.romanov@nginx.com 
526114Smax.romanov@nginx.com     if (len > 0) {
527114Smax.romanov@nginx.com         rc = nxt_app_msg_write_raw(ctx->task, ctx->wmsg, data, len);
528114Smax.romanov@nginx.com     } else {
529114Smax.romanov@nginx.com         rc = NXT_OK;
530114Smax.romanov@nginx.com     }
53186Smax.romanov@nginx.com 
53286Smax.romanov@nginx.com     if (flush || last) {
53386Smax.romanov@nginx.com         rc = nxt_app_msg_flush(ctx->task, ctx->wmsg, last);
53486Smax.romanov@nginx.com     }
53586Smax.romanov@nginx.com 
53686Smax.romanov@nginx.com     return rc;
5370Sigor@sysoev.ru }
5380Sigor@sysoev.ru 
5390Sigor@sysoev.ru 
5400Sigor@sysoev.ru static int
5410Sigor@sysoev.ru nxt_php_startup(sapi_module_struct *sapi_module)
5420Sigor@sysoev.ru {
5430Sigor@sysoev.ru    return php_module_startup(sapi_module, NULL, 0);
5440Sigor@sysoev.ru }
5450Sigor@sysoev.ru 
5460Sigor@sysoev.ru 
5470Sigor@sysoev.ru #ifdef NXT_PHP7
5480Sigor@sysoev.ru static size_t
5490Sigor@sysoev.ru nxt_php_unbuffered_write(const char *str, size_t str_length TSRMLS_DC)
5500Sigor@sysoev.ru #else
5510Sigor@sysoev.ru static int
5520Sigor@sysoev.ru nxt_php_unbuffered_write(const char *str, uint str_length TSRMLS_DC)
5530Sigor@sysoev.ru #endif
5540Sigor@sysoev.ru {
555114Smax.romanov@nginx.com     nxt_int_t          rc;
55686Smax.romanov@nginx.com     nxt_php_run_ctx_t  *ctx;
5570Sigor@sysoev.ru 
55886Smax.romanov@nginx.com     ctx = SG(server_context);
5590Sigor@sysoev.ru 
560114Smax.romanov@nginx.com     rc = nxt_php_write(ctx, (u_char *) str, str_length, 1, 0);
561114Smax.romanov@nginx.com 
562114Smax.romanov@nginx.com     if (nxt_fast_path(rc == NXT_OK)) {
563114Smax.romanov@nginx.com         return str_length;
564114Smax.romanov@nginx.com     }
5650Sigor@sysoev.ru 
566114Smax.romanov@nginx.com     // TODO handle NXT_AGAIN
567114Smax.romanov@nginx.com     php_handle_aborted_connection();
568114Smax.romanov@nginx.com     return 0;
569114Smax.romanov@nginx.com }
570114Smax.romanov@nginx.com 
571114Smax.romanov@nginx.com 
572114Smax.romanov@nginx.com static void
573114Smax.romanov@nginx.com nxt_php_flush(void *server_context)
574114Smax.romanov@nginx.com {
575114Smax.romanov@nginx.com     nxt_php_run_ctx_t  *ctx;
576114Smax.romanov@nginx.com 
577114Smax.romanov@nginx.com     ctx = server_context;
578114Smax.romanov@nginx.com 
579114Smax.romanov@nginx.com     (void) nxt_app_msg_flush(ctx->task, ctx->wmsg, 0);
5800Sigor@sysoev.ru }
5810Sigor@sysoev.ru 
5820Sigor@sysoev.ru 
5830Sigor@sysoev.ru static int
5840Sigor@sysoev.ru nxt_php_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
5850Sigor@sysoev.ru {
5860Sigor@sysoev.ru     size_t               len;
587114Smax.romanov@nginx.com     u_char               *status, buf[64];
588114Smax.romanov@nginx.com     nxt_int_t            rc;
589114Smax.romanov@nginx.com     nxt_php_run_ctx_t    *ctx;
5900Sigor@sysoev.ru     sapi_header_struct   *h;
5910Sigor@sysoev.ru     zend_llist_position  zpos;
5920Sigor@sysoev.ru 
5930Sigor@sysoev.ru     static const u_char default_repsonse[]
5940Sigor@sysoev.ru         = "HTTP/1.1 200 OK\r\n"
5959Sigor@sysoev.ru           "Server: nginext/0.1\r\n"
5960Sigor@sysoev.ru           "Content-Type: text/html; charset=UTF-8\r\n"
5970Sigor@sysoev.ru           "Connection: close\r\n"
5980Sigor@sysoev.ru           "\r\n";
5990Sigor@sysoev.ru 
6000Sigor@sysoev.ru     static const u_char default_headers[]
6019Sigor@sysoev.ru         = "Server: nginext/0.1\r\n"
6020Sigor@sysoev.ru           "Connection: close\r\n";
6030Sigor@sysoev.ru 
60486Smax.romanov@nginx.com     static const u_char http_11[] = "HTTP/1.1 ";
60586Smax.romanov@nginx.com     static const u_char cr_lf[] = "\r\n";
60686Smax.romanov@nginx.com     static const u_char _200_ok[] = "200 OK";
60786Smax.romanov@nginx.com 
60886Smax.romanov@nginx.com     ctx = SG(server_context);
6090Sigor@sysoev.ru 
610114Smax.romanov@nginx.com #define RC(S)                                                                 \
611114Smax.romanov@nginx.com     do {                                                                      \
612114Smax.romanov@nginx.com         rc = (S);                                                             \
613114Smax.romanov@nginx.com         if (nxt_slow_path(rc != NXT_OK)) {                                    \
614114Smax.romanov@nginx.com             goto fail;                                                        \
615114Smax.romanov@nginx.com         }                                                                     \
616114Smax.romanov@nginx.com     } while(0)
617114Smax.romanov@nginx.com 
6180Sigor@sysoev.ru     if (SG(request_info).no_headers == 1) {
619114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, default_repsonse, sizeof(default_repsonse) - 1,
620114Smax.romanov@nginx.com                       1, 0));
6210Sigor@sysoev.ru         return SAPI_HEADER_SENT_SUCCESSFULLY;
6220Sigor@sysoev.ru     }
6230Sigor@sysoev.ru 
6240Sigor@sysoev.ru     if (SG(sapi_headers).http_status_line) {
625114Smax.romanov@nginx.com         status = (u_char *) SG(sapi_headers).http_status_line;
6260Sigor@sysoev.ru         len = nxt_strlen(status);
6270Sigor@sysoev.ru 
628114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, status, len, 0, 0));
6290Sigor@sysoev.ru 
6300Sigor@sysoev.ru     } else if (SG(sapi_headers).http_response_code) {
63186Smax.romanov@nginx.com         status = nxt_sprintf(buf, buf + sizeof(buf), "%03d",
6320Sigor@sysoev.ru                         SG(sapi_headers).http_response_code);
63386Smax.romanov@nginx.com         len = status - buf;
63486Smax.romanov@nginx.com 
635114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, http_11, sizeof(http_11) - 1, 0, 0));
636114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, buf, len, 0, 0));
6370Sigor@sysoev.ru 
6380Sigor@sysoev.ru     } else {
639114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, http_11, sizeof(http_11) - 1, 0, 0));
640114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, _200_ok, sizeof(_200_ok) - 1, 0, 0));
6410Sigor@sysoev.ru     }
6420Sigor@sysoev.ru 
643114Smax.romanov@nginx.com     RC(nxt_php_write(ctx, cr_lf, sizeof(cr_lf) - 1, 0, 0));
644114Smax.romanov@nginx.com     RC(nxt_php_write(ctx, default_headers, sizeof(default_headers) - 1, 0, 0));
6450Sigor@sysoev.ru 
6460Sigor@sysoev.ru     h = zend_llist_get_first_ex(&sapi_headers->headers, &zpos);
6470Sigor@sysoev.ru 
6480Sigor@sysoev.ru     while (h) {
649114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, (u_char *) h->header, h->header_len, 0, 0));
650114Smax.romanov@nginx.com         RC(nxt_php_write(ctx, cr_lf, sizeof(cr_lf) - 1, 0, 0));
6510Sigor@sysoev.ru 
6520Sigor@sysoev.ru         h = zend_llist_get_next_ex(&sapi_headers->headers, &zpos);
6530Sigor@sysoev.ru     }
6540Sigor@sysoev.ru 
655114Smax.romanov@nginx.com     RC(nxt_php_write(ctx, cr_lf, sizeof(cr_lf) - 1, 1, 0));
656114Smax.romanov@nginx.com 
657114Smax.romanov@nginx.com #undef RC
6580Sigor@sysoev.ru 
6590Sigor@sysoev.ru     return SAPI_HEADER_SENT_SUCCESSFULLY;
660114Smax.romanov@nginx.com 
661114Smax.romanov@nginx.com fail:
662114Smax.romanov@nginx.com 
663114Smax.romanov@nginx.com     // TODO handle NXT_AGAIN
664114Smax.romanov@nginx.com     return SAPI_HEADER_SEND_FAILED;
6650Sigor@sysoev.ru }
6660Sigor@sysoev.ru 
6670Sigor@sysoev.ru 
6680Sigor@sysoev.ru #ifdef NXT_PHP7
6690Sigor@sysoev.ru static size_t
6700Sigor@sysoev.ru nxt_php_read_post(char *buffer, size_t count_bytes TSRMLS_DC)
6710Sigor@sysoev.ru #else
6720Sigor@sysoev.ru static int
6730Sigor@sysoev.ru nxt_php_read_post(char *buffer, uint count_bytes TSRMLS_DC)
6740Sigor@sysoev.ru #endif
6750Sigor@sysoev.ru {
6760Sigor@sysoev.ru     off_t              rest;
6770Sigor@sysoev.ru     size_t             size;
67886Smax.romanov@nginx.com /*
6790Sigor@sysoev.ru     ssize_t            n;
6800Sigor@sysoev.ru     nxt_err_t          err;
6810Sigor@sysoev.ru     nxt_php_ctx_t      *ctx;
6820Sigor@sysoev.ru     nxt_app_request_t  *r;
68386Smax.romanov@nginx.com */
68486Smax.romanov@nginx.com     nxt_php_run_ctx_t         *ctx;
68586Smax.romanov@nginx.com     nxt_app_request_body_t    *b;
68686Smax.romanov@nginx.com     nxt_app_request_header_t  *h;
6870Sigor@sysoev.ru 
68886Smax.romanov@nginx.com     ctx = SG(server_context);
68986Smax.romanov@nginx.com     h = &ctx->r.header;
69086Smax.romanov@nginx.com     b = &ctx->r.body;
6910Sigor@sysoev.ru 
69286Smax.romanov@nginx.com     rest = h->parsed_content_length - SG(read_post_bytes);
69386Smax.romanov@nginx.com 
69486Smax.romanov@nginx.com     nxt_debug(ctx->task, "nxt_php_read_post %O", rest);
6950Sigor@sysoev.ru 
6960Sigor@sysoev.ru     if (rest == 0) {
6970Sigor@sysoev.ru         return 0;
6980Sigor@sysoev.ru     }
6990Sigor@sysoev.ru 
7000Sigor@sysoev.ru     size = 0;
7010Sigor@sysoev.ru #ifdef NXT_PHP7
7020Sigor@sysoev.ru     count_bytes = (size_t) nxt_min(rest, (off_t) count_bytes);
7030Sigor@sysoev.ru #else
7040Sigor@sysoev.ru     count_bytes = (uint) nxt_min(rest, (off_t) count_bytes);
7050Sigor@sysoev.ru #endif
7060Sigor@sysoev.ru 
70786Smax.romanov@nginx.com     if (b->preread.length != 0) {
70886Smax.romanov@nginx.com         size = nxt_min(b->preread.length, count_bytes);
7090Sigor@sysoev.ru 
71086Smax.romanov@nginx.com         nxt_memcpy(buffer, b->preread.start, size);
7110Sigor@sysoev.ru 
71286Smax.romanov@nginx.com         b->preread.length -= size;
71386Smax.romanov@nginx.com         b->preread.start += size;
7140Sigor@sysoev.ru 
7150Sigor@sysoev.ru         if (size == count_bytes) {
7160Sigor@sysoev.ru             return size;
7170Sigor@sysoev.ru         }
7180Sigor@sysoev.ru     }
7190Sigor@sysoev.ru 
72086Smax.romanov@nginx.com #if 0
72186Smax.romanov@nginx.com     nxt_debug(ctx->task, "recv %z", (size_t) count_bytes - size);
7220Sigor@sysoev.ru 
7230Sigor@sysoev.ru     n = recv(r->event_conn->socket.fd, buffer + size, count_bytes - size, 0);
7240Sigor@sysoev.ru 
7250Sigor@sysoev.ru     if (nxt_slow_path(n <= 0)) {
7260Sigor@sysoev.ru         err = (n == 0) ? 0 : nxt_socket_errno;
7270Sigor@sysoev.ru 
7280Sigor@sysoev.ru         nxt_log_error(NXT_LOG_ERR, r->log, "recv(%d, %uz) failed %E",
7290Sigor@sysoev.ru                       r->event_conn->socket.fd, (size_t) count_bytes - size,
7300Sigor@sysoev.ru                       err);
7310Sigor@sysoev.ru 
7320Sigor@sysoev.ru         return size;
7330Sigor@sysoev.ru     }
7340Sigor@sysoev.ru 
7350Sigor@sysoev.ru     return size + n;
73686Smax.romanov@nginx.com #endif
73786Smax.romanov@nginx.com     return size;
7380Sigor@sysoev.ru }
7390Sigor@sysoev.ru 
7400Sigor@sysoev.ru 
7410Sigor@sysoev.ru static char *
7420Sigor@sysoev.ru nxt_php_read_cookies(TSRMLS_D)
7430Sigor@sysoev.ru {
74486Smax.romanov@nginx.com     nxt_php_run_ctx_t  *ctx;
7450Sigor@sysoev.ru 
74686Smax.romanov@nginx.com     ctx = SG(server_context);
7470Sigor@sysoev.ru 
74894Smax.romanov@nginx.com     nxt_debug(ctx->task, "nxt_php_read_cookies");
74994Smax.romanov@nginx.com 
75086Smax.romanov@nginx.com     return (char *) ctx->r.header.cookie.start;
7510Sigor@sysoev.ru }
7520Sigor@sysoev.ru 
7530Sigor@sysoev.ru 
7540Sigor@sysoev.ru static void
7550Sigor@sysoev.ru nxt_php_register_variables(zval *track_vars_array TSRMLS_DC)
7560Sigor@sysoev.ru {
757114Smax.romanov@nginx.com     u_char                    *colon;
75886Smax.romanov@nginx.com     nxt_str_t                 n, v;
75986Smax.romanov@nginx.com     nxt_int_t                 rc;
760114Smax.romanov@nginx.com     nxt_str_t                 host, server_name, server_port;
76186Smax.romanov@nginx.com     nxt_task_t                *task;
76286Smax.romanov@nginx.com     nxt_php_run_ctx_t         *ctx;
76386Smax.romanov@nginx.com     nxt_app_request_header_t  *h;
7640Sigor@sysoev.ru 
765114Smax.romanov@nginx.com     static nxt_str_t def_host = nxt_string("localhost");
766114Smax.romanov@nginx.com     static nxt_str_t def_port = nxt_string("80");
767114Smax.romanov@nginx.com 
76886Smax.romanov@nginx.com     ctx = SG(server_context);
7690Sigor@sysoev.ru 
77086Smax.romanov@nginx.com     h = &ctx->r.header;
77186Smax.romanov@nginx.com     task = ctx->task;
7720Sigor@sysoev.ru 
77386Smax.romanov@nginx.com     nxt_debug(task, "php register variables");
7740Sigor@sysoev.ru 
775114Smax.romanov@nginx.com #define NXT_PHP_SET(n, v)                                                     \
776*142Smax.romanov@nginx.com     nxt_debug(task, "php: register %s='%V'", n, &v);                          \
777114Smax.romanov@nginx.com     php_register_variable_safe((char *) (n), (char *) (v).start,              \
778114Smax.romanov@nginx.com                                (v).length, track_vars_array TSRMLS_CC)        \
779114Smax.romanov@nginx.com 
780114Smax.romanov@nginx.com     NXT_PHP_SET("SERVER_PROTOCOL", h->version);
78186Smax.romanov@nginx.com 
78286Smax.romanov@nginx.com /*
78386Smax.romanov@nginx.com  * 'SCRIPT_NAME'
78486Smax.romanov@nginx.com  * Contains the current script's path. This is useful for pages which need to
78586Smax.romanov@nginx.com  * point to themselves. The __FILE__ constant contains the full path and
78686Smax.romanov@nginx.com  * filename of the current (i.e. included) file.
78786Smax.romanov@nginx.com  */
78886Smax.romanov@nginx.com 
78986Smax.romanov@nginx.com /*
79086Smax.romanov@nginx.com  * 'SCRIPT_FILENAME'
79186Smax.romanov@nginx.com  * The absolute pathname of the currently executing script.
79286Smax.romanov@nginx.com  */
79386Smax.romanov@nginx.com 
79486Smax.romanov@nginx.com /*
79586Smax.romanov@nginx.com  * 'DOCUMENT_ROOT'
79686Smax.romanov@nginx.com  * The document root directory under which the current script is executing,
79786Smax.romanov@nginx.com  * as defined in the server's configuration file.
79886Smax.romanov@nginx.com  */
7990Sigor@sysoev.ru 
80086Smax.romanov@nginx.com     if (nxt_php_script.start != NULL) {
80186Smax.romanov@nginx.com     // ABS_MODE
80286Smax.romanov@nginx.com /*
80386Smax.romanov@nginx.com  * 'PHP_SELF'
80486Smax.romanov@nginx.com  * The filename of the currently executing script, relative to the document
80586Smax.romanov@nginx.com  * root. For instance, $_SERVER['PHP_SELF'] in a script at the address
80686Smax.romanov@nginx.com  * http://example.com/foo/bar.php would be /foo/bar.php. The __FILE__ constant
80786Smax.romanov@nginx.com  * contains the full path and filename of the current (i.e. included) file.
80886Smax.romanov@nginx.com  * If PHP is running as a command-line processor this variable contains the
80986Smax.romanov@nginx.com  * script name since PHP 4.3.0. Previously it was not available.
81086Smax.romanov@nginx.com  */
811114Smax.romanov@nginx.com         NXT_PHP_SET("PHP_SELF", nxt_php_script);
812114Smax.romanov@nginx.com         NXT_PHP_SET("SCRIPT_NAME", nxt_php_script);
81386Smax.romanov@nginx.com     } else {
814114Smax.romanov@nginx.com         NXT_PHP_SET("PHP_SELF", h->path);
815114Smax.romanov@nginx.com         NXT_PHP_SET("SCRIPT_NAME", h->path);
81686Smax.romanov@nginx.com     }
8170Sigor@sysoev.ru 
818114Smax.romanov@nginx.com     NXT_PHP_SET("SCRIPT_FILENAME", ctx->script);
819114Smax.romanov@nginx.com     NXT_PHP_SET("DOCUMENT_ROOT", nxt_php_root);
8200Sigor@sysoev.ru 
821114Smax.romanov@nginx.com     NXT_PHP_SET("REQUEST_METHOD", h->method);
822114Smax.romanov@nginx.com     NXT_PHP_SET("REQUEST_URI", h->target);
8230Sigor@sysoev.ru 
82486Smax.romanov@nginx.com     if (h->query.start != NULL) {
825114Smax.romanov@nginx.com         NXT_PHP_SET("QUERY_STRING", h->query);
8260Sigor@sysoev.ru     }
8270Sigor@sysoev.ru 
82886Smax.romanov@nginx.com     if (h->content_type.start != NULL) {
829114Smax.romanov@nginx.com         NXT_PHP_SET("CONTENT_TYPE", h->content_type);
8300Sigor@sysoev.ru     }
8310Sigor@sysoev.ru 
83286Smax.romanov@nginx.com     if (h->content_length.start != NULL) {
833114Smax.romanov@nginx.com         NXT_PHP_SET("CONTENT_LENGTH", h->content_length);
834114Smax.romanov@nginx.com     }
835114Smax.romanov@nginx.com 
836114Smax.romanov@nginx.com     host = h->host;
837114Smax.romanov@nginx.com     if (host.length == 0) {
838114Smax.romanov@nginx.com         host = def_host;
83986Smax.romanov@nginx.com     }
8400Sigor@sysoev.ru 
841114Smax.romanov@nginx.com     server_name = host;
842114Smax.romanov@nginx.com     colon = nxt_memchr(host.start, ':', host.length);
843114Smax.romanov@nginx.com 
844114Smax.romanov@nginx.com     if (colon != NULL) {
845114Smax.romanov@nginx.com         server_name.length = colon - host.start;
846114Smax.romanov@nginx.com 
847114Smax.romanov@nginx.com         server_port.start = colon + 1;
848114Smax.romanov@nginx.com         server_port.length = host.length - server_name.length - 1;
849114Smax.romanov@nginx.com     } else {
850114Smax.romanov@nginx.com         server_port = def_port;
851114Smax.romanov@nginx.com     }
852114Smax.romanov@nginx.com 
853114Smax.romanov@nginx.com     NXT_PHP_SET("SERVER_NAME", server_name);
854114Smax.romanov@nginx.com     NXT_PHP_SET("SERVER_PORT", server_port);
855114Smax.romanov@nginx.com 
856114Smax.romanov@nginx.com     NXT_PHP_SET("REMOTE_ADDR", ctx->r.remote);
857114Smax.romanov@nginx.com 
85894Smax.romanov@nginx.com     while (nxt_app_msg_read_str(task, ctx->rmsg, &n) == NXT_OK) {
85986Smax.romanov@nginx.com         if (nxt_slow_path(n.length == 0)) {
86086Smax.romanov@nginx.com             break;
8610Sigor@sysoev.ru         }
8620Sigor@sysoev.ru 
86394Smax.romanov@nginx.com         rc = nxt_app_msg_read_str(task, ctx->rmsg, &v);
86494Smax.romanov@nginx.com         if (nxt_slow_path(rc != NXT_OK)) {
86594Smax.romanov@nginx.com             break;
86694Smax.romanov@nginx.com         }
86794Smax.romanov@nginx.com 
868114Smax.romanov@nginx.com         NXT_PHP_SET(n.start, v);
8690Sigor@sysoev.ru     }
870114Smax.romanov@nginx.com 
871114Smax.romanov@nginx.com #undef NXT_PHP_SET
8720Sigor@sysoev.ru }
8730Sigor@sysoev.ru 
8740Sigor@sysoev.ru 
8750Sigor@sysoev.ru static void
87686Smax.romanov@nginx.com nxt_php_log_message(char *message
87786Smax.romanov@nginx.com #ifdef NXT_HAVE_PHP_LOG_MESSAGE_WITH_SYSLOG_TYPE
87886Smax.romanov@nginx.com                                 , int syslog_type_int
87986Smax.romanov@nginx.com #endif
88086Smax.romanov@nginx.com )
8810Sigor@sysoev.ru {
8820Sigor@sysoev.ru     return;
8830Sigor@sysoev.ru }
884