⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thttpd.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   +----------------------------------------------------------------------+   | PHP Version 4                                                        |   +----------------------------------------------------------------------+   | Copyright (c) 1997-2007 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>                         |   +----------------------------------------------------------------------+*//* $Id: thttpd.c,v 1.77.2.15.4.2 2007/01/01 09:46:52 sebastian Exp $ */#include "php.h"#include "SAPI.h"#include "php_main.h"#include "php_thttpd.h"#include "php_variables.h"#include "version.h"#include "php_ini.h"#include "zend_highlight.h"#include "ext/standard/php_smart_str.h"#include <sys/time.h>#include <sys/types.h>#include <sys/uio.h>#include <stdlib.h>#include <unistd.h>#ifdef HAVE_GETNAMEINFO#include <sys/socket.h>#include <netdb.h>#endiftypedef struct {	httpd_conn *hc;	void (*on_close)(int);	size_t unconsumed_length;	smart_str sbuf;	int seen_cl;	int seen_cn;} php_thttpd_globals;#define PHP_SYS_CALL(x) do { x } while (n == -1 && errno == EINTR)#ifdef PREMIUM_THTTPD# define do_keep_alive persistent#endif#ifdef ZTSstatic int thttpd_globals_id;#define TG(v) TSRMG(thttpd_globals_id, php_thttpd_globals *, v)#elsestatic php_thttpd_globals thttpd_globals;#define TG(v) (thttpd_globals.v)#endifstatic int sapi_thttpd_ub_write(const char *str, uint str_length TSRMLS_DC){	int n;	uint sent = 0;		if (TG(sbuf).c != 0) {		smart_str_appendl_ex(&TG(sbuf), str, str_length, 1);		return str_length;	}		while (str_length > 0) {		PHP_SYS_CALL(n = send(TG(hc)->conn_fd, str, str_length, 0););		if (n == -1) {			if (errno == EAGAIN) {				smart_str_appendl_ex(&TG(sbuf), str, str_length, 1);				return sent + str_length;			} else				php_handle_aborted_connection();		}		TG(hc)->bytes_sent += n;		str += n;		sent += n;		str_length -= n;	}	return sent;}#define COMBINE_HEADERS 64#if defined(IOV_MAX)# if IOV_MAX - 64 <= 0#  define SERIALIZE_HEADERS# endif#endifstatic int do_writev(struct iovec *vec, int nvec, int len TSRMLS_DC){	int n;	assert(nvec <= IOV_MAX);	if (TG(sbuf).c == 0) {		PHP_SYS_CALL(n = writev(TG(hc)->conn_fd, vec, nvec););		if (n == -1) {			if (errno == EAGAIN) {				n = 0;			} else {				php_handle_aborted_connection();			}		}		TG(hc)->bytes_sent += n;	} else {		n = 0;	}	if (n < len) {		int i;		/* merge all unwritten data into sbuf */		for (i = 0; i < nvec; vec++, i++) {			/* has this vector been written completely? */			if (n >= vec->iov_len) {				/* yes, proceed */				n -= vec->iov_len;				continue;			}			if (n > 0) {				/* adjust vector */				vec->iov_base = (char *) vec->iov_base + n;				vec->iov_len -= n;				n = 0;			}			smart_str_appendl_ex(&TG(sbuf), vec->iov_base, vec->iov_len, 1);		}	}		return 0;}#ifdef SERIALIZE_HEADERS# define ADD_VEC(str,l) smart_str_appendl(&vec_str, (str), (l))# define VEC_BASE() smart_str vec_str = {0}# define VEC_FREE() smart_str_free(&vec_str)#else# define ADD_VEC(str,l) vec[n].iov_base=str;len += (vec[n].iov_len=l); n++# define VEC_BASE() struct iovec vec[COMBINE_HEADERS]# define VEC_FREE() do {} while (0)#endif#define ADD_VEC_S(str) ADD_VEC((str), sizeof(str)-1)#define CL_TOKEN "Content-length: "#define CN_TOKEN "Connection: "#define KA_DO "Connection: keep-alive\r\n"#define KA_NO "Connection: close\r\n"#define DEF_CT "Content-Type: text/html\r\n"static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){	char buf[1024], *p;	VEC_BASE();	int n = 0;	zend_llist_position pos;	sapi_header_struct *h;	size_t len = 0;		if (!SG(sapi_headers).http_status_line) {		ADD_VEC_S("HTTP/1.1 ");		p = smart_str_print_long(buf+sizeof(buf)-1, 				SG(sapi_headers).http_response_code);		ADD_VEC(p, strlen(p));		ADD_VEC_S(" HTTP\r\n");	} else {		ADD_VEC(SG(sapi_headers).http_status_line, 				strlen(SG(sapi_headers).http_status_line));		ADD_VEC("\r\n", 2);	}	TG(hc)->status = SG(sapi_headers).http_response_code;	if (SG(sapi_headers).send_default_content_type) {		ADD_VEC(DEF_CT, strlen(DEF_CT));	}	h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);	while (h) {				switch (h->header[0]) {			case 'c': case 'C':				if (!TG(seen_cl) && strncasecmp(h->header, CL_TOKEN, sizeof(CL_TOKEN)-1) == 0) {					TG(seen_cl) = 1;				} else if (!TG(seen_cn) && strncasecmp(h->header, CN_TOKEN, sizeof(CN_TOKEN)-1) == 0) {					TG(seen_cn) = 1;				}		}		ADD_VEC(h->header, h->header_len);#ifndef SERIALIZE_HEADERS		if (n >= COMBINE_HEADERS - 1) {			len = do_writev(vec, n, len TSRMLS_CC);			n = 0;		}#endif		ADD_VEC("\r\n", 2);				h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);	}	if (TG(seen_cl) && !TG(seen_cn) && TG(hc)->do_keep_alive) {		ADD_VEC(KA_DO, sizeof(KA_DO)-1);	} else {		TG(hc)->do_keep_alive = 0;		ADD_VEC(KA_NO, sizeof(KA_NO)-1);	}			ADD_VEC("\r\n", 2);#ifdef SERIALIZE_HEADERS	sapi_thttpd_ub_write(vec_str.c, vec_str.len TSRMLS_CC);#else				do_writev(vec, n, len TSRMLS_CC);#endif	VEC_FREE();	return SAPI_HEADER_SENT_SUCCESSFULLY;}/* to understand this, read cgi_interpose_input() in libhttpd.c */#define SIZEOF_UNCONSUMED_BYTES() (TG(hc)->read_idx - TG(hc)->checked_idx)#define CONSUME_BYTES(n) do { TG(hc)->checked_idx += (n); } while (0)static int sapi_thttpd_read_post(char *buffer, uint count_bytes TSRMLS_DC){	size_t read_bytes = 0;	if (TG(unconsumed_length) > 0) {		read_bytes = MIN(TG(unconsumed_length), count_bytes);		memcpy(buffer, TG(hc)->read_buf + TG(hc)->checked_idx, read_bytes);		TG(unconsumed_length) -= read_bytes;		CONSUME_BYTES(read_bytes);	}		return read_bytes;}static char *sapi_thttpd_read_cookies(TSRMLS_D){	return TG(hc)->cookie;}#define BUF_SIZE 512#define ADD_STRING_EX(name,buf)									\	php_register_variable(name, buf, track_vars_array TSRMLS_CC)#define ADD_STRING(name) ADD_STRING_EX((name), buf)static void sapi_thttpd_register_variables(zval *track_vars_array TSRMLS_DC){	char buf[BUF_SIZE + 1];	char *p;	php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC);	php_register_variable("SERVER_SOFTWARE", SERVER_SOFTWARE, 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("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);	if (TG(hc)->one_one) {		php_register_variable("SERVER_PROTOCOL", "HTTP/1.1", track_vars_array TSRMLS_CC);	} else {		php_register_variable("SERVER_PROTOCOL", "HTTP/1.0", track_vars_array TSRMLS_CC);	}	p = httpd_ntoa(&TG(hc)->client_addr);			ADD_STRING_EX("REMOTE_ADDR", p);	ADD_STRING_EX("REMOTE_HOST", p);	ADD_STRING_EX("SERVER_PORT",			smart_str_print_long(buf + sizeof(buf) - 1,				TG(hc)->hs->port));	buf[0] = '/';	memcpy(buf + 1, TG(hc)->pathinfo, strlen(TG(hc)->pathinfo) + 1);	ADD_STRING("PATH_INFO");	buf[0] = '/';	memcpy(buf + 1, TG(hc)->origfilename, strlen(TG(hc)->origfilename) + 1);	ADD_STRING("SCRIPT_NAME");#define CONDADD(name, field) 							\	if (TG(hc)->field[0]) {								\		php_register_variable(#name, TG(hc)->field, track_vars_array TSRMLS_CC); \	}	CONDADD(QUERY_STRING, query);	CONDADD(HTTP_HOST, hdrhost);	CONDADD(HTTP_REFERER, referer);	CONDADD(HTTP_USER_AGENT, useragent);	CONDADD(HTTP_ACCEPT, accept);	CONDADD(HTTP_ACCEPT_LANGUAGE, acceptl);	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) {		ADD_STRING_EX("CONTENT_LENGTH",				smart_str_print_long(buf + sizeof(buf) - 1, 					TG(hc)->contentlength));	}	if (TG(hc)->authorization[0])		php_register_variable("AUTH_TYPE", "Basic", track_vars_array TSRMLS_CC);}static PHP_MINIT_FUNCTION(thttpd){	return SUCCESS;}static zend_module_entry php_thttpd_module = {	STANDARD_MODULE_HEADER,	"thttpd",	NULL,	PHP_MINIT(thttpd),	NULL,	NULL,	NULL,	NULL, /* info */	NULL,	STANDARD_MODULE_PROPERTIES};static int php_thttpd_startup(sapi_module_struct *sapi_module){#if PHP_API_VERSION >= 20020918	if (php_module_startup(sapi_module, &php_thttpd_module, 1) == FAILURE) {#else	if (php_module_startup(sapi_module) == FAILURE			|| zend_startup_module(&php_thttpd_module) == FAILURE) {#endif		return FAILURE;	}	return SUCCESS;}static int sapi_thttpd_get_fd(int *nfd TSRMLS_DC){	if (nfd) *nfd = TG(hc)->conn_fd;	return SUCCESS;}static sapi_module_struct thttpd_sapi_module = {	"thttpd",	"thttpd",		php_thttpd_startup,	php_module_shutdown_wrapper,		NULL,									/* activate */	NULL,									/* deactivate */	sapi_thttpd_ub_write,	NULL,	NULL,									/* get uid */	NULL,									/* getenv */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -