xref: /PHP-5.5/sapi/phttpd/phttpd.c (revision 73c1be26)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2015 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 
75 	http_sendheaders(PHG(cip)->fd, PHG(cip), SG(sapi_headers).http_response_code, NULL);
76 
77     header_name = sapi_header->header;
78     header_content = p = strchr(header_name, ':');
79 
80     if (p) {
81         *p = '\0';
82         do {
83             header_content++;
84         } while (*header_content == ' ');
85 
86 		fd_printf(PHG(cip)->fd,"%s: %s\n", header_name, header_content);
87 
88         *p = ':';
89     }
90 
91     sapi_free_header(sapi_header);
92 
93     return 0;
94 }
95 
96 static int
php_phttpd_sapi_send_headers(sapi_headers_struct * sapi_headers TSRMLS_DC)97 php_phttpd_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
98 {
99     if (SG(sapi_headers).send_default_content_type) {
100 		fd_printf(PHG(cip)->fd,"Content-Type: text/html\n");
101     }
102 
103 	fd_putc('\n', PHG(cip)->fd);
104 
105     return SAPI_HEADER_SENT_SUCCESSFULLY;
106 }
107 
108 static char *
php_phttpd_sapi_read_cookies(TSRMLS_D)109 php_phttpd_sapi_read_cookies(TSRMLS_D)
110 {
111 
112 /*
113     int i;
114     char *http_cookie = NULL;
115 
116     i = Ns_SetIFind(NSG(conn->headers), "cookie");
117     if(i != -1) {
118         http_cookie = Ns_SetValue(NSG(conn->headers), i);
119     }
120 
121     return http_cookie;
122 */
123 	fprintf(stderr,"***php_phttpd_sapi_read_cookies\n");
124 
125 	return 0;
126 }
127 
128 static int
php_phttpd_sapi_read_post(char * buf,uint count_bytes TSRMLS_DC)129 php_phttpd_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
130 {
131 /*
132     uint max_read;
133     uint total_read = 0;
134 
135     max_read = MIN(NSG(data_avail), count_bytes);
136 
137     total_read = Ns_ConnRead(NSG(conn), buf, max_read);
138 
139     if(total_read == NS_ERROR) {
140         total_read = -1;
141     } else {
142         NSG(data_avail) -= total_read;
143     }
144 
145     return total_read;
146 */
147 	fprintf(stderr,"***php_phttpd_sapi_read_post\n");
148 	return 0;
149 }
150 
151 static sapi_module_struct phttpd_sapi_module = {
152     "phttpd",
153     "PHTTPD",
154 
155     php_phttpd_startup,                     /* startup */
156     php_module_shutdown_wrapper,            /* shutdown */
157 
158 	NULL,									/* activate */
159 	NULL,									/* deactivate */
160 
161     php_phttpd_sapi_ub_write,               /* unbuffered write */
162 	NULL,									/* flush */
163 	NULL,									/* get uid */
164  	NULL,									/* getenv */
165 
166     php_error,                              /* error handler */
167 
168     php_phttpd_sapi_header_handler,         /* header handler */
169     php_phttpd_sapi_send_headers,           /* send headers handler */
170     NULL,                                   /* send header handler */
171 
172     php_phttpd_sapi_read_post,              /* read POST data */
173     php_phttpd_sapi_read_cookies,           /* read Cookies */
174 
175 	NULL,									/* register server variables */
176 	NULL,									/* Log message */
177 	NULL,									/* Get request time */
178 	NULL,									/* Child terminate */
179 
180     STANDARD_SAPI_MODULE_PROPERTIES
181 };
182 
183 static void
php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)184 php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)
185 {
186 	memset(&SG(request_info), 0, sizeof(sapi_globals_struct)); /* pfusch! */
187 
188     SG(request_info).query_string = PHG(cip)->hip->request;
189     SG(request_info).request_method = PHG(cip)->hip->method;
190 	SG(request_info).path_translated = malloc(MAXPATHLEN);
191     SG(sapi_headers).http_response_code = 200;
192 	if (url_expand(PHG(cip)->hip->url, SG(request_info).path_translated, MAXPATHLEN, &PHG(sb), NULL, NULL) == NULL) {
193 		/* handle error */
194 	}
195 
196 #if 0
197     char *server;
198     Ns_DString ds;
199     char *root;
200     int index;
201     char *tmp;
202 
203     server = Ns_ConnServer(NSG(conn));
204 
205     Ns_DStringInit(&ds);
206     Ns_UrlToFile(&ds, server, NSG(conn->request->url));
207 
208     /* path_translated is the absolute path to the file */
209     SG(request_info).path_translated = strdup(Ns_DStringValue(&ds));
210     Ns_DStringFree(&ds);
211     root = Ns_PageRoot(server);
212     SG(request_info).request_uri = SG(request_info).path_translated + strlen(root);
213     SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
214     index = Ns_SetIFind(NSG(conn)->headers, "content-type");
215     SG(request_info).content_type = index == -1 ? NULL :
216         Ns_SetValue(NSG(conn)->headers, index);
217 
218     tmp = Ns_ConnAuthUser(NSG(conn));
219     if(tmp) {
220         tmp = estrdup(tmp);
221     }
222     SG(request_info).auth_user = tmp;
223 
224     tmp = Ns_ConnAuthPasswd(NSG(conn));
225     if(tmp) {
226         tmp = estrdup(tmp);
227     }
228     SG(request_info).auth_password = tmp;
229 
230     NSG(data_avail) = SG(request_info).content_length;
231 #endif
232 }
233 
234 static void
php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)235 php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)
236 {
237     free(SG(request_info).path_translated);
238 }
239 
240 
php_doit(TSRMLS_D)241 int php_doit(TSRMLS_D)
242 {
243 	struct stat sb;
244 	zend_file_handle file_handle;
245 	struct httpinfo *hip = PHG(cip)->hip;
246 
247 	if (php_request_startup(TSRMLS_C) == FAILURE) {
248         return -1;
249     }
250 
251     file_handle.type = ZEND_HANDLE_FILENAME;
252     file_handle.filename = SG(request_info).path_translated;
253     file_handle.free_filename = 0;
254 
255 /*
256 	php_phttpd_hash_environment(TSRMLS_C);
257 */
258 	php_execute_script(&file_handle TSRMLS_CC);
259 	php_request_shutdown(NULL);
260 
261 	return SG(sapi_headers).http_response_code;
262 }
263 
pm_init(const char ** argv)264 int pm_init(const char **argv)
265 {
266 	tsrm_startup(1, 1, 0, NULL);
267 	sapi_startup(&phttpd_sapi_module);
268     phttpd_sapi_module.startup(&phttpd_sapi_module);
269 
270 	ts_allocate_id(&ph_globals_id, sizeof(phttpd_globals_struct), NULL, NULL);
271 
272 	return 0;
273 }
274 
pm_exit(void)275 void pm_exit(void)
276 {
277 	fprintf(stderr,"***pm_exit\n");
278 }
279 
pm_request(struct connectioninfo * cip)280 int pm_request(struct connectioninfo *cip)
281 {
282 	struct httpinfo *hip = cip->hip;
283 	int status;
284 	TSRMLS_FETCH();
285 
286 	if (strcasecmp(hip->method, "GET") == 0 ||
287 	    strcasecmp(hip->method, "HEAD") == 0 ||
288 	    strcasecmp(hip->method, "POST") == 0) {
289 		PHG(cip) = cip;
290 
291 		php_phttpd_request_ctor(TSRMLS_C);
292 		status = php_doit(TSRMLS_C);
293 		php_phttpd_request_dtor(TSRMLS_C);
294 
295 		return status;
296 	} else {
297 		return -2;
298 	}
299 }
300 
301 #endif
302