summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sapi/thttpd/Makefile.am2
-rw-r--r--sapi/thttpd/README53
-rw-r--r--sapi/thttpd/config.m416
-rw-r--r--sapi/thttpd/php.sym3
-rw-r--r--sapi/thttpd/php_thttpd.h30
-rw-r--r--sapi/thttpd/thttpd.c285
-rw-r--r--sapi/thttpd/thttpd_patch85
7 files changed, 474 insertions, 0 deletions
diff --git a/sapi/thttpd/Makefile.am b/sapi/thttpd/Makefile.am
new file mode 100644
index 0000000000..3affcbf4ff
--- /dev/null
+++ b/sapi/thttpd/Makefile.am
@@ -0,0 +1,2 @@
+noinst_LTLIBRARIES = libphpsapi_thttpd.la
+libphpsapi_thttpd_la_SOURCES = thttpd.c
diff --git a/sapi/thttpd/README b/sapi/thttpd/README
new file mode 100644
index 0000000000..7dc32d8a64
--- /dev/null
+++ b/sapi/thttpd/README
@@ -0,0 +1,53 @@
+README FOR THTTPD MODULE (by Sascha Schumann) ($Date$)
+
+ This is a SAPI module for PHP 4.0 supporting thttpd, the tiny,
+ turbo, throttling HTTP server by Jef Poskanzer.
+
+ The module contains a patch against version 2.10 of thttpd. The patch
+ adds hooks to thttpd to call PHP, if a filename matches *.php. This
+ patch will be applied when you install PHP.
+
+ While functional, this module exists primarily to demonstrate the ability
+ of PHP to work in almost every web server environment.
+
+REQUIRED DOWNLOADS
+
+ 1. thttpd 2.xx
+
+ Full Distribution:
+ http://www.acme.com/software/thttpd/
+
+ 2. PHP 4.0.x
+
+ Beta Versions:
+ http://www.php.net/version4/
+
+ Snapshots:
+ http://va.php.net/~sas/snapshots/
+
+
+BUILD INSTRUCTIONS
+
+ 1. Extract software packages
+
+ $ gunzip -c thttpd-2.xx.tar.gz | tar xf -
+ $ gunzip -c php-*.tar.gz | tar xf -
+
+ 2. Prepare PHP
+
+ $ cd php-*
+ $ ./configure \
+ --with-thttpd=../thttpd-2.xx \
+ <further PHP options>
+ $ make install
+ $ cd ..
+
+ You can see the list of valid PHP options by executing
+
+ $ ./configure --help
+
+ 3. Configure, compile, install thttpd
+
+ Now follow the thttpd instructions. The Makefile template of
+ thttpd was changed to automatically use the components
+ required by PHP.
diff --git a/sapi/thttpd/config.m4 b/sapi/thttpd/config.m4
new file mode 100644
index 0000000000..79ae3dbde1
--- /dev/null
+++ b/sapi/thttpd/config.m4
@@ -0,0 +1,16 @@
+AC_ARG_WITH(thttpd,
+[ --with-thttpd=SRCDIR],[
+ test -d $withval || AC_MSG_RESULT(thttpd directory does not exist ($withval))
+ AC_EXPAND_PATH($withval, THTTPD)
+ INSTALL_IT="\
+ echo 'PHP_LIBS = -L. -lphp4 \$(PHP_LIBS) \$(EXTRA_LIBS)' > $THTTPD/php_makefile; \
+ echo 'PHP_LDFLAGS = \$(NATIVE_RPATHS) \$(PHP_LDFLAGS)' >> $THTTPD/php_makefile; \
+ cp $abs_srcdir/sapi/thttpd/php_thttpd.h $SAPI_STATIC $THTTPD;\
+ test -f $THTTPD/php_patched || \
+ (cd $THTTPD && patch < $abs_srcdir/sapi/thttpd/thttpd_patch && touch php_patched)"
+ AC_MSG_CHECKING(for thttpd)
+ AC_MSG_RESULT(yes - $THTTPD)
+ AC_ADD_INCLUDE($THTTPD)
+ PHP_BUILD_STATIC
+ PHP_SAPI=thttpd
+])
diff --git a/sapi/thttpd/php.sym b/sapi/thttpd/php.sym
new file mode 100644
index 0000000000..2214d3964d
--- /dev/null
+++ b/sapi/thttpd/php.sym
@@ -0,0 +1,3 @@
+thttpd_php_request
+thttpd_php_init
+thttpd_php_shutdown
diff --git a/sapi/thttpd/php_thttpd.h b/sapi/thttpd/php_thttpd.h
new file mode 100644
index 0000000000..1bd81f969f
--- /dev/null
+++ b/sapi/thttpd/php_thttpd.h
@@ -0,0 +1,30 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_0.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> |
+ +----------------------------------------------------------------------+
+*/
+
+#ifndef PHP_THTTPD_H
+#define PHP_THTTPD_H
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <libhttpd.h>
+
+void thttpd_php_shutdown(void);
+void thttpd_php_init(void);
+off_t thttpd_php_request(httpd_conn *hc);
+
+#endif
diff --git a/sapi/thttpd/thttpd.c b/sapi/thttpd/thttpd.c
new file mode 100644
index 0000000000..c3ac2c5e7f
--- /dev/null
+++ b/sapi/thttpd/thttpd.c
@@ -0,0 +1,285 @@
+/*
+ +----------------------------------------------------------------------+
+ | PHP version 4.0 |
+ +----------------------------------------------------------------------+
+ | Copyright (c) 1997, 1998, 1999 The PHP Group |
+ +----------------------------------------------------------------------+
+ | This source file is subject to version 2.0 of the PHP license, |
+ | that is bundled with this package in the file LICENSE, and is |
+ | available at through the world-wide-web at |
+ | http://www.php.net/license/2_0.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 "main.h"
+#include "php_thttpd.h"
+#include "version.h"
+
+typedef struct {
+ httpd_conn *hc;
+ int post_off;
+} php_thttpd_globals;
+
+static php_thttpd_globals thttpd_globals;
+
+#define TLS_D
+#define TLS_DC
+#define TLS_C
+#define TLS_CC
+#define TG(v) (thttpd_globals.v)
+#define TLS_FETCH()
+
+static int sapi_thttpd_ub_write(const char *str, uint str_length)
+{
+ TLS_FETCH();
+
+ return send(TG(hc)->conn_fd, str, str_length, 0);
+}
+
+static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers SLS_DC)
+{
+ char buf[1024];
+
+ if (!SG(sapi_headers).http_status_line) {
+ snprintf(buf, 1023, "HTTP/1.0 %d Something\r\n", SG(sapi_headers).http_response_code);
+ send(TG(hc)->conn_fd, buf, strlen(buf), 0);
+ }
+
+ return SAPI_HEADER_DO_SEND;
+}
+
+static void sapi_thttpd_send_header(sapi_header_struct *sapi_header, void *server_context)
+{
+ TLS_FETCH();
+
+ if (sapi_header)
+ send(TG(hc)->conn_fd, sapi_header->header, sapi_header->header_len, 0);
+ send(TG(hc)->conn_fd, "\r\n", sizeof("\r\n") - 1, 0);
+}
+
+static int sapi_thttpd_read_post(char *buffer, uint count_bytes SLS_DC)
+{
+ size_t read_bytes = 0, tmp;
+ int c;
+ TLS_FETCH();
+
+ /* to understand this, read cgi_interpose_input() in libhttpd.c */
+ c = TG(hc)->read_idx - TG(hc)->checked_idx;
+ if (c > 0) {
+ read_bytes = MIN(c, count_bytes);
+ memcpy(buffer, TG(hc)->read_buf + TG(hc)->checked_idx, read_bytes);
+ TG(hc)->checked_idx += read_bytes;
+ count_bytes -= read_bytes;
+ }
+
+ count_bytes = MIN(count_bytes,
+ SG(request_info).content_length - SG(read_post_bytes) - TG(post_off));
+
+ while (read_bytes < count_bytes) {
+ tmp = recv(TG(hc)->conn_fd, buffer + read_bytes,
+ count_bytes - read_bytes, 0);
+ if (tmp <= 0)
+ break;
+ read_bytes += tmp;
+ }
+
+ return read_bytes;
+}
+
+static char *sapi_thttpd_read_cookies(SLS_D)
+{
+ TLS_FETCH();
+
+ return TG(hc)->cookie;
+}
+
+static sapi_module_struct sapi_module = {
+ "PHP Language",
+
+ php_module_startup,
+ php_module_shutdown_wrapper,
+
+ sapi_thttpd_ub_write,
+ php_error,
+
+ NULL,
+ sapi_thttpd_send_headers,
+ sapi_thttpd_send_header,
+ sapi_thttpd_read_post,
+ sapi_thttpd_read_cookies,
+
+ STANDARD_SAPI_MODULE_PROPERTIES
+};
+
+#define BUF_SIZE 512
+#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 void thttpd_hash_environment(void)
+{
+ char buf[BUF_SIZE + 1];
+ zval *pval;
+
+ buf[BUF_SIZE] = '\0';
+
+ strncpy(buf, SERVER_SOFTWARE, BUF_SIZE);
+ ADD_STRING("SERVER_SOFTWARE");
+
+ strncpy(buf, "CGI/1.1", BUF_SIZE);
+ ADD_STRING("GATEWAY_INTERFACE");
+
+ snprintf(buf, BUF_SIZE, "%d", TG(hc)->hs->port);
+ ADD_STRING("SERVER_PORT");
+
+ strncpy(buf, SG(request_info).request_method, BUF_SIZE);
+ ADD_STRING("REQUEST_METHOD");
+
+ strncpy(buf, SG(request_info).request_uri, BUF_SIZE);
+ ADD_STRING("REQUEST_URI");
+
+ snprintf(buf, BUF_SIZE, "/%s", TG(hc)->pathinfo);
+ ADD_STRING("PATH_INFO");
+
+ strncpy(buf, SG(request_info).path_translated, BUF_SIZE);
+ ADD_STRING("PATH_TRANSLATED");
+
+ snprintf(buf, BUF_SIZE, "/%s", TG(hc)->origfilename);
+ ADD_STRING("SCRIPT_NAME");
+
+ strncpy(buf, inet_ntoa(TG(hc)->client_addr), BUF_SIZE);
+ ADD_STRING("REMOTE_ADDR");
+ ADD_STRING("REMOTE_HOST");
+
+#define CONDADD(name, field) \
+ if (TG(hc)->field[0]) { \
+ strncpy(buf, TG(hc)->field, BUF_SIZE); \
+ ADD_STRING(#name); \
+ }
+
+ CONDADD(HTTP_REFERER, referer);
+ CONDADD(HTTP_USER_AGENT, useragent);
+ CONDADD(HTTP_ACCEPT, accept);
+ CONDADD(HTTP_ACCEPT_ENCODING, accepte);
+ CONDADD(HTTP_COOKIE, cookie);
+ CONDADD(CONTENT_TYPE, contenttype);
+ CONDADD(REMOTE_USER, remoteuser);
+ CONDADD(SERVER_PROTOCOL, protocol);
+
+ if (TG(hc)->contentlength != -1) {
+ sprintf(buf, "%ld", (long) TG(hc)->contentlength);
+ ADD_STRING("CONTENT_LENGTH");
+ }
+
+ if (TG(hc)->authorization[0]) {
+ strcpy(buf, "Basic");
+ ADD_STRING("AUTH_TYPE");
+ }
+}
+
+static void thttpd_module_main(TLS_D SLS_DC)
+{
+ zend_file_handle file_handle;
+ CLS_FETCH();
+ ELS_FETCH();
+ PLS_FETCH();
+
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = TG(hc)->expnfilename;
+ file_handle.free_filename = 0;
+
+ if (php_request_startup(CLS_C ELS_CC PLS_CC SLS_CC) == FAILURE) {
+ return;
+ }
+
+ thttpd_hash_environment();
+ php_execute_script(&file_handle CLS_CC ELS_CC PLS_CC);
+ php_request_shutdown(NULL);
+}
+
+static void thttpd_request_ctor(TLS_D SLS_DC)
+{
+ char *cp2;
+ int l;
+ char buf[1024];
+ int offset;
+ size_t pathinfo_len;
+ size_t cwd_len;
+
+ pathinfo_len = strlen(TG(hc)->pathinfo);
+ cwd_len = strlen(TG(hc)->hs->cwd);
+
+ SG(request_info).query_string = TG(hc)->query;
+
+ l = cwd_len + pathinfo_len + 1;
+ cp2 = (char *) malloc(l);
+ sprintf(cp2, "%s%s", TG(hc)->hs->cwd, TG(hc)->pathinfo);
+ SG(request_info).path_translated = cp2;
+
+ snprintf(buf, 1023, "/%s", TG(hc)->origfilename);
+ SG(request_info).request_uri = strdup(buf);
+ SG(request_info).request_method = httpd_method_str(TG(hc)->method);
+
+ SG(request_info).content_type = TG(hc)->contenttype;
+ SG(request_info).content_length = TG(hc)->contentlength;
+
+ SG(request_info).auth_user = NULL;
+ SG(request_info).auth_password = NULL;
+
+ TG(post_off) = TG(hc)->read_idx - TG(hc)->checked_idx;
+
+ /* avoid feeding \r\n from POST data to SAPI */
+ offset = TG(post_off) - SG(request_info).content_length;
+
+ if (offset > 0) {
+ TG(post_off) -= offset;
+ TG(hc)->read_idx -= offset;
+ }
+}
+
+static void thttpd_request_dtor(TLS_D SLS_DC)
+{
+ free(SG(request_info).request_uri);
+ free(SG(request_info).path_translated);
+}
+
+off_t thttpd_php_request(httpd_conn *hc)
+{
+ SLS_FETCH();
+ TLS_FETCH();
+
+ TG(hc) = hc;
+
+ thttpd_request_ctor(TLS_C SLS_CC);
+
+ thttpd_module_main(TLS_C SLS_CC);
+
+ thttpd_request_dtor(TLS_C SLS_CC);
+
+ return 0;
+}
+
+void thttpd_php_init(void)
+{
+ sapi_startup(&sapi_module);
+ sapi_module.startup(&sapi_module);
+ SG(server_context) = (void *) 1;
+}
+
+void thttpd_php_shutdown(void)
+{
+ sapi_module.shutdown(&sapi_module);
+ sapi_shutdown();
+}
diff --git a/sapi/thttpd/thttpd_patch b/sapi/thttpd/thttpd_patch
new file mode 100644
index 0000000000..fc9fb7d47c
--- /dev/null
+++ b/sapi/thttpd/thttpd_patch
@@ -0,0 +1,85 @@
+diff -ur thttpd-2.10/Makefile.in thttpd-2.10-php/Makefile.in
+--- thttpd-2.10/Makefile.in Mon Oct 11 20:45:38 1999
++++ thttpd-2.10-php/Makefile.in Mon Dec 20 01:37:49 1999
+@@ -46,13 +46,15 @@
+
+ # You shouldn't need to edit anything below here.
+
++include php_makefile
++
+ CC = @CC@
+ CCOPT = @V_CCOPT@
+ DEFS = @DEFS@
+ INCLS = -I.
+ CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
+-LDFLAGS = @LDFLAGS@
+-LIBS = @LIBS@
++LDFLAGS = @LDFLAGS@ $(PHP_LDFLAGS)
++LIBS = @LIBS@ $(PHP_LIBS)
+ NETLIBS = @V_NETLIBS@
+ INSTALL = @INSTALL@
+
+diff -ur thttpd-2.10/libhttpd.c thttpd-2.10-php/libhttpd.c
+--- thttpd-2.10/libhttpd.c Wed Dec 15 23:22:50 1999
++++ thttpd-2.10-php/libhttpd.c Mon Dec 20 01:05:47 1999
+@@ -75,6 +75,8 @@
+ #include "match.h"
+ #include "tdate_parse.h"
+
++#include "php_thttpd.h"
++
+ #ifndef STDIN_FILENO
+ #define STDIN_FILENO 0
+ #endif
+@@ -211,7 +213,11 @@
+ free( (void*) hs->cwd );
+ if ( hs->cgi_pattern != (char*) 0 )
+ free( (void*) hs->cgi_pattern );
++ if ( hs->php_pattern != (char*) 0 )
++ free( (void *) hs->php_pattern );
+ free( (void*) hs );
++
++ thttpd_php_shutdown();
+ }
+
+
+@@ -244,6 +250,7 @@
+ else
+ hs->hostname = strdup( hostname );
+ hs->port = port;
++ hs->php_pattern = strdup("*.php");
+ if ( cgi_pattern == (char*) 0 )
+ hs->cgi_pattern = (char*) 0;
+ else
+@@ -272,6 +279,8 @@
+ hs->no_symlinks = no_symlinks;
+ hs->vhost = vhost;
+
++ thttpd_php_init();
++
+ /* Create socket. */
+ hs->listen_fd = socket( AF_INET, SOCK_STREAM, 0 );
+ if ( hs->listen_fd < 0 )
+@@ -3129,6 +3138,11 @@
+ ( hc->sb.st_mode & S_IXOTH ) &&
+ match( hc->hs->cgi_pattern, hc->expnfilename ) )
+ return cgi( hc );
++
++ if ( hc->hs->php_pattern != (char*) 0 &&
++ match( hc->hs->php_pattern, hc->expnfilename)) {
++ return thttpd_php_request( hc );
++ }
+
+ /* It's not CGI. If it's executable or there's pathinfo, someone's
+ ** trying to either serve or run a non-CGI file as CGI. Either case
+diff -ur thttpd-2.10/libhttpd.h thttpd-2.10-php/libhttpd.h
+--- thttpd-2.10/libhttpd.h Wed Dec 8 19:53:34 1999
++++ thttpd-2.10-php/libhttpd.h Mon Dec 20 01:06:09 1999
+@@ -57,6 +57,7 @@
+ struct in_addr host_addr;
+ int port;
+ char* cgi_pattern;
++ char* php_pattern;
+ char* cwd;
+ int listen_fd;
+ FILE* logfp;