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