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

📄 thttpd.c

📁 php-4.4.7学习linux时下载的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	php_error,		NULL,	sapi_thttpd_send_headers,	NULL,	sapi_thttpd_read_post,	sapi_thttpd_read_cookies,	sapi_thttpd_register_variables,	NULL,									/* Log message */	NULL,									/* php.ini path override */	NULL,									/* Block interruptions */	NULL,									/* Unblock interruptions */	NULL,	NULL,	NULL,	0,	sapi_thttpd_get_fd};static void thttpd_module_main(int show_source TSRMLS_DC){	zend_file_handle file_handle = {0};	if (php_request_startup(TSRMLS_C) == FAILURE) {		return;	}		if (show_source) {		zend_syntax_highlighter_ini syntax_highlighter_ini;		php_get_highlight_struct(&syntax_highlighter_ini);		highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC);	} else {		file_handle.type = ZEND_HANDLE_FILENAME;		file_handle.filename = SG(request_info).path_translated;		file_handle.free_filename = 0;		file_handle.opened_path = NULL;		php_execute_script(&file_handle TSRMLS_CC);	}		php_request_shutdown(NULL);}static void thttpd_request_ctor(TSRMLS_D){	smart_str s = {0};	TG(seen_cl) = 0;	TG(seen_cn) = 0;	TG(sbuf).c = 0;	SG(request_info).query_string = TG(hc)->query?strdup(TG(hc)->query):NULL;	smart_str_appends_ex(&s, TG(hc)->hs->cwd, 1);	smart_str_appends_ex(&s, TG(hc)->expnfilename, 1);	smart_str_0(&s);	SG(request_info).path_translated = s.c;		s.c = NULL;	smart_str_appendc_ex(&s, '/', 1);	smart_str_appends_ex(&s, TG(hc)->origfilename, 1);	smart_str_0(&s);	SG(request_info).request_uri = s.c;	SG(request_info).request_method = httpd_method_str(TG(hc)->method);	SG(sapi_headers).http_response_code = 200;	if (TG(hc)->contenttype)		SG(request_info).content_type = strdup(TG(hc)->contenttype);	SG(request_info).content_length = TG(hc)->contentlength == -1 ? 0		: TG(hc)->contentlength;	TG(unconsumed_length) = SG(request_info).content_length;		php_handle_auth_data(TG(hc)->authorization TSRMLS_CC);}static void thttpd_request_dtor(TSRMLS_D){	smart_str_free_ex(&TG(sbuf), 1);	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 (SG(request_info).content_type)		free(SG(request_info).content_type);}#ifdef ZTS#ifdef TSRM_ST#define thread_create_simple_detached(n) st_thread_create(n, NULL, 0, 0)#define thread_usleep(n) st_usleep(n)#define thread_exit() st_thread_exit(NULL)/* No preemption, simple operations are safe */#define thread_atomic_inc(n) (++n)#define thread_atomic_dec(n) (--n)#else#error No thread primitives available#endif/* We might want to replace this with a STAILQ */typedef struct qreq {	httpd_conn *hc;	struct qreq *next;} qreq_t;static MUTEX_T qr_lock;static qreq_t *queued_requests;static qreq_t *last_qr;static int nr_free_threads;static int nr_threads;static int max_threads = 50;#define HANDLE_STRINGS() { \	HANDLE_STR(encodedurl); \	HANDLE_STR(decodedurl); \	HANDLE_STR(origfilename); \	HANDLE_STR(expnfilename); \	HANDLE_STR(pathinfo); \	HANDLE_STR(query); \	HANDLE_STR(referer); \	HANDLE_STR(useragent); \	HANDLE_STR(accept); \	HANDLE_STR(accepte); \	HANDLE_STR(acceptl); \	HANDLE_STR(cookie); \	HANDLE_STR(contenttype); \	HANDLE_STR(authorization); \	HANDLE_STR(remoteuser); \	}static httpd_conn *duplicate_conn(httpd_conn *hc, httpd_conn *nhc){	memcpy(nhc, hc, sizeof(*nhc));#define HANDLE_STR(m) nhc->m = nhc->m ? strdup(nhc->m) : NULL	HANDLE_STRINGS();#undef HANDLE_STR		return nhc;}static void destroy_conn(httpd_conn *hc){#define HANDLE_STR(m) if (hc->m) free(hc->m)	HANDLE_STRINGS();#undef HANDLE_STR}static httpd_conn *dequeue_request(void){	httpd_conn *ret = NULL;	qreq_t *m;		tsrm_mutex_lock(qr_lock);	if (queued_requests) {		m = queued_requests;		ret = m->hc;		if (!(queued_requests = m->next))			last_qr = NULL;		free(m);	}	tsrm_mutex_unlock(qr_lock);		return ret;}static void *worker_thread(void *);static void queue_request(httpd_conn *hc){	qreq_t *m;	httpd_conn *nhc;		/* Mark as long-running request */	hc->file_address = (char *) 1;	/*     * We cannot synchronously revoke accesses to hc in the worker	 * thread, so we need to pass a copy of hc to the worker thread.	 */	nhc = malloc(sizeof *nhc);	duplicate_conn(hc, nhc);		/* Allocate request queue container */	m = malloc(sizeof *m);	m->hc = nhc;	m->next = NULL;		tsrm_mutex_lock(qr_lock);	/* Create new threads when reaching a certain threshhold */	if (nr_threads < max_threads && nr_free_threads < 2) {		nr_threads++; /* protected by qr_lock */				thread_atomic_inc(nr_free_threads);		thread_create_simple_detached(worker_thread);	}	/* Insert container into request queue */	if (queued_requests)		last_qr->next = m;	else		queued_requests = m;	last_qr = m;	tsrm_mutex_unlock(qr_lock);}static off_t thttpd_real_php_request(httpd_conn *hc, int TSRMLS_DC);static void *worker_thread(void *dummy){	int do_work = 50;	httpd_conn *hc;	while (do_work) {		hc = dequeue_request();		if (!hc) {/*			do_work--; */			thread_usleep(500000);			continue;		}/*		do_work = 50; */		thread_atomic_dec(nr_free_threads);		thttpd_real_php_request(hc, 0 TSRMLS_CC);		shutdown(hc->conn_fd, 0);		destroy_conn(hc);		free(hc);		thread_atomic_inc(nr_free_threads);	}	thread_atomic_dec(nr_free_threads);	thread_atomic_dec(nr_threads);	thread_exit();}static void remove_dead_conn(int fd){	qreq_t *m, *prev = NULL;	tsrm_mutex_lock(qr_lock);	m = queued_requests;	while (m) {		if (m->hc->conn_fd == fd) {			if (prev)				if (!(prev->next = m->next))					last_qr = prev;			else				if (!(queued_requests = m->next))					last_qr = NULL;			destroy_conn(m->hc);			free(m->hc);			free(m);			break;		}		prev = m;		m = m->next;	}	tsrm_mutex_unlock(qr_lock);}#endifstatic off_t thttpd_real_php_request(httpd_conn *hc, int show_source TSRMLS_DC){	TG(hc) = hc;	hc->bytes_sent = 0;	if (hc->contentlength != -1) {		hc->should_linger = 1;		hc->do_keep_alive = 0;	}		if (hc->contentlength != -1			&& SIZEOF_UNCONSUMED_BYTES() < hc->contentlength) {		hc->read_body_into_mem = 1;		return 0;	}		thttpd_request_ctor(TSRMLS_C);	thttpd_module_main(show_source TSRMLS_CC);	/* disable kl, if no content-length was seen or Connection: was set */	if (TG(seen_cl) == 0 || TG(seen_cn) == 1) {		TG(hc)->do_keep_alive = 0;	}		if (TG(sbuf).c != 0) {		if (TG(hc)->response)			free(TG(hc)->response);				TG(hc)->response = TG(sbuf).c;		TG(hc)->responselen = TG(sbuf).len;		TG(hc)->maxresponse = TG(sbuf).a;		TG(sbuf).c = 0;		TG(sbuf).len = 0;		TG(sbuf).a = 0;	}	thttpd_request_dtor(TSRMLS_C);	return 0;}off_t thttpd_php_request(httpd_conn *hc, int show_source){#ifdef ZTS	queue_request(hc);#else	TSRMLS_FETCH();	return thttpd_real_php_request(hc, show_source TSRMLS_CC);#endif}void thttpd_register_on_close(void (*arg)(int)) {	TSRMLS_FETCH();	TG(on_close) = arg;}void thttpd_closed_conn(int fd){	TSRMLS_FETCH();	if (TG(on_close)) TG(on_close)(fd);}int thttpd_get_fd(void){	TSRMLS_FETCH();	return TG(hc)->conn_fd;}void thttpd_set_dont_close(void){	TSRMLS_FETCH();#ifndef PREMIUM_THTTPD	TG(hc)->file_address = (char *) 1;#endif}void thttpd_php_init(void){	char *ini;#ifdef ZTS	tsrm_startup(1, 1, 0, NULL);	ts_allocate_id(&thttpd_globals_id, sizeof(php_thttpd_globals), NULL, NULL);	qr_lock = tsrm_mutex_alloc();	thttpd_register_on_close(remove_dead_conn);#endif	if ((ini = getenv("PHP_INI_PATH"))) {		thttpd_sapi_module.php_ini_path_override = ini;	}	sapi_startup(&thttpd_sapi_module);	thttpd_sapi_module.startup(&thttpd_sapi_module);		{		TSRMLS_FETCH();		SG(server_context) = (void *) 1;	}}void thttpd_php_shutdown(void){	TSRMLS_FETCH();	if (SG(server_context) != NULL) {		thttpd_sapi_module.shutdown(&thttpd_sapi_module);		sapi_shutdown();#ifdef ZTS		tsrm_shutdown();#endif	}}

⌨️ 快捷键说明

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