summaryrefslogtreecommitdiff
path: root/sapi/thttpd
diff options
context:
space:
mode:
authorSascha Schumann <sas@php.net>1999-12-20 07:11:14 +0000
committerSascha Schumann <sas@php.net>1999-12-20 07:11:14 +0000
commit56a5e84f9ddbf2d63e34c797746124c5385306d4 (patch)
tree69440866a3fe79033ed60c24a008ba5b9edb1234 /sapi/thttpd
parentf5d5637f729d9b6b221022a3a423d0d400560162 (diff)
downloadphp-git-56a5e84f9ddbf2d63e34c797746124c5385306d4.tar.gz
Add SAPI module for thttpd server. Quote from the README:
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.
Diffstat (limited to 'sapi/thttpd')
-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;