xref: /PHP-5.3/sapi/phttpd/phttpd.c (revision a2045ff3)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2013 The PHP Group                                |
6    +----------------------------------------------------------------------+
7    | This source file is subject to version 3.01 of the PHP license,      |
8    | that is bundled with this package in the file LICENSE, and is        |
9    | available through the world-wide-web at the following url:           |
10    | http://www.php.net/license/3_01.txt                                  |
11    | If you did not receive a copy of the PHP license and are unable to   |
12    | obtain it through the world-wide-web, please send a note to          |
13    | license@php.net so we can mail you a copy immediately.               |
14    +----------------------------------------------------------------------+
15    | Author: Thies C. Arntzen <thies@thieso.net>						  |
16    | Based on aolserver SAPI by Sascha Schumann <sascha@schumann.cx>      |
17    +----------------------------------------------------------------------+
18 */
19 
20 #include "php.h"
21 #include "SAPI.h"
22 #include "php_main.h"
23 
24 #ifdef HAVE_PHTTPD
25 
26 #include "ext/standard/info.h"
27 
28 #ifndef ZTS
29 #error PHTTPD module is only useable in thread-safe mode
30 #endif
31 
32 #include "php_phttpd.h"
33 
34 typedef struct {
35     struct connectioninfo *cip;
36 	struct stat sb;
37 } phttpd_globals_struct;
38 
39 static int ph_globals_id;
40 
41 #define PHG(v) TSRMG(ph_globals_id, phttpd_globals_struct *, v)
42 
43 static int
php_phttpd_startup(sapi_module_struct * sapi_module)44 php_phttpd_startup(sapi_module_struct *sapi_module)
45 {
46 	fprintf(stderr,"***php_phttpd_startup\n");
47 
48     if (php_module_startup(sapi_module, NULL, 0)) {
49         return FAILURE;
50     } else {
51         return SUCCESS;
52     }
53 }
54 
55 static int
php_phttpd_sapi_ub_write(const char * str,uint str_length TSRMLS_DC)56 php_phttpd_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
57 {
58     int sent_bytes;
59 
60 	sent_bytes = fd_write(PHG(cip)->fd, str, str_length);
61 
62 	if (sent_bytes == -1) {
63 		php_handle_aborted_connection();
64 	}
65 
66     return sent_bytes;
67 }
68 
69 static int
php_phttpd_sapi_header_handler(sapi_header_struct * sapi_header,sapi_headers_struct * sapi_headers TSRMLS_DC)70 php_phttpd_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
71 {
72     char *header_name, *header_content;
73     char *p;
74     TSRMLS_FETCH();
75 
76 	http_sendheaders(PHG(cip)->fd, PHG(cip), SG(sapi_headers).http_response_code, NULL);
77 
78     header_name = sapi_header->header;
79     header_content = p = strchr(header_name, ':');
80 
81     if (p) {
82         *p = '\0';
83         do {
84             header_content++;
85         } while (*header_content == ' ');
86 
87 		fd_printf(PHG(cip)->fd,"%s: %s\n", header_name, header_content);
88 
89         *p = ':';
90     }
91 
92     sapi_free_header(sapi_header);
93 
94     return 0;
95 }
96 
97 static int
php_phttpd_sapi_send_headers(sapi_headers_struct * sapi_headers TSRMLS_DC)98 php_phttpd_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
99 {
100     TSRMLS_FETCH();
101 
102     if (SG(sapi_headers).send_default_content_type) {
103 		fd_printf(PHG(cip)->fd,"Content-Type: text/html\n");
104     }
105 
106 	fd_putc('\n', PHG(cip)->fd);
107 
108     return SAPI_HEADER_SENT_SUCCESSFULLY;
109 }
110 
111 static char *
php_phttpd_sapi_read_cookies(TSRMLS_D)112 php_phttpd_sapi_read_cookies(TSRMLS_D)
113 {
114 
115 /*
116     int i;
117     char *http_cookie = NULL;
118     NTSRMLS_FETCH();
119 
120     i = Ns_SetIFind(NSG(conn->headers), "cookie");
121     if(i != -1) {
122         http_cookie = Ns_SetValue(NSG(conn->headers), i);
123     }
124 
125     return http_cookie;
126 */
127 	fprintf(stderr,"***php_phttpd_sapi_read_cookies\n");
128 
129 	return 0;
130 }
131 
132 static int
php_phttpd_sapi_read_post(char * buf,uint count_bytes TSRMLS_DC)133 php_phttpd_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
134 {
135 /*
136     uint max_read;
137     uint total_read = 0;
138     NTSRMLS_FETCH();
139 
140     max_read = MIN(NSG(data_avail), count_bytes);
141 
142     total_read = Ns_ConnRead(NSG(conn), buf, max_read);
143 
144     if(total_read == NS_ERROR) {
145         total_read = -1;
146     } else {
147         NSG(data_avail) -= total_read;
148     }
149 
150     return total_read;
151 */
152 	fprintf(stderr,"***php_phttpd_sapi_read_post\n");
153 	return 0;
154 }
155 
156 static sapi_module_struct phttpd_sapi_module = {
157     "phttpd",
158     "PHTTPD",
159 
160     php_phttpd_startup,                     /* startup */
161     php_module_shutdown_wrapper,            /* shutdown */
162 
163 	NULL,									/* activate */
164 	NULL,									/* deactivate */
165 
166     php_phttpd_sapi_ub_write,               /* unbuffered write */
167 	NULL,									/* flush */
168 	NULL,									/* get uid */
169  	NULL,									/* getenv */
170 
171     php_error,                              /* error handler */
172 
173     php_phttpd_sapi_header_handler,         /* header handler */
174     php_phttpd_sapi_send_headers,           /* send headers handler */
175     NULL,                                   /* send header handler */
176 
177     php_phttpd_sapi_read_post,              /* read POST data */
178     php_phttpd_sapi_read_cookies,           /* read Cookies */
179 
180 	NULL,									/* register server variables */
181 	NULL,									/* Log message */
182 	NULL,									/* Get request time */
183 	NULL,									/* Child terminate */
184 
185     STANDARD_SAPI_MODULE_PROPERTIES
186 };
187 
188 static void
php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)189 php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)
190 {
191 	memset(&SG(request_info), 0, sizeof(sapi_globals_struct)); /* pfusch! */
192 
193     SG(request_info).query_string = PHG(cip)->hip->request;
194     SG(request_info).request_method = PHG(cip)->hip->method;
195 	SG(request_info).path_translated = malloc(MAXPATHLEN);
196     SG(sapi_headers).http_response_code = 200;
197 	if (url_expand(PHG(cip)->hip->url, SG(request_info).path_translated, MAXPATHLEN, &PHG(sb), NULL, NULL) == NULL) {
198 		/* handle error */
199 	}
200 
201 #if 0
202     char *server;
203     Ns_DString ds;
204     char *root;
205     int index;
206     char *tmp;
207 
208     server = Ns_ConnServer(NSG(conn));
209 
210     Ns_DStringInit(&ds);
211     Ns_UrlToFile(&ds, server, NSG(conn->request->url));
212 
213     /* path_translated is the absolute path to the file */
214     SG(request_info).path_translated = strdup(Ns_DStringValue(&ds));
215     Ns_DStringFree(&ds);
216     root = Ns_PageRoot(server);
217     SG(request_info).request_uri = SG(request_info).path_translated + strlen(root);
218     SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
219     index = Ns_SetIFind(NSG(conn)->headers, "content-type");
220     SG(request_info).content_type = index == -1 ? NULL :
221         Ns_SetValue(NSG(conn)->headers, index);
222 
223     tmp = Ns_ConnAuthUser(NSG(conn));
224     if(tmp) {
225         tmp = estrdup(tmp);
226     }
227     SG(request_info).auth_user = tmp;
228 
229     tmp = Ns_ConnAuthPasswd(NSG(conn));
230     if(tmp) {
231         tmp = estrdup(tmp);
232     }
233     SG(request_info).auth_password = tmp;
234 
235     NSG(data_avail) = SG(request_info).content_length;
236 #endif
237 }
238 
239 static void
php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)240 php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)
241 {
242     free(SG(request_info).path_translated);
243 }
244 
245 
php_doit(TSRMLS_D TSRMLS_DC)246 int php_doit(TSRMLS_D TSRMLS_DC)
247 {
248 	struct stat sb;
249 	zend_file_handle file_handle;
250 	struct httpinfo *hip = PHG(cip)->hip;
251 	TSRMLS_FETCH();
252 
253 	if (php_request_startup(TSRMLS_C) == FAILURE) {
254         return -1;
255     }
256 
257     file_handle.type = ZEND_HANDLE_FILENAME;
258     file_handle.filename = SG(request_info).path_translated;
259     file_handle.free_filename = 0;
260 
261 /*
262 	php_phttpd_hash_environment(TSRMLS_C);
263 */
264 	php_execute_script(&file_handle TSRMLS_CC);
265 	php_request_shutdown(NULL);
266 
267 	return SG(sapi_headers).http_response_code;
268 }
269 
pm_init(const char ** argv)270 int pm_init(const char **argv)
271 {
272 	tsrm_startup(1, 1, 0, NULL);
273 	sapi_startup(&phttpd_sapi_module);
274     phttpd_sapi_module.startup(&phttpd_sapi_module);
275 
276 	ts_allocate_id(&ph_globals_id, sizeof(phttpd_globals_struct), NULL, NULL);
277 
278 	return 0;
279 }
280 
pm_exit(void)281 void pm_exit(void)
282 {
283 	fprintf(stderr,"***pm_exit\n");
284 }
285 
pm_request(struct connectioninfo * cip)286 int pm_request(struct connectioninfo *cip)
287 {
288 	struct httpinfo *hip = cip->hip;
289 	int status;
290 	TSRMLS_FETCH();
291 
292 	if (strcasecmp(hip->method, "GET") == 0 ||
293 	    strcasecmp(hip->method, "HEAD") == 0 ||
294 	    strcasecmp(hip->method, "POST") == 0) {
295 		PHG(cip) = cip;
296 
297 		php_phttpd_request_ctor(TSRMLS_C);
298 		status = php_doit(TSRMLS_C);
299 		php_phttpd_request_dtor(TSRMLS_C);
300 
301 		return status;
302 	} else {
303 		return -2;
304 	}
305 }
306 
307 #endif
308