/[hydra]/hydra/contrib/sapi-hydra/hydra.c
ViewVC logotype

Contents of /hydra/contrib/sapi-hydra/hydra.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations)
Wed Jan 22 07:47:39 2003 UTC (21 years, 2 months ago) by nmav
Branch: MAIN
CVS Tags: hydra_0_1_6_without_hic, hydra_0_1_7, hydra_0_1_6, hydra_0_1_4
Changes since 1.11: +9 -3 lines
File MIME type: text/plain
added missing redhat directory

1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 4 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2002 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.02 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available at through the world-wide-web at |
10 | http://www.php.net/license/2_02.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: Nikos Mavroyanopoulos <nmav@gnutls.org> |
16 +----------------------------------------------------------------------+
17 */
18
19 /* $Id: hydra.c,v 1.11.2.2 2003/01/19 10:15:22 nmav Exp $ */
20
21 #include "php.h"
22 #include "SAPI.h"
23 #include "php_main.h"
24 #include "php_variables.h"
25 #include "php_ini.h"
26
27 #include "ext/standard/php_smart_str.h"
28
29 #include <sys/time.h>
30 #include <sys/types.h>
31 #include <sys/uio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34
35 #include <hic.h> /* for hic_stuff structure */
36
37 typedef struct {
38 hic_stuff *hc;
39 int read_post_data;
40 void (*on_close)(int);
41 long async_send;
42 } php_hydra_globals;
43
44
45 #ifdef ZTS
46 static int hydra_globals_id;
47 #define TG(v) TSRMG(hydra_globals_id, php_hydra_globals *, v)
48 #else
49 static php_hydra_globals hydra_globals;
50 #define TG(v) (hydra_globals.v)
51 #endif
52
53 PHP_INI_BEGIN()
54 STD_PHP_INI_ENTRY("async_send", "0", PHP_INI_ALL, OnUpdateInt, async_send, php_hydra_globals, hydra_globals)
55 PHP_INI_END()
56
57 static int sapi_hydra_ub_write(const char *str, uint str_length TSRMLS_DC)
58 {
59 int n;
60 uint sent = 0;
61
62 while (str_length > 0) {
63 n = write(TG(hc)->out_fd, str, str_length);
64
65 if (n == -1 && errno == EPIPE)
66 php_handle_aborted_connection();
67 if (n == -1 && errno == EINTR)
68 continue;
69
70 if (n <= 0)
71 return n;
72
73 TG(hc)->bytes_sent += n;
74 str += n;
75 sent += n;
76 str_length -= n;
77 }
78
79 return sent;
80 }
81
82 #define COMBINE_HEADERS 30
83
84 static int sapi_hydra_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
85 {
86 char buf[1024];
87 struct iovec vec[COMBINE_HEADERS];
88 int n = 0;
89 zend_llist_position pos;
90 sapi_header_struct *h;
91 size_t len;
92
93 if (!SG(sapi_headers).http_status_line) {
94 char* desc;
95
96 if (SG(sapi_headers).http_response_code == 200)
97 desc = "OK";
98 else
99 desc = "Something";
100
101 snprintf(buf, sizeof(buf)-1, "Status: %d %s\r\n", SG(sapi_headers).http_response_code,
102 desc);
103 len = strlen(buf);
104 vec[n].iov_base = buf;
105 vec[n].iov_len = len;
106
107 } else {
108 vec[n].iov_base = SG(sapi_headers).http_status_line;
109 len = strlen(vec[n].iov_base);
110 vec[n].iov_len = len;
111 vec[++n].iov_base = "\r\n";
112 vec[n].iov_len = 2;
113 len += 2;
114 }
115 TG(hc)->status = SG(sapi_headers).http_response_code;
116 TG(hc)->bytes_sent += len;
117 n++;
118
119 #define DEF_CONTENT_TYPE_LINE "Content-Type: text/html\r\n"
120 if (SG(sapi_headers).send_default_content_type) {
121 vec[n].iov_base = DEF_CONTENT_TYPE_LINE;
122 vec[n].iov_len = sizeof(DEF_CONTENT_TYPE_LINE) - 1;
123 n++;
124 }
125
126 h = zend_llist_get_first_ex(&sapi_headers->headers, &pos);
127 while (h) {
128 vec[n].iov_base = h->header;
129 vec[n++].iov_len = h->header_len;
130 if (n >= COMBINE_HEADERS - 1) {
131 /* XXX: partial writevs are not handled */
132 if (writev(TG(hc)->out_fd, vec, n) == -1 && errno == EPIPE)
133 php_handle_aborted_connection();
134 n = 0;
135 }
136 vec[n].iov_base = "\r\n";
137 vec[n++].iov_len = 2;
138
139 h = zend_llist_get_next_ex(&sapi_headers->headers, &pos);
140 }
141
142 vec[n].iov_base = "\r\n";
143 vec[n++].iov_len = 2;
144
145 if (n) {
146 /* XXX: partial writevs are not handled */
147 if (writev(TG(hc)->out_fd, vec, n) == -1 && errno == EPIPE)
148 php_handle_aborted_connection();
149 }
150
151 return SAPI_HEADER_SENT_SUCCESSFULLY;
152 }
153
154 static int sapi_hydra_read_post(char *buffer, uint count_bytes TSRMLS_DC)
155 {
156 size_t read_bytes = 0, tmp;
157 int c;
158 int n;
159
160 /* In hydra, post data are written to a file, and an fd of the file is sent here
161 */
162
163 while (read_bytes < count_bytes) {
164 tmp = read(TG(hc)->post_data_fd, buffer + read_bytes,
165 count_bytes - read_bytes);
166
167 if (tmp == 0 || (tmp == -1 && errno != EINTR))
168 break;
169 /* A simple "tmp > 0" produced broken code on Solaris/GCC */
170 if (tmp != 0 && tmp != -1)
171 read_bytes += tmp;
172
173 }
174
175 TG(read_post_data) += read_bytes;
176
177 return read_bytes;
178 }
179
180 #define COOKIE "HTTP_COOKIE="
181 #define COOKIE_SIZE sizeof("HTTP_COOKIE=")-1
182 static char *sapi_hydra_read_cookies(TSRMLS_D)
183 {
184 int i;
185 char *p = NULL;
186 /* register_variables should have been called before this.
187 */
188 i = 0;
189 while( TG(hc)->cgi_env[i] != NULL) {
190 if (strncmp( TG(hc)->cgi_env[i], COOKIE, COOKIE_SIZE)==0) {
191 p = strchr( TG(hc)->cgi_env[i], '=');
192 if (p) p++;
193 break;
194 }
195 i++;
196 }
197
198 return p;
199 }
200
201 #define BUF_SIZE 512
202
203 static void sapi_hydra_register_variables(zval *track_vars_array TSRMLS_DC)
204 {
205 char buf[BUF_SIZE];
206 char *p;
207 int i;
208
209 php_register_variable("PHP_SELF", SG(request_info).request_uri, track_vars_array TSRMLS_CC);
210
211 buf[BUF_SIZE] = 0;
212
213 /* Register all variables in cgi_env
214 * cgi_env has variables in the form XXX=YYY
215 */
216 i = 0;
217 while( TG(hc)->cgi_env[i] != NULL) {
218 if (TG(hc)->cgi_env[i] == NULL) continue;
219
220 strncpy( buf, TG(hc)->cgi_env[i], BUF_SIZE - 1);
221 p = strchr( buf, '=');
222 if (p!=NULL) { /* replace '=' with '\0' */
223 *p=0;
224 php_register_variable( buf, p+1, track_vars_array TSRMLS_CC);
225 }
226 i++;
227 }
228
229 }
230
231 static PHP_MINIT_FUNCTION(hydra)
232 {
233 REGISTER_INI_ENTRIES();
234 return SUCCESS;
235 }
236
237 static zend_module_entry php_hydra_module = {
238 STANDARD_MODULE_HEADER,
239 "hydra",
240 NULL,
241 PHP_MINIT(hydra),
242 NULL,
243 NULL,
244 NULL,
245 NULL, /* info */
246 NULL,
247 STANDARD_MODULE_PROPERTIES
248 };
249
250 static int php_hydra_startup(sapi_module_struct *sapi_module)
251 {
252 if (php_module_startup(sapi_module) == FAILURE
253 || zend_startup_module(&php_hydra_module) == FAILURE) {
254 return FAILURE;
255 }
256 return SUCCESS;
257 }
258
259 static sapi_module_struct hydra_sapi_module = {
260 "hydra",
261 "hydra",
262
263 php_hydra_startup,
264 php_module_shutdown_wrapper,
265
266 NULL, /* activate */
267 NULL, /* deactivate */
268
269 sapi_hydra_ub_write,
270 NULL,
271 NULL, /* get uid */
272 NULL, /* getenv */
273
274 php_error,
275
276 NULL,
277 sapi_hydra_send_headers,
278 NULL,
279 sapi_hydra_read_post,
280 sapi_hydra_read_cookies,
281
282 sapi_hydra_register_variables,
283 NULL, /* Log message */
284
285 NULL, /* Block interruptions */
286 NULL, /* Unblock interruptions */
287
288 STANDARD_SAPI_MODULE_PROPERTIES
289 };
290
291 static void hydra_module_main(TSRMLS_D)
292 {
293 zend_file_handle file_handle;
294
295 file_handle.type = ZEND_HANDLE_FILENAME;
296 file_handle.filename = SG(request_info).path_translated;
297 file_handle.free_filename = 0;
298 file_handle.opened_path = NULL;
299
300 if (php_request_startup(TSRMLS_C) == FAILURE) {
301 return;
302 }
303
304 php_execute_script(&file_handle TSRMLS_CC);
305 php_request_shutdown(NULL);
306 }
307
308 static int hydra_request_ctor(TSRMLS_D)
309 {
310 int offset, i;
311 char* query_string;
312 char* content_length;
313 char* auth = NULL;
314 char* request_method;
315 char *p = NULL;
316
317 i = 0;
318 while( TG(hc)->cgi_env[i] != NULL) {
319 if (TG(hc)->cgi_env[i] == NULL) continue;
320
321 if (strncmp( TG(hc)->cgi_env[i], "REQUEST_METHOD=", 15)==0) {
322 p = strchr( TG(hc)->cgi_env[i], '=');
323 if (p) p++;
324 SG(request_info).request_method = p;
325 } else if (strncmp( TG(hc)->cgi_env[i], "HTTP_AUTHORIZATION=", 19)==0) {
326 p = strchr( TG(hc)->cgi_env[i], '=');
327 if (p) p++;
328 auth = p;
329 } else if (strncmp( TG(hc)->cgi_env[i], "CONTENT_TYPE=", 13)==0) {
330 p = strchr( TG(hc)->cgi_env[i], '=');
331 if (p) p++;
332 SG(request_info).content_type = p;
333 } else if (strncmp( TG(hc)->cgi_env[i], "CONTENT_LENGTH=", 15)==0) {
334 p = strchr( TG(hc)->cgi_env[i], '=');
335 if (p) {
336 p++;
337 SG(request_info).content_length = atoi(p);
338 }
339 } else if (strncmp( TG(hc)->cgi_env[i], "QUERY_STRING=", 13)==0) {
340 p = strchr( TG(hc)->cgi_env[i], '=');
341 if (p) {
342 p++;
343 SG(request_info).query_string = p;
344 }
345 } else if (strncmp( TG(hc)->cgi_env[i], "REQUEST_URI=", 12)==0) {
346 p = strchr( TG(hc)->cgi_env[i], '=');
347 if (p) {
348 p++;
349 SG(request_info).request_uri = p;
350 }
351 } else if (strncmp( TG(hc)->cgi_env[i], "PATH_TRANSLATED=", 14)==0) {
352 p = strchr( TG(hc)->cgi_env[i], '=');
353 if (p) {
354 p++;
355 SG(request_info).path_translated = p;
356 }
357 }
358 i++;
359 }
360 if ( SG(request_info).path_translated == NULL ||
361 SG(request_info).request_uri == NULL) return -1;
362
363 SG(sapi_headers).http_response_code = 200;
364
365 php_handle_auth_data(auth TSRMLS_CC);
366
367 SG(server_context) = (void *) 1;
368
369 return 0;
370 }
371
372 static void hydra_request_dtor(TSRMLS_D)
373 {
374 return;
375 }
376
377
378
379 static off_t hydra_php_request(hic_stuff *hc TSRMLS_DC)
380 {
381 TG(hc) = hc;
382 hc->bytes_sent = 0;
383 hc->status = 200;
384
385 TG(read_post_data) = 0;
386
387 if (hydra_request_ctor(TSRMLS_C) == -1)
388 return 0;
389
390 hydra_module_main(TSRMLS_C);
391
392 hydra_request_dtor(TSRMLS_C);
393
394 return 0;
395 }
396
397 off_t _php_hic_request( hic_stuff *hc)
398 {
399 TSRMLS_FETCH();
400 return hydra_php_request(hc TSRMLS_CC);
401 }
402
403 void _php_hic_init(void)
404 {
405 char *ini;
406
407 #ifdef ZTS
408 tsrm_startup(1, 1, 0, NULL);
409 ts_allocate_id(&hydra_globals_id, sizeof(php_hydra_globals), NULL, NULL);
410 {
411 TSRMLS_FETCH();
412 TG(on_close) = NULL;
413 }
414 #endif
415
416 if ((ini = getenv("PHP_INI_PATH"))) {
417 hydra_sapi_module.php_ini_path_override = ini;
418 }
419
420 sapi_startup(&hydra_sapi_module);
421 hydra_sapi_module.startup(&hydra_sapi_module);
422
423 {
424 TSRMLS_FETCH();
425 }
426
427 }
428
429 void _php_hic_shutdown(void)
430 {
431 TSRMLS_FETCH();
432
433 if (SG(server_context) != NULL) {
434 hydra_sapi_module.shutdown(&hydra_sapi_module);
435 sapi_shutdown();
436 #ifdef ZTS
437 tsrm_shutdown();
438 #endif
439 }
440 }

webmaster@linux.gr
ViewVC Help
Powered by ViewVC 1.1.26