📄 roxen.c
字号:
push_int(SG(sapi_headers).http_response_code); if(s_headermap && s_headermap->type == PIKE_T_MAPPING) ref_push_mapping(s_headermap->u.mapping); else push_int(0); safe_apply(MY_FD_OBJ, "send_headers", 2); pop_stack(); return SAPI_HEADER_SENT_SUCCESSFULLY;}static intphp_roxen_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){ int res = 0; THREAD_SAFE_RUN(res = php_roxen_low_send_headers(sapi_headers TSRMLS_CC), "send headers"); return res;}/* * php_roxen_sapi_read_post() reads a specified number of bytes from * the client. Used for POST/PUT requests. */INLINE static int php_roxen_low_read_post(char *buf, uint count_bytes){ uint total_read = 0;#ifdef ROXEN_USE_ZTS GET_THIS();#endif TSRMLS_FETCH(); if(!MY_FD_OBJ->prog) { PG(connection_status) = PHP_CONNECTION_ABORTED; zend_bailout(); return -1; } push_int(count_bytes); safe_apply(MY_FD_OBJ, "read_post", 1); if(Pike_sp[-1].type == PIKE_T_STRING) { MEMCPY(buf, Pike_sp[-1].u.string->str, (total_read = Pike_sp[-1].u.string->len)); buf[total_read] = '\0'; } else total_read = 0; pop_stack(); return total_read;}static intphp_roxen_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC){ uint total_read = 0; THREAD_SAFE_RUN(total_read = php_roxen_low_read_post(buf, count_bytes), "read post"); return total_read;}/* * php_roxen_sapi_read_cookies() returns the Cookie header from * the HTTP request header */ static char *php_roxen_sapi_read_cookies(TSRMLS_D){ char *cookies; cookies = lookup_string_header("HTTP_COOKIE", NULL); return cookies;}static void php_info_roxen(ZEND_MODULE_INFO_FUNC_ARGS){ /* char buf[512]; */ php_info_print_table_start(); php_info_print_table_row(2, "SAPI module version", "$Id: roxen.c,v 1.53.2.5.6.2 2007/01/01 09:46:52 sebastian Exp $"); /* php_info_print_table_row(2, "Build date", Ns_InfoBuildDate()); php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile()); php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog()); php_info_print_table_row(2, "Installation path", Ns_InfoHomePath()); php_info_print_table_row(2, "Hostname of server", Ns_InfoHostname()); php_info_print_table_row(2, "Source code label", Ns_InfoLabel()); php_info_print_table_row(2, "Server platform", Ns_InfoPlatform()); snprintf(buf, 511, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion()); php_info_print_table_row(2, "Server version", buf); snprintf(buf, 511, "%d day(s), %02d:%02d:%02d", uptime / 86400, (uptime / 3600) % 24, (uptime / 60) % 60, uptime % 60); php_info_print_table_row(2, "Server uptime", buf); */ php_info_print_table_end();}static zend_module_entry php_roxen_module = { STANDARD_MODULE_HEADER, "Roxen", NULL, NULL, NULL, NULL, NULL, php_info_roxen, NULL, STANDARD_MODULE_PROPERTIES};static int php_roxen_startup(sapi_module_struct *sapi_module){ if(php_module_startup(sapi_module, &php_roxen_module, 1) == FAILURE) { return FAILURE; } else { return SUCCESS; }}/* this structure is static (as in "it does not change") */static sapi_module_struct roxen_sapi_module = { "roxen", "Roxen", php_roxen_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ NULL, /* activate */ NULL, /* deactivate */ php_roxen_sapi_ub_write, /* unbuffered write */ NULL, /* flush */ NULL, /* get uid */ NULL, /* getenv */ php_error, /* error handler */ php_roxen_sapi_header_handler, /* header handler */ php_roxen_sapi_send_headers, /* send headers handler */ NULL, /* send header handler */ php_roxen_sapi_read_post, /* read POST data */ php_roxen_sapi_read_cookies, /* read Cookies */ NULL, /* register server variables */ NULL, /* Log message */ NULL, /* Block interruptions */ NULL, /* Unblock interruptions */ STANDARD_SAPI_MODULE_PROPERTIES};/* * php_roxen_hash_environment() populates the php script environment * with a number of variables. HTTP_* variables are created for * the HTTP header data, so that a script can access these. */#define ADD_STRING(name) \ MAKE_STD_ZVAL(pval); \ pval->type = IS_STRING; \ pval->value.str.len = strlen(buf); \ pval->value.str.val = estrndup(buf, pval->value.str.len); \ zend_hash_update(&EG(symbol_table), name, sizeof(name), \ &pval, sizeof(zval *), NULL)static voidphp_roxen_hash_environment(TSRMLS_D){ int i; char buf[512]; zval *pval; struct svalue *headers; struct pike_string *sind; struct array *indices; struct svalue *ind, *val;#ifdef ROXEN_USE_ZTS GET_THIS();#endif sind = make_shared_string("env"); headers = low_mapping_string_lookup(REQUEST_DATA, sind); free_string(sind); if(headers && headers->type == PIKE_T_MAPPING) { indices = mapping_indices(headers->u.mapping); for(i = 0; i < indices->size; i++) { ind = &indices->item[i]; val = low_mapping_lookup(headers->u.mapping, ind); if(ind && ind->type == PIKE_T_STRING && val && val->type == PIKE_T_STRING) { int buf_len; buf_len = MIN(511, ind->u.string->len); strncpy(buf, ind->u.string->str, buf_len); buf[buf_len] = '\0'; /* Terminate correctly */ MAKE_STD_ZVAL(pval); pval->type = IS_STRING; pval->value.str.len = val->u.string->len; pval->value.str.val = estrndup(val->u.string->str, pval->value.str.len); zend_hash_update(&EG(symbol_table), buf, buf_len + 1, &pval, sizeof(zval *), NULL); } } free_array(indices); } /* MAKE_STD_ZVAL(pval); pval->type = IS_LONG; pval->value.lval = Ns_InfoBootTime(); zend_hash_update(&EG(symbol_table), "SERVER_BOOTTIME", sizeof("SERVER_BOOTTIME"), &pval, sizeof(zval *), NULL); */}/* * php_roxen_module_main() is called by the per-request handler and * "executes" the script */static int php_roxen_module_main(TSRMLS_D){ int res, len; char *dir; zend_file_handle file_handle = {0};#ifdef ROXEN_USE_ZTS GET_THIS();#endif file_handle.type = ZEND_HANDLE_FILENAME; file_handle.filename = THIS->filename; file_handle.free_filename = 0; file_handle.opened_path = NULL; THREADS_ALLOW(); res = php_request_startup(TSRMLS_C); THREADS_DISALLOW(); if(res == FAILURE) { return 0; } php_roxen_hash_environment(TSRMLS_C); THREADS_ALLOW(); php_execute_script(&file_handle TSRMLS_CC); php_request_shutdown(NULL); THREADS_DISALLOW(); return 1;}/* * The php_roxen_request_handler() is called per request and handles * everything for one request. */void f_php_roxen_request_handler(INT32 args){ struct object *my_fd_obj; struct mapping *request_data; struct svalue *done_callback, *raw_fd; struct pike_string *script, *ind; int status = 1;#ifdef ROXEN_USE_ZTS GET_THIS();#endif TSRMLS_FETCH(); if(current_thread == th_self()) php_error(E_WARNING, "PHP4.Interpreter->run: Tried to run a PHP-script from a PHP " "callback!"); get_all_args("PHP4.Interpreter->run", args, "%S%m%O%*", &script, &request_data, &my_fd_obj, &done_callback); if(done_callback->type != PIKE_T_FUNCTION) php_error(E_WARNING, "PHP4.Interpreter->run: Bad argument 4, expected function.\n"); PHP_LOCK(THIS); /* Need to lock here or reusing the same object might cause * problems in changing stuff in that object */#ifndef ROXEN_USE_ZTS GET_THIS();#endif THIS->request_data = request_data; THIS->my_fd_obj = my_fd_obj; THIS->filename = script->str; current_thread = th_self(); SG(request_info).query_string = lookup_string_header("QUERY_STRING", 0); SG(server_context) = (void *)1; /* avoid server_context == NULL */ /* path_translated is apparently the absolute path to the file, not the translated PATH_INFO */ SG(request_info).path_translated = lookup_string_header("SCRIPT_FILENAME", NULL); SG(request_info).request_uri = lookup_string_header("DOCUMENT_URI", NULL); if(!SG(request_info).request_uri) SG(request_info).request_uri = lookup_string_header("SCRIPT_NAME", NULL); SG(request_info).request_method = lookup_string_header("REQUEST_METHOD", "GET"); SG(request_info).content_length = lookup_integer_header("HTTP_CONTENT_LENGTH", 0); SG(request_info).content_type = lookup_string_header("HTTP_CONTENT_TYPE", NULL); SG(sapi_headers).http_response_code = 200; /* FIXME: Check for auth stuff needs to be fixed... */ SG(request_info).auth_user = NULL; SG(request_info).auth_password = NULL; ind = make_shared_binary_string("my_fd", 5); raw_fd = low_mapping_string_lookup(THIS->request_data, ind); if(raw_fd && raw_fd->type == PIKE_T_OBJECT) { int fd = fd_from_object(raw_fd->u.object); if(fd == -1) php_error(E_WARNING, "PHP4.Interpreter->run: my_fd object not open or not an FD.\n"); THIS->my_fd = fd; } else THIS->my_fd = 0; status = php_roxen_module_main(TSRMLS_C); current_thread = -1; apply_svalue(done_callback, 0); pop_stack(); pop_n_elems(args); push_int(status); PHP_UNLOCK(THIS);}/* Clear the object global struct */static void clear_struct(struct object *o){ MEMSET(Pike_fp->current_storage, 0, sizeof(php_roxen_request));}/* * pike_module_init() is called by Pike once at startup * * This functions allocates basic structures */void pike_module_init( void ){ if (!roxen_php_initialized) {#ifdef ZTS tsrm_startup(1, 1, 0, NULL);#ifdef ROXEN_USE_ZTS ts_allocate_id(&roxen_globals_id, sizeof(php_roxen_request), NULL, NULL);#endif #endif sapi_startup(&roxen_sapi_module); /*php_roxen_startup(&roxen_sapi_module); removed - should be called from SAPI activation*/ roxen_php_initialized = 1; PHP_INIT_LOCK(); } start_new_program(); /* Text */ ADD_STORAGE(php_roxen_request); set_init_callback(clear_struct); pike_add_function("run", f_php_roxen_request_handler, "function(string, mapping, object, function:int)", 0); add_program_constant("Interpreter", (php_program = end_program()), 0);}/* * pike_module_exit() performs the last steps before the * server exists. Shutdowns basic services and frees memory */void pike_module_exit(void){ roxen_php_initialized = 0; roxen_sapi_module.shutdown(&roxen_sapi_module); if(php_program) free_program(php_program);#ifdef ZTS tsrm_shutdown();#endif PHP_DESTROY();}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -