|
@@ -1,208 +1,305 @@
|
|
|
-/*
|
|
|
- +----------------------------------------------------------------------+
|
|
|
- | PHP Version 5 |
|
|
|
- +----------------------------------------------------------------------+
|
|
|
- | Copyright (c) 1997-2015 The PHP Group |
|
|
|
- +----------------------------------------------------------------------+
|
|
|
- | This source file is subject to version 3.01 of the PHP license, |
|
|
|
- | that is bundled with this package in the file LICENSE, and is |
|
|
|
- | available through the world-wide-web at the following url: |
|
|
|
- | http://www.php.net/license/3_01.txt |
|
|
|
- | If you did not receive a copy of the PHP license and are unable to |
|
|
|
- | obtain it through the world-wide-web, please send a note to |
|
|
|
- | license@php.net so we can mail you a copy immediately. |
|
|
|
- +----------------------------------------------------------------------+
|
|
|
- | Author: |
|
|
|
- +----------------------------------------------------------------------+
|
|
|
-*/
|
|
|
-
|
|
|
-/* $Id$ */
|
|
|
-
|
|
|
-#ifdef HAVE_CONFIG_H
|
|
|
-#include "config.h"
|
|
|
-#endif
|
|
|
-
|
|
|
-#include "php.h"
|
|
|
-#include "php_ini.h"
|
|
|
-#include "ext/standard/info.h"
|
|
|
-#include "php_fcgi.h"
|
|
|
-#include <fcgi_stdio.h>
|
|
|
-
|
|
|
-static int le_fcgi;
|
|
|
-
|
|
|
-const zend_function_entry fcgi_functions[] = {
|
|
|
- PHP_FE(confirm_fcgi_compiled, NULL) /* For testing, remove later. */
|
|
|
- PHP_FE(fcgi_init, NULL)
|
|
|
- PHP_FE(fcgi_fini, NULL)
|
|
|
- PHP_FE(fcgi_accept, NULL)
|
|
|
- PHP_FE(fcgi_finish, NULL)
|
|
|
- PHP_FE(fcgi_getparam, NULL)
|
|
|
- PHP_FE(fcgi_echo, NULL)
|
|
|
- PHP_FE(fcgi_getcontent, NULL)
|
|
|
- PHP_FE_END /* Must be the last line in fcgi_functions[] */
|
|
|
-};
|
|
|
-
|
|
|
-zend_module_entry fcgi_module_entry = {
|
|
|
-#if ZEND_MODULE_API_NO >= 20010901
|
|
|
- STANDARD_MODULE_HEADER,
|
|
|
-#endif
|
|
|
- "fcgi",
|
|
|
- fcgi_functions,
|
|
|
- PHP_MINIT(fcgi),
|
|
|
- PHP_MSHUTDOWN(fcgi),
|
|
|
- PHP_RINIT(fcgi), /* Replace with NULL if there's nothing to do at request start */
|
|
|
- PHP_RSHUTDOWN(fcgi), /* Replace with NULL if there's nothing to do at request end */
|
|
|
- PHP_MINFO(fcgi),
|
|
|
-#if ZEND_MODULE_API_NO >= 20010901
|
|
|
- PHP_FCGI_VERSION,
|
|
|
-#endif
|
|
|
- STANDARD_MODULE_PROPERTIES
|
|
|
-};
|
|
|
-/* }}} */
|
|
|
-
|
|
|
-#ifdef COMPILE_DL_FCGI
|
|
|
-ZEND_GET_MODULE(fcgi)
|
|
|
-#endif
|
|
|
-
|
|
|
-PHP_MINIT_FUNCTION(fcgi)
|
|
|
-{
|
|
|
- /* If you have INI entries, uncomment these lines
|
|
|
- REGISTER_INI_ENTRIES();
|
|
|
- */
|
|
|
- return SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
-PHP_MSHUTDOWN_FUNCTION(fcgi)
|
|
|
-{
|
|
|
- /* uncomment this line if you have INI entries
|
|
|
- UNREGISTER_INI_ENTRIES();
|
|
|
- */
|
|
|
- return SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
-PHP_RINIT_FUNCTION(fcgi)
|
|
|
-{
|
|
|
- return SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
-PHP_RSHUTDOWN_FUNCTION(fcgi)
|
|
|
-{
|
|
|
- return SUCCESS;
|
|
|
-}
|
|
|
-
|
|
|
-PHP_MINFO_FUNCTION(fcgi)
|
|
|
-{
|
|
|
- php_info_print_table_start();
|
|
|
- php_info_print_table_header(2, "fcgi support", "enabled");
|
|
|
- php_info_print_table_end();
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(confirm_fcgi_compiled)
|
|
|
-{
|
|
|
- char *arg = NULL;
|
|
|
- int arg_len, len;
|
|
|
- char *strg;
|
|
|
-
|
|
|
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- len = spprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "fcgi", arg);
|
|
|
- RETURN_STRINGL(strg, len, 0);
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_init)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_fini)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-static FCGX_Stream* stInstream;
|
|
|
-static FCGX_Stream* stOutstream;
|
|
|
-static FCGX_Stream* stErrstream;
|
|
|
-static FCGX_ParamArray stParams;
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_accept)
|
|
|
-{
|
|
|
- int ret = FCGX_Accept(&stInstream,&stOutstream,&stErrstream,&stParams);
|
|
|
-
|
|
|
- if(stInstream == NULL) {
|
|
|
- RETVAL_LONG(-1);
|
|
|
- }
|
|
|
- if(stOutstream == NULL) {
|
|
|
- RETVAL_LONG(-1);
|
|
|
- }
|
|
|
- if(stErrstream == NULL) {
|
|
|
- RETVAL_LONG(-1);
|
|
|
- }
|
|
|
-
|
|
|
- RETVAL_LONG(ret);
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_getparam)
|
|
|
-{
|
|
|
- char *arg = NULL;
|
|
|
- int arg_len;
|
|
|
-
|
|
|
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- const char* ret = FCGX_GetParam(arg, stParams);
|
|
|
- ret = (ret == NULL) ? "" : ret;
|
|
|
-
|
|
|
- char* result = estrdup(ret);
|
|
|
- RETURN_STRINGL(result,strlen(result),0);
|
|
|
-}
|
|
|
-
|
|
|
-static int content_length()
|
|
|
-{
|
|
|
- const char* pbuf = FCGX_GetParam("CONTENT_LENGTH", stParams);
|
|
|
- if(pbuf)
|
|
|
- {
|
|
|
- if(strlen(pbuf) == 0)
|
|
|
- return 0;
|
|
|
- else
|
|
|
- return atoi(pbuf);
|
|
|
- } else {
|
|
|
- return 0;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_getcontent)
|
|
|
-{
|
|
|
- int con_len = content_length();
|
|
|
- if(con_len) {
|
|
|
- char* pCon = (char*)malloc(con_len + 1);
|
|
|
- con_len = FCGX_GetStr(pCon, con_len, stInstream);
|
|
|
- pCon[con_len] = '\0';
|
|
|
-
|
|
|
- char* result = estrdup(pCon);
|
|
|
- RETURN_STRINGL(result,strlen(result),0);
|
|
|
- } else {
|
|
|
- char* result = estrdup("");
|
|
|
- RETURN_STRINGL(result,strlen(result),0);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_echo)
|
|
|
-{
|
|
|
- char *arg = NULL;
|
|
|
- int arg_len;
|
|
|
-
|
|
|
- if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if(arg != NULL) {
|
|
|
- FCGX_PutS(arg,stOutstream);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-PHP_FUNCTION(fcgi_finish)
|
|
|
-{
|
|
|
- FCGX_Finish();
|
|
|
-}
|
|
|
-
|
|
|
+/*
|
|
|
+ +----------------------------------------------------------------------+
|
|
|
+ | PHP Version 5 |
|
|
|
+ +----------------------------------------------------------------------+
|
|
|
+ | Copyright (c) 1997-2015 The PHP Group |
|
|
|
+ +----------------------------------------------------------------------+
|
|
|
+ | This source file is subject to version 3.01 of the PHP license, |
|
|
|
+ | that is bundled with this package in the file LICENSE, and is |
|
|
|
+ | available through the world-wide-web at the following url: |
|
|
|
+ | http://www.php.net/license/3_01.txt |
|
|
|
+ | If you did not receive a copy of the PHP license and are unable to |
|
|
|
+ | obtain it through the world-wide-web, please send a note to |
|
|
|
+ | license@php.net so we can mail you a copy immediately. |
|
|
|
+ +----------------------------------------------------------------------+
|
|
|
+ | Author: |
|
|
|
+ +----------------------------------------------------------------------+
|
|
|
+*/
|
|
|
+
|
|
|
+/* $Id$ */
|
|
|
+
|
|
|
+#ifdef HAVE_CONFIG_H
|
|
|
+#include "config.h"
|
|
|
+#endif
|
|
|
+
|
|
|
+#include "php.h"
|
|
|
+#include "php_ini.h"
|
|
|
+#include "ext/standard/info.h"
|
|
|
+#include "php_fcgi.h"
|
|
|
+#include <fcgi_stdio.h>
|
|
|
+#include "multipart_parser.h"
|
|
|
+#include "multipart_parser.c"
|
|
|
+
|
|
|
+static int le_fcgi;
|
|
|
+
|
|
|
+const zend_function_entry fcgi_functions[] = {
|
|
|
+ PHP_FE(confirm_fcgi_compiled, NULL) /* For testing, remove later. */
|
|
|
+ PHP_FE(fcgi_init, NULL)
|
|
|
+ PHP_FE(fcgi_fini, NULL)
|
|
|
+ PHP_FE(fcgi_accept, NULL)
|
|
|
+ PHP_FE(fcgi_finish, NULL)
|
|
|
+ PHP_FE(fcgi_getparam, NULL)
|
|
|
+ PHP_FE(fcgi_echo, NULL)
|
|
|
+ PHP_FE(fcgi_getcontent, NULL)
|
|
|
+ PHP_FE_END /* Must be the last line in fcgi_functions[] */
|
|
|
+};
|
|
|
+
|
|
|
+zend_module_entry fcgi_module_entry = {
|
|
|
+#if ZEND_MODULE_API_NO >= 20010901
|
|
|
+ STANDARD_MODULE_HEADER,
|
|
|
+#endif
|
|
|
+ "fcgi",
|
|
|
+ fcgi_functions,
|
|
|
+ PHP_MINIT(fcgi),
|
|
|
+ PHP_MSHUTDOWN(fcgi),
|
|
|
+ PHP_RINIT(fcgi), /* Replace with NULL if there's nothing to do at request start */
|
|
|
+ PHP_RSHUTDOWN(fcgi), /* Replace with NULL if there's nothing to do at request end */
|
|
|
+ PHP_MINFO(fcgi),
|
|
|
+#if ZEND_MODULE_API_NO >= 20010901
|
|
|
+ PHP_FCGI_VERSION,
|
|
|
+#endif
|
|
|
+ STANDARD_MODULE_PROPERTIES
|
|
|
+};
|
|
|
+/* }}} */
|
|
|
+
|
|
|
+#ifdef COMPILE_DL_FCGI
|
|
|
+ZEND_GET_MODULE(fcgi)
|
|
|
+#endif
|
|
|
+
|
|
|
+PHP_MINIT_FUNCTION(fcgi)
|
|
|
+{
|
|
|
+ /* If you have INI entries, uncomment these lines
|
|
|
+ REGISTER_INI_ENTRIES();
|
|
|
+ */
|
|
|
+ return SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+PHP_MSHUTDOWN_FUNCTION(fcgi)
|
|
|
+{
|
|
|
+ /* uncomment this line if you have INI entries
|
|
|
+ UNREGISTER_INI_ENTRIES();
|
|
|
+ */
|
|
|
+ return SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+PHP_RINIT_FUNCTION(fcgi)
|
|
|
+{
|
|
|
+ return SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+PHP_RSHUTDOWN_FUNCTION(fcgi)
|
|
|
+{
|
|
|
+ return SUCCESS;
|
|
|
+}
|
|
|
+
|
|
|
+PHP_MINFO_FUNCTION(fcgi)
|
|
|
+{
|
|
|
+ php_info_print_table_start();
|
|
|
+ php_info_print_table_header(2, "fcgi support", "enabled");
|
|
|
+ php_info_print_table_end();
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(confirm_fcgi_compiled)
|
|
|
+{
|
|
|
+ char *arg = NULL;
|
|
|
+ int arg_len, len;
|
|
|
+ char *strg;
|
|
|
+
|
|
|
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ len = sprintf(&strg, 0, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "fcgi", arg);
|
|
|
+ RETURN_STRINGL(strg, len, 0);
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_init)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_fini)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+static FCGX_Stream* stInstream;
|
|
|
+static FCGX_Stream* stOutstream;
|
|
|
+static FCGX_Stream* stErrstream;
|
|
|
+static FCGX_ParamArray stParams;
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_accept)
|
|
|
+{
|
|
|
+ int ret = FCGX_Accept(&stInstream,&stOutstream,&stErrstream,&stParams);
|
|
|
+
|
|
|
+ if(stInstream == NULL) {
|
|
|
+ RETVAL_LONG(-1);
|
|
|
+ }
|
|
|
+ if(stOutstream == NULL) {
|
|
|
+ RETVAL_LONG(-1);
|
|
|
+ }
|
|
|
+ if(stErrstream == NULL) {
|
|
|
+ RETVAL_LONG(-1);
|
|
|
+ }
|
|
|
+
|
|
|
+ RETVAL_LONG(ret);
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_getparam)
|
|
|
+{
|
|
|
+ char *arg = NULL;
|
|
|
+ int arg_len;
|
|
|
+
|
|
|
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const char* ret = FCGX_GetParam(arg, stParams);
|
|
|
+ ret = (ret == NULL) ? "" : ret;
|
|
|
+
|
|
|
+ char* result = estrdup(ret);
|
|
|
+ RETURN_STRINGL(result,strlen(result),0);
|
|
|
+}
|
|
|
+
|
|
|
+static int content_length()
|
|
|
+{
|
|
|
+ const char* pbuf = FCGX_GetParam("CONTENT_LENGTH", stParams);
|
|
|
+ if(pbuf)
|
|
|
+ {
|
|
|
+ if(strlen(pbuf) == 0)
|
|
|
+ return 0;
|
|
|
+ else
|
|
|
+ return atoi(pbuf);
|
|
|
+ } else {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+////////////////////////////////////////////////////////////////////////////////////
|
|
|
+// rfc1867 callback
|
|
|
+static char* g_pcontent = NULL;
|
|
|
+int read_header_name(multipart_parser* p, const char *at, size_t length)
|
|
|
+{
|
|
|
+ // printf("%.*s: ", length, at);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+// rfc1867 callback
|
|
|
+int read_header_value(multipart_parser* p, const char *at, size_t length)
|
|
|
+{
|
|
|
+ // printf("%.*s\n", length, at);
|
|
|
+
|
|
|
+ if (NULL == g_pcontent) return 0;
|
|
|
+
|
|
|
+ char* pbegin = strstr(at, "\"");
|
|
|
+ if (!pbegin) return 0;
|
|
|
+
|
|
|
+ ++pbegin;
|
|
|
+ const char* pend = strstr(pbegin, "\"");
|
|
|
+
|
|
|
+ if (!pend) return 0;
|
|
|
+ const int len = pend - pbegin;
|
|
|
+
|
|
|
+ strncat(g_pcontent, pbegin, len);
|
|
|
+ strcat(g_pcontent, "=");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+// rfc1867 callback
|
|
|
+int read_part_data(multipart_parser* p, const char *at, size_t length)
|
|
|
+{
|
|
|
+ // printf("%.*s\n", length, at);
|
|
|
+ if (NULL == g_pcontent) return 0;
|
|
|
+
|
|
|
+ strncat(g_pcontent, at, length);
|
|
|
+ strcat(g_pcontent, "&");
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_getcontent)
|
|
|
+{
|
|
|
+ int con_len = content_length();
|
|
|
+ if(con_len) {
|
|
|
+ char* pCon = (char*)malloc(con_len + 1);
|
|
|
+ con_len = FCGX_GetStr(pCon, con_len, stInstream);
|
|
|
+ pCon[con_len] = '\0';
|
|
|
+
|
|
|
+ // post webform boundary proccess
|
|
|
+ const char* pbuf = FCGX_GetParam("CONTENT_TYPE", stParams);
|
|
|
+ if(pbuf)
|
|
|
+ {
|
|
|
+ const char* boundary_begin = strstr(pbuf, "boundary");
|
|
|
+ if (boundary_begin)
|
|
|
+ {
|
|
|
+ boundary_begin = boundary_begin + strlen("boundary");
|
|
|
+ boundary_begin = strstr(boundary_begin, "=");
|
|
|
+ if (boundary_begin)
|
|
|
+ {
|
|
|
+ ++boundary_begin;
|
|
|
+ const int boundary_len = strlen(boundary_begin) + 3;
|
|
|
+ char* boundary_value = (char*)malloc(boundary_len);
|
|
|
+ if (boundary_value)
|
|
|
+ {
|
|
|
+ memset(boundary_value, 0, boundary_len);
|
|
|
+ strcat(boundary_value, "--");
|
|
|
+ strcat(boundary_value, boundary_begin);
|
|
|
+
|
|
|
+ g_pcontent = (char*)malloc(con_len + 1);
|
|
|
+ memset(g_pcontent, 0, con_len + 1);
|
|
|
+
|
|
|
+ multipart_parser_settings callbacks;
|
|
|
+ memset(&callbacks, 0, sizeof(multipart_parser_settings));
|
|
|
+
|
|
|
+ callbacks.on_header_field = read_header_name;
|
|
|
+ callbacks.on_header_value = read_header_value;
|
|
|
+ callbacks.on_part_data = read_part_data;
|
|
|
+
|
|
|
+ multipart_parser* parser = multipart_parser_init(boundary_value, &callbacks);
|
|
|
+ if (parser) {
|
|
|
+ multipart_parser_execute(parser, pCon, con_len);
|
|
|
+ multipart_parser_free(parser);
|
|
|
+ }
|
|
|
+
|
|
|
+ if(g_pcontent != NULL)
|
|
|
+ {
|
|
|
+ int len = strlen(g_pcontent);
|
|
|
+ if(len > 0 && g_pcontent[len - 1] == '&') {
|
|
|
+ g_pcontent[len - 1] = '\0';
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ char* result = estrdup(g_pcontent);
|
|
|
+ free(g_pcontent);
|
|
|
+ g_pcontent = NULL;
|
|
|
+ RETURN_STRINGL(result, strlen(result),0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // normal proccess
|
|
|
+ char* result = estrdup(pCon);
|
|
|
+ RETURN_STRINGL(result,strlen(result),0);
|
|
|
+ } else {
|
|
|
+ char* result = estrdup("");
|
|
|
+ RETURN_STRINGL(result,strlen(result),0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_echo)
|
|
|
+{
|
|
|
+ char *arg = NULL;
|
|
|
+ int arg_len;
|
|
|
+
|
|
|
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if(arg != NULL) {
|
|
|
+ FCGX_PutS(arg,stOutstream);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+PHP_FUNCTION(fcgi_finish)
|
|
|
+{
|
|
|
+ FCGX_Finish();
|
|
|
+}
|
|
|
+
|