summaryrefslogtreecommitdiff
path: root/sapi/tux
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2013-03-14 05:42:27 +0000
committer <>2013-04-03 16:25:08 +0000
commitc4dd7a1a684490673e25aaf4fabec5df138854c4 (patch)
tree4d57c44caae4480efff02b90b9be86f44bf25409 /sapi/tux
downloadphp2-master.tar.gz
Imported from /home/lorry/working-area/delta_php2/php-5.4.13.tar.bz2.HEADphp-5.4.13master
Diffstat (limited to 'sapi/tux')
-rw-r--r--sapi/tux/CREDITS2
-rw-r--r--sapi/tux/README86
-rw-r--r--sapi/tux/config.m416
-rw-r--r--sapi/tux/php.sym2
-rw-r--r--sapi/tux/php_tux.c457
5 files changed, 563 insertions, 0 deletions
diff --git a/sapi/tux/CREDITS b/sapi/tux/CREDITS
new file mode 100644
index 0000000..3b7aa70
--- /dev/null
+++ b/sapi/tux/CREDITS
@@ -0,0 +1,2 @@
+tux
+Sascha Schumann
diff --git a/sapi/tux/README b/sapi/tux/README
new file mode 100644
index 0000000..92c0211
--- /dev/null
+++ b/sapi/tux/README
@@ -0,0 +1,86 @@
+README FOR THE TUX MODULE (by Sascha Schumann)
+($Date$)
+
+ This is a SAPI module for the TUX web-server by Ingo Molnar.
+
+ The special thing about TUX is that it is integrated into the Linux
+ kernel and thus provides high-speed serving of static files.
+
+ The web-server provides a user-space API which allows arbitrary
+ plug-ins to be made available.
+
+ All requests to the PHP userspace module are currently serialized.
+
+ This module is of alpha quality. Due to incomplete APIs, HTTP
+ authentication and handling of POST requests has not been
+ implemented yet.
+
+ SECURITY NOTE: PHP will happily run everything under the
+ web-root through the parser; so be careful what you put
+ there.
+
+ Note that requests are served in a chroot'ed environment.
+ The initialization of PHP does not take place in the chroot'ed
+ environment, so that e.g. /usr/local/lib/php.ini is treated
+ as usual.
+
+REQUIRED DOWNLOADS
+
+ 1. TUX
+
+ http://people.redhat.com/~mingo/TUX-patches/QuickStart-TUX.txt
+
+ 2. PHP 4.0.x
+
+ Download:
+ http://www.php.net/
+
+ Snapshots from CVS:
+ http://snaps.php.net/
+
+
+BUILD INSTRUCTIONS
+
+ 1. Install TUX as outlined in the QuickStart text.
+ Create /tux-modules where modules will reside.
+
+ 2. Prepare PHP
+
+ $ cd php-*
+ $ ./configure \
+ --with-tux=/tux-modules \
+ <further PHP options>
+ # make install
+
+ You can see the list of valid PHP options by executing
+
+ $ ./configure --help
+
+ 3. Touch a file in your web-root 'php5.tux'. This will
+ cause requests to '/php5.tux' to be redirected to the
+ userspace module php5.tux.
+
+ 4. Start TUX with something like
+
+ # tux -d -t 8 -r /www -m /tux-modules php5.tux
+
+ (daemon mode, eight threads, web-root /www, modules in
+ /tux-modules, load php5.tux)
+
+ BEFORE running this command, the kernel side of TUX has to
+ be properly setup.
+
+ 5. Try to access
+
+ http://yourserver/php5.tux?=PHPB8B5F2A0-3C92-11d3-A3A9-4C7B08C10000
+
+ It should display the PHP credits page.
+
+ To access a script /foo/bar.php, use
+
+ http://yourserver/php5.tux?/foo/bar.php
+
+ Parameters can be appended:
+
+ http://yourserver/php5.tux?/foo/bar.php&var=value
+
diff --git a/sapi/tux/config.m4 b/sapi/tux/config.m4
new file mode 100644
index 0000000..06788be
--- /dev/null
+++ b/sapi/tux/config.m4
@@ -0,0 +1,16 @@
+dnl
+dnl $Id$
+dnl
+
+PHP_ARG_WITH(tux,,
+[ --with-tux=MODULEDIR Build PHP as a TUX module (Linux only)], no, no)
+
+AC_MSG_CHECKING([for TUX])
+if test "$PHP_TUX" != "no"; then
+ INSTALL_IT="\$(INSTALL) -m 0755 $SAPI_SHARED $PHP_TUX/php5.tux.so"
+ AC_CHECK_HEADERS(tuxmodule.h,[:],[AC_MSG_ERROR([Cannot find tuxmodule.h])])
+ PHP_SELECT_SAPI(tux, shared, php_tux.c)
+ AC_MSG_RESULT([$PHP_TUX])
+else
+ AC_MSG_RESULT(no)
+fi
diff --git a/sapi/tux/php.sym b/sapi/tux/php.sym
new file mode 100644
index 0000000..b968c5f
--- /dev/null
+++ b/sapi/tux/php.sym
@@ -0,0 +1,2 @@
+TUXAPI_handle_events
+TUXAPI_init
diff --git a/sapi/tux/php_tux.c b/sapi/tux/php_tux.c
new file mode 100644
index 0000000..968dd9e
--- /dev/null
+++ b/sapi/tux/php_tux.c
@@ -0,0 +1,457 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP Version 5 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997-2013 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: Sascha Schumann <sascha@schumann.cx> |
+ +----------------------------------------------------------------------+
+*/
+
+#include "php.h"
+#include "SAPI.h"
+#include "php_main.h"
+#include "php_variables.h"
+
+#include "ext/standard/php_smart_str.h"
+
+#include "tuxmodule.h"
+
+#include <sys/uio.h>
+
+#if 0
+#include <pthread.h>
+#endif
+
+void tux_closed_conn(int fd);
+
+enum {
+ PHP_TUX_BACKGROUND_CONN = 1
+};
+
+typedef struct {
+ user_req_t *req;
+ void (*on_close)(int);
+ int tux_action;
+ struct iovec *header_vec;
+ int number_vec;
+} php_tux_globals;
+
+static php_tux_globals tux_globals;
+
+#define TG(v) (tux_globals.v)
+
+static int sapi_tux_ub_write(const char *str, uint str_length TSRMLS_DC)
+{
+ int n;
+ int m;
+ const char *estr;
+
+ /* combine headers and body */
+ if (TG(number_vec)) {
+ struct iovec *vec = TG(header_vec);
+
+ n = TG(number_vec);
+ vec[n].iov_base = (void *) str;
+ vec[n++].iov_len = str_length;
+
+ /* XXX: this might need more complete error handling */
+ if ((m = writev(TG(req)->sock, vec, n)) == -1 && errno == EPIPE)
+ php_handle_aborted_connection();
+
+ if (m > 0)
+ TG(req)->bytes_sent += str_length;
+
+ TG(number_vec) = 0;
+ return str_length;
+ }
+
+ estr = str + str_length;
+
+ while (str < estr) {
+ n = send(TG(req)->sock, str, estr - str, 0);
+
+ if (n == -1 && errno == EPIPE)
+ php_handle_aborted_connection();
+ if (n == -1 && errno == EAGAIN)
+ continue;
+ if (n <= 0)
+ return n;
+
+ str += n;
+ }
+
+ n = str_length - (estr - str);
+
+ TG(req)->bytes_sent += n;
+
+ return n;
+}
+
+static int sapi_tux_send_headers(sapi_headers_struct *sapi_headers)
+{
+ char buf[1024];
+ struct iovec *vec;
+ int n;
+ int max_headers;
+ zend_llist_position pos;
+ sapi_header_struct *h;
+ size_t len;
+ char *status_line;
+ int locate_cl;
+ TSRMLS_FETCH();
+
+ max_headers = 30;
+ n = 1;
+
+ vec = malloc(sizeof(struct iovec) * max_headers);
+ status_line = malloc(30);
+
+ /* safe sprintf use */
+ len = slprintf(status_line, 30, "HTTP/1.1 %d NA\r\n", SG(sapi_headers).http_response_code);
+
+ vec[0].iov_base = status_line;
+ vec[0].iov_len = len;
+
+ TG(req)->http_status = SG(sapi_headers).http_response_code;
+
+ if (TG(tux_action) == TUX_ACTION_FINISH_CLOSE_REQ && TG(req)->http_version == HTTP_1_1)
+ locate_cl = 1;
+ else
+ locate_cl = 0;
+
+ h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
+ while (h) {
+ if (locate_cl
+ && strncasecmp(h->header, "Content-length:", sizeof("Content-length:")-1) == 0) {
+ TG(tux_action) = TUX_ACTION_FINISH_REQ;
+ locate_cl = 0;
+ }
+
+ vec[n].iov_base = h->header;
+ vec[n++].iov_len = h->header_len;
+ if (n >= max_headers - 3) {
+ max_headers *= 2;
+ vec = realloc(vec, sizeof(struct iovec) * max_headers);
+ }
+ vec[n].iov_base = "\r\n";
+ vec[n++].iov_len = 2;
+
+ h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
+ }
+
+ vec[n].iov_base = "\r\n";
+ vec[n++].iov_len = 2;
+
+ TG(number_vec) = n;
+ TG(header_vec) = vec;
+
+
+ return SAPI_HEADER_SENT_SUCCESSFULLY;
+}
+
+static int sapi_tux_read_post(char *buffer, uint count_bytes)
+{
+#if 0
+ int amount = 0;
+ TSRMLS_FETCH();
+
+ TG(req)->objectlen = count_bytes;
+ TG(req)->object_addr = buffer;
+ if (tux(TUX_ACTION_READ_POST_DATA, TG(req)))
+ return 0;
+
+ TG(read_post_data) = 1;
+
+ return TG(req)->objectlen;
+#else
+ return 0;
+#endif
+}
+
+static char *sapi_tux_read_cookies(void)
+{
+ TSRMLS_FETCH();
+
+ return TG(req)->cookies;
+}
+
+#define BUF_SIZE 512
+#define ADD_STRING(name) \
+ php_register_variable(name, buf, track_vars_array TSRMLS_CC)
+
+static void sapi_tux_register_variables(zval *track_vars_array TSRMLS_DC)
+{
+ char buf[BUF_SIZE + 1];
+ char *p;
+ sapi_header_line ctr = {0};
+
+ ctr.line = buf;
+ ctr.line_len = slprintf(buf, sizeof(buf), "Server: %s", TUXAPI_version);
+ sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC);
+
+ php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
+ php_register_variable("SERVER_SOFTWARE", TUXAPI_version, track_vars_array TSRMLS_CC);
+ php_register_variable("GATEWAY_INTERFACE", "CGI/1.1", track_vars_array TSRMLS_CC);
+ php_register_variable("REQUEST_METHOD", (char *) SG(request_info).request_method, track_vars_array TSRMLS_CC);
+ php_register_variable("DOCUMENT_ROOT", TUXAPI_docroot, track_vars_array TSRMLS_CC);
+ php_register_variable("SERVER_NAME", TUXAPI_servername, track_vars_array TSRMLS_CC);
+ php_register_variable("REQUEST_URI", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
+ php_register_variable("PATH_TRANSLATED", SG(request_info).path_translated, track_vars_array TSRMLS_CC);
+
+ p = inet_ntoa(TG(req)->client_host);
+ /* string representation of IPs are never larger than 512 bytes */
+ if (p) {
+ memcpy(buf, p, strlen(p) + 1);
+ ADD_STRING("REMOTE_ADDR");
+ ADD_STRING("REMOTE_HOST");
+ }
+
+ snprintf(buf, sizeof(buf), "%d", CGI_SERVER_PORT(TG(req)));
+ ADD_STRING("SERVER_PORT");
+
+#if 0
+ snprintf(buf, BUF_SIZE, "/%s", TG(hc)->pathinfo);
+ ADD_STRING("PATH_INFO");
+
+ snprintf(buf, BUF_SIZE, "/%s", TG(hc)->origfilename);
+ ADD_STRING("SCRIPT_NAME");
+#endif
+
+#define CONDADD(name, field) \
+ if (TG(req)->field[0]) { \
+ php_register_variable(#name, TG(req)->field, track_vars_array TSRMLS_CC); \
+ }
+
+ CONDADD(HTTP_REFERER, referer);
+ CONDADD(HTTP_USER_AGENT, user_agent);
+ CONDADD(HTTP_ACCEPT, accept);
+ CONDADD(HTTP_ACCEPT_ENCODING, accept_encoding);
+ CONDADD(HTTP_ACCEPT_LANGUAGE, accept_language);
+ CONDADD(HTTP_COOKIE, cookies);
+ CONDADD(CONTENT_TYPE, content_type);
+
+#if 0
+ if (TG(hc)->contentlength != -1) {
+ snprintf(buf, sizeof(buf), "%ld", (long) TG(hc)->contentlength);
+ ADD_STRING("CONTENT_LENGTH");
+ }
+#endif
+
+#if 0
+ if (TG(hc)->authorization[0])
+ php_register_variable("AUTH_TYPE", "Basic", track_vars_array TSRMLS_CC);
+#endif
+}
+
+
+static int php_tux_startup(sapi_module_struct *sapi_module)
+{
+ if (php_module_startup(sapi_module, NULL, 0)==FAILURE) {
+ return FAILURE;
+ } else {
+ return SUCCESS;
+ }
+}
+
+static sapi_module_struct tux_sapi_module = {
+ "tux",
+ "tux",
+
+ php_tux_startup,
+ php_module_shutdown_wrapper,
+
+ NULL, /* activate */
+ NULL, /* deactivate */
+
+ sapi_tux_ub_write,
+ NULL,
+ NULL, /* get uid */
+ NULL, /* getenv */
+
+ php_error,
+
+ NULL,
+ sapi_tux_send_headers,
+ NULL,
+ sapi_tux_read_post,
+ sapi_tux_read_cookies,
+
+ sapi_tux_register_variables,
+ NULL, /* Log message */
+ NULL, /* Get request time */
+ NULL, /* Child terminate */
+
+ STANDARD_SAPI_MODULE_PROPERTIES
+};
+
+static void tux_module_main(TSRMLS_D)
+{
+ zend_file_handle file_handle;
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = SG(request_info).path_translated;
+ file_handle.free_filename = 0;
+ file_handle.opened_path = NULL;
+
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ return;
+ }
+
+ php_execute_script(&file_handle TSRMLS_CC);
+ php_request_shutdown(NULL);
+}
+
+static void tux_request_ctor(TSRMLS_D)
+{
+ char buf[1024];
+ int offset;
+ size_t filename_len;
+ size_t cwd_len;
+ smart_str s = {0};
+ char *p;
+
+ TG(number_vec) = 0;
+ TG(header_vec) = NULL;
+ SG(request_info).query_string = strdup(TG(req)->query);
+
+ smart_str_appends_ex(&s, "/", 1);
+ smart_str_appends_ex(&s, TG(req)->query, 1);
+ smart_str_0(&s);
+ p = strchr(s.c, '&');
+ if (p)
+ *p = '\0';
+ SG(request_info).path_translated = s.c;
+
+ s.c = NULL;
+ smart_str_appendc_ex(&s, '/', 1);
+ smart_str_appends_ex(&s, TG(req)->objectname, 1);
+ smart_str_0(&s);
+ SG(request_info).request_uri = s.c;
+ SG(request_info).request_method = CGI_REQUEST_METHOD(TG(req));
+ if(TG(req)->http_version == HTTP_1_1) SG(request_info).proto_num = 1001;
+ else SG(request_info).proto_num = 1000;
+ SG(sapi_headers).http_response_code = 200;
+ SG(request_info).content_type = TG(req)->content_type;
+ SG(request_info).content_length = 0; /* TG(req)->contentlength; */
+
+#if 0
+ php_handle_auth_data(TG(hc)->authorization TSRMLS_CC);
+#endif
+}
+
+static void tux_request_dtor(TSRMLS_D)
+{
+ if (TG(header_vec)) {
+ /* free status_line */
+ free(TG(header_vec)[0].iov_base);
+ free(TG(header_vec));
+ }
+ if (SG(request_info).query_string)
+ free(SG(request_info).query_string);
+ free(SG(request_info).request_uri);
+ free(SG(request_info).path_translated);
+}
+
+#if 0
+static void *separate_thread(void *bla)
+{
+ int fd;
+ int i = 0;
+
+ fd = (int) bla;
+
+ while (i++ < 5) {
+ send(fd, "test<br />\n", 9, 0);
+ sleep(1);
+ }
+
+ tux(TUX_ACTION_CONTINUE_REQ, (user_req_t *) fd);
+ /* We HAVE to trigger some event on the fd. Otherwise
+ fast_thread won't wake up, so that the eventloop
+ won't be entered -> TUX hangs */
+ shutdown(fd, 2);
+ pthread_exit(NULL);
+}
+#endif
+
+int TUXAPI_handle_events(user_req_t *req)
+{
+ TSRMLS_FETCH();
+
+ if (req->event == PHP_TUX_BACKGROUND_CONN) {
+ tux_closed_conn(req->sock);
+ return tux(TUX_ACTION_FINISH_CLOSE_REQ, req);
+ }
+
+ TG(req) = req;
+ TG(tux_action) = TUX_ACTION_FINISH_CLOSE_REQ;
+
+ tux_request_ctor(TSRMLS_C);
+
+ tux_module_main(TSRMLS_C);
+
+ tux_request_dtor(TSRMLS_C);
+
+ return tux(TG(tux_action), req);
+}
+
+void tux_register_on_close(void (*arg)(int))
+{
+ TG(on_close) = arg;
+}
+
+void tux_closed_conn(int fd)
+{
+ TSRMLS_FETCH();
+
+ if (TG(on_close)) TG(on_close)(fd);
+}
+
+int tux_get_fd(void)
+{
+ TSRMLS_FETCH();
+
+ return TG(req)->sock;
+}
+
+void tux_set_dont_close(void)
+{
+ TSRMLS_FETCH();
+
+ TG(req)->event = PHP_TUX_BACKGROUND_CONN;
+ tux(TUX_ACTION_POSTPONE_REQ, TG(req));
+ TG(tux_action) = TUX_ACTION_EVENTLOOP;
+}
+
+void TUXAPI_init(void)
+{
+ sapi_startup(&tux_sapi_module);
+ tux_sapi_module.startup(&tux_sapi_module);
+ SG(server_context) = (void *) 1;
+}
+
+void doesnotmatter_fini(void)
+{
+ if (SG(server_context) != NULL) {
+ tux_sapi_module.shutdown(&tux_sapi_module);
+ sapi_shutdown();
+ }
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: sw=4 ts=4 fdm=marker
+ * vim<600: sw=4 ts=4
+ */