This source file includes following definitions.
- php_ns_sapi_ub_write
- php_ns_sapi_header_handler
- php_ns_sapi_send_headers
- php_ns_sapi_read_post
- php_ns_sapi_read_cookies
- php_info_aolserver
- PHP_FUNCTION
- php_ns_startup
- php_ns_sapi_register_variables
- php_ns_module_main
- php_ns_request_ctor
- php_ns_request_dtor
- php_ns_request_handler
- php_ns_config
- php_ns_server_shutdown
- Ns_ModuleInit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 #define Debug php_Debug
29 #include "php.h"
30 #undef Debug
31
32 #ifdef HAVE_AOLSERVER
33
34 #ifndef ZTS
35 #error AOLserver module is only useable in thread-safe mode
36 #endif
37
38 #include "ext/standard/info.h"
39 #define SECTION(name) PUTS("<h2>" name "</h2>\n")
40
41 #define NS_BUF_SIZE 511
42
43 #include "php_ini.h"
44 #include "php_globals.h"
45 #include "SAPI.h"
46 #include "php_main.h"
47 #include "php_variables.h"
48
49 #include "ns.h"
50
51 #include "php_version.h"
52
53
54
55 int Ns_ModuleVersion = 1;
56
57 #define NSG(v) TSRMG(ns_globals_id, ns_globals_struct *, v)
58
59
60
61 typedef struct {
62 sapi_module_struct *sapi_module;
63 char *ns_server;
64 char *ns_module;
65 } php_ns_context;
66
67
68
69 typedef struct {
70 Ns_Conn *conn;
71 size_t data_avail;
72 } ns_globals_struct;
73
74
75
76 static int ns_globals_id;
77
78
79
80 static php_ns_context *global_context;
81
82 static void php_ns_config(php_ns_context *ctx, char global);
83
84
85
86
87
88 static int
89 php_ns_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
90 {
91 int n;
92 uint sent = 0;
93
94 while (str_length > 0) {
95 n = Ns_ConnWrite(NSG(conn), (void *) str, str_length);
96
97 if (n == -1)
98 php_handle_aborted_connection();
99
100 str += n;
101 sent += n;
102 str_length -= n;
103 }
104
105 return sent;
106 }
107
108
109
110
111
112
113 static int
114 php_ns_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
115 {
116 char *header_name, *header_content;
117 char *p;
118
119 header_name = sapi_header->header;
120 header_content = p = strchr(header_name, ':');
121
122 if (p) {
123 *p = '\0';
124 do {
125 header_content++;
126 } while (*header_content == ' ');
127
128 if (!strcasecmp(header_name, "Content-type")) {
129 Ns_ConnSetTypeHeader(NSG(conn), header_content);
130 } else {
131 Ns_ConnSetHeaders(NSG(conn), header_name, header_content);
132 }
133
134 *p = ':';
135 }
136
137 sapi_free_header(sapi_header);
138
139 return 0;
140 }
141
142
143
144
145
146
147 static int
148 php_ns_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
149 {
150 if(SG(sapi_headers).send_default_content_type) {
151 Ns_ConnSetRequiredHeaders(NSG(conn), "text/html", 0);
152 }
153
154 Ns_ConnFlushHeaders(NSG(conn), SG(sapi_headers).http_response_code);
155
156 return SAPI_HEADER_SENT_SUCCESSFULLY;
157 }
158
159
160
161
162
163
164 static int
165 php_ns_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
166 {
167 uint max_read;
168 uint total_read = 0;
169
170 max_read = MIN(NSG(data_avail), count_bytes);
171
172 total_read = Ns_ConnRead(NSG(conn), buf, max_read);
173
174 if(total_read == NS_ERROR) {
175 total_read = -1;
176 } else {
177 NSG(data_avail) -= total_read;
178 }
179
180 return total_read;
181 }
182
183
184
185
186
187
188 static char *php_ns_sapi_read_cookies(TSRMLS_D)
189 {
190 int i;
191 char *http_cookie = NULL;
192
193 i = Ns_SetIFind(NSG(conn->headers), "cookie");
194 if(i != -1) {
195 http_cookie = Ns_SetValue(NSG(conn->headers), i);
196 }
197
198 return http_cookie;
199 }
200
201 static void php_info_aolserver(ZEND_MODULE_INFO_FUNC_ARGS)
202 {
203 char buf[512];
204 int uptime = Ns_InfoUptime();
205 int i;
206
207 php_info_print_table_start();
208 php_info_print_table_row(2, "SAPI module version", "$Id$");
209 php_info_print_table_row(2, "Build date", Ns_InfoBuildDate());
210 php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile());
211 php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog());
212 php_info_print_table_row(2, "Installation path", Ns_InfoHomePath());
213 php_info_print_table_row(2, "Hostname of server", Ns_InfoHostname());
214 php_info_print_table_row(2, "Source code label", Ns_InfoLabel());
215 php_info_print_table_row(2, "Server platform", Ns_InfoPlatform());
216 snprintf(buf, 511, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion());
217 php_info_print_table_row(2, "Server version", buf);
218 snprintf(buf, 511, "%d day(s), %02d:%02d:%02d",
219 uptime / 86400,
220 (uptime / 3600) % 24,
221 (uptime / 60) % 60,
222 uptime % 60);
223 php_info_print_table_row(2, "Server uptime", buf);
224 php_info_print_table_end();
225
226 SECTION("HTTP Headers Information");
227 php_info_print_table_start();
228 php_info_print_table_colspan_header(2, "HTTP Request Headers");
229 php_info_print_table_row(2, "HTTP Request", NSG(conn)->request->line);
230 for (i = 0; i < Ns_SetSize(NSG(conn)->headers); i++) {
231 php_info_print_table_row(2, Ns_SetKey(NSG(conn)->headers, i), Ns_SetValue(NSG(conn)->headers, i));
232 }
233
234 php_info_print_table_colspan_header(2, "HTTP Response Headers");
235 for (i = 0; i < Ns_SetSize(NSG(conn)->outputheaders); i++) {
236 php_info_print_table_row(2, Ns_SetKey(NSG(conn)->outputheaders, i), Ns_SetValue(NSG(conn)->outputheaders, i));
237 }
238 php_info_print_table_end();
239 }
240
241 PHP_FUNCTION(getallheaders);
242
243
244 ZEND_BEGIN_ARG_INFO(arginfo_aolserver_getallheaders, 0)
245 ZEND_END_ARG_INFO()
246
247
248 static const zend_function_entry aolserver_functions[] = {
249 PHP_FE(getallheaders, arginfo_aolserver_getallheaders)
250 {NULL, NULL, NULL}
251 };
252
253 static zend_module_entry php_aolserver_module = {
254 STANDARD_MODULE_HEADER,
255 "AOLserver",
256 aolserver_functions,
257 NULL,
258 NULL,
259 NULL,
260 NULL,
261 php_info_aolserver,
262 NULL,
263 STANDARD_MODULE_PROPERTIES
264 };
265
266 PHP_FUNCTION(getallheaders)
267 {
268 int i;
269
270 array_init(return_value);
271
272 for (i = 0; i < Ns_SetSize(NSG(conn->headers)); i++) {
273 char *key = Ns_SetKey(NSG(conn->headers), i);
274 char *value = Ns_SetValue(NSG(conn->headers), i);
275
276 add_assoc_string(return_value, key, value, 1);
277 }
278 }
279
280 static int
281 php_ns_startup(sapi_module_struct *sapi_module)
282 {
283 if (php_module_startup(sapi_module, &php_aolserver_module, 1) == FAILURE) {
284 return FAILURE;
285 } else {
286 return SUCCESS;
287 }
288 }
289
290
291
292
293
294
295
296
297 #define ADD_STRINGX(name, buf) \
298 php_register_variable(name, buf, track_vars_array TSRMLS_CC)
299
300 #define ADD_STRING(name) \
301 ADD_STRINGX(name, buf)
302
303 static void
304 php_ns_sapi_register_variables(zval *track_vars_array TSRMLS_DC)
305 {
306 int i;
307 char buf[NS_BUF_SIZE + 1];
308 char *tmp;
309
310 for(i = 0; i < Ns_SetSize(NSG(conn->headers)); i++) {
311 char *key = Ns_SetKey(NSG(conn->headers), i);
312 char *value = Ns_SetValue(NSG(conn->headers), i);
313 char *p;
314 char c;
315
316 snprintf(buf, NS_BUF_SIZE, "HTTP_%s", key);
317
318 for(p = buf + 5; (c = *p); p++) {
319 c = toupper(c);
320 if(c < 'A' || c > 'Z') {
321 c = '_';
322 }
323 *p = c;
324 }
325
326 ADD_STRINGX(buf, value);
327 }
328
329 snprintf(buf, NS_BUF_SIZE, "%s/%s", Ns_InfoServerName(), Ns_InfoServerVersion());
330 ADD_STRING("SERVER_SOFTWARE");
331 snprintf(buf, NS_BUF_SIZE, "HTTP/%1.1f", NSG(conn)->request->version);
332 ADD_STRING("SERVER_PROTOCOL");
333
334 ADD_STRINGX("REQUEST_METHOD", NSG(conn)->request->method);
335
336 if(NSG(conn)->request->query)
337 ADD_STRINGX("QUERY_STRING", NSG(conn)->request->query);
338
339 ADD_STRINGX("SERVER_BUILDDATE", Ns_InfoBuildDate());
340
341 ADD_STRINGX("REMOTE_ADDR", Ns_ConnPeer(NSG(conn)));
342
343 snprintf(buf, NS_BUF_SIZE, "%d", Ns_ConnPeerPort(NSG(conn)));
344 ADD_STRING("REMOTE_PORT");
345
346 snprintf(buf, NS_BUF_SIZE, "%d", Ns_ConnPort(NSG(conn)));
347 ADD_STRING("SERVER_PORT");
348
349 tmp = Ns_ConnHost(NSG(conn));
350 if (tmp)
351 ADD_STRINGX("SERVER_NAME", tmp);
352
353 ADD_STRINGX("PATH_TRANSLATED", SG(request_info).path_translated);
354 ADD_STRINGX("REQUEST_URI", SG(request_info).request_uri);
355 ADD_STRINGX("PHP_SELF", SG(request_info).request_uri);
356
357 ADD_STRINGX("GATEWAY_INTERFACE", "CGI/1.1");
358
359 snprintf(buf, NS_BUF_SIZE, "%d", Ns_InfoBootTime());
360 ADD_STRING("SERVER_BOOTTIME");
361 }
362
363
364
365
366
367 static sapi_module_struct aolserver_sapi_module = {
368 "aolserver",
369 "AOLserver",
370
371 php_ns_startup,
372 php_module_shutdown_wrapper,
373
374 NULL,
375 NULL,
376
377 php_ns_sapi_ub_write,
378 NULL,
379 NULL,
380 NULL,
381
382 php_error,
383
384 php_ns_sapi_header_handler,
385 php_ns_sapi_send_headers,
386 NULL,
387
388 php_ns_sapi_read_post,
389 php_ns_sapi_read_cookies,
390
391 php_ns_sapi_register_variables,
392 NULL,
393 NULL,
394 NULL,
395
396 STANDARD_SAPI_MODULE_PROPERTIES
397 };
398
399
400
401
402
403
404 static int
405 php_ns_module_main(TSRMLS_D)
406 {
407 zend_file_handle file_handle;
408
409 file_handle.type = ZEND_HANDLE_FILENAME;
410 file_handle.filename = SG(request_info).path_translated;
411 file_handle.free_filename = 0;
412 file_handle.opened_path = NULL;
413
414 php_ns_config(global_context, 0);
415 if (php_request_startup(TSRMLS_C) == FAILURE) {
416 return NS_ERROR;
417 }
418
419 php_execute_script(&file_handle TSRMLS_CC);
420 php_request_shutdown(NULL);
421
422 return NS_OK;
423 }
424
425
426
427
428
429
430 static void
431 php_ns_request_ctor(TSRMLS_D)
432 {
433 char *server;
434 Ns_DString ds;
435 char *root;
436 int index;
437 char *tmp;
438
439 server = Ns_ConnServer(NSG(conn));
440
441 #define safe_strdup(x) ((x)?strdup((x)):NULL)
442 SG(request_info).query_string = safe_strdup(NSG(conn->request->query));
443
444 Ns_DStringInit(&ds);
445 Ns_UrlToFile(&ds, server, NSG(conn->request->url));
446
447
448 SG(request_info).path_translated = safe_strdup(Ns_DStringValue(&ds));
449 Ns_DStringFree(&ds);
450 root = Ns_PageRoot(server);
451 SG(request_info).request_uri = strdup(SG(request_info).path_translated + strlen(root));
452 SG(request_info).request_method = NSG(conn)->request->method;
453 if(NSG(conn)->request->version > 1.0) SG(request_info).proto_num = 1001;
454 else SG(request_info).proto_num = 1000;
455 SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
456 index = Ns_SetIFind(NSG(conn)->headers, "content-type");
457 SG(request_info).content_type = index == -1 ? NULL :
458 Ns_SetValue(NSG(conn)->headers, index);
459 SG(sapi_headers).http_response_code = 200;
460
461 tmp = Ns_ConnAuthUser(NSG(conn));
462 if (tmp)
463 tmp = estrdup(tmp);
464 SG(request_info).auth_user = tmp;
465
466 tmp = Ns_ConnAuthPasswd(NSG(conn));
467 if (tmp)
468 tmp = estrdup(tmp);
469 SG(request_info).auth_password = tmp;
470
471 NSG(data_avail) = SG(request_info).content_length;
472 }
473
474
475
476
477
478
479 static void
480 php_ns_request_dtor(TSRMLS_D)
481 {
482 free(SG(request_info).path_translated);
483 if (SG(request_info).query_string)
484 free(SG(request_info).query_string);
485 free(SG(request_info).request_uri);
486 }
487
488
489
490
491
492
493 static int
494 php_ns_request_handler(void *context, Ns_Conn *conn)
495 {
496 int status = NS_OK;
497 TSRMLS_FETCH();
498
499 NSG(conn) = conn;
500
501 SG(server_context) = global_context;
502
503 php_ns_request_ctor(TSRMLS_C);
504
505 status = php_ns_module_main(TSRMLS_C);
506
507 php_ns_request_dtor(TSRMLS_C);
508
509 return status;
510 }
511
512
513
514
515
516
517
518 static void
519 php_ns_config(php_ns_context *ctx, char global)
520 {
521 int i;
522 char *path;
523 Ns_Set *set;
524
525 path = Ns_ConfigGetPath(ctx->ns_server, ctx->ns_module, NULL);
526 set = Ns_ConfigGetSection(path);
527
528 for (i = 0; set && i < Ns_SetSize(set); i++) {
529 char *key = Ns_SetKey(set, i);
530 char *value = Ns_SetValue(set, i);
531
532 if (global && !strcasecmp(key, "map")) {
533 Ns_Log(Notice, "Registering PHP for \"%s\"", value);
534 Ns_RegisterRequest(ctx->ns_server, "GET", value, php_ns_request_handler, NULL, ctx, 0);
535 Ns_RegisterRequest(ctx->ns_server, "POST", value, php_ns_request_handler, NULL, ctx, 0);
536 Ns_RegisterRequest(ctx->ns_server, "HEAD", value, php_ns_request_handler, NULL, ctx, 0);
537
538
539
540
541
542
543
544 } else if (!global && !strcasecmp(key, "php_value")) {
545 Ns_Log(Notice, "php_value has been deactivated temporarily. Please use a php.ini file to pass directives to PHP. Thanks.");
546 #if 0
547 char *val;
548
549 val = strchr(value, ' ');
550 if (val) {
551 char *new_key;
552
553 new_key = estrndup(value, val - value);
554
555 do {
556 val++;
557 } while(*val == ' ');
558
559 Ns_Log(Debug, "PHP configuration option '%s=%s'", new_key, val);
560 zend_alter_ini_entry(new_key, strlen(new_key) + 1, val,
561 strlen(val) + 1, PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE);
562
563 efree(new_key);
564 }
565 #endif
566 }
567
568 }
569 }
570
571
572
573
574
575
576 static void
577 php_ns_server_shutdown(void *context)
578 {
579 php_ns_context *ctx = (php_ns_context *) context;
580
581 ctx->sapi_module->shutdown(ctx->sapi_module);
582 sapi_shutdown();
583 tsrm_shutdown();
584
585 free(ctx->ns_module);
586 free(ctx->ns_server);
587 free(ctx);
588 }
589
590
591
592
593
594
595
596
597 int Ns_ModuleInit(char *server, char *module)
598 {
599 php_ns_context *ctx;
600
601 tsrm_startup(1, 1, 0, NULL);
602 sapi_startup(&aolserver_sapi_module);
603 sapi_module.startup(&aolserver_sapi_module);
604
605
606 ts_allocate_id(&ns_globals_id, sizeof(ns_globals_struct), NULL, NULL);
607
608
609 ctx = malloc(sizeof *ctx);
610 ctx->sapi_module = &aolserver_sapi_module;
611 ctx->ns_server = strdup(server);
612 ctx->ns_module = strdup(module);
613
614
615 php_ns_config(ctx, 1);
616
617 global_context = ctx;
618
619
620 Ns_RegisterServerShutdown(server, php_ns_server_shutdown, ctx);
621
622 return NS_OK;
623 }
624
625 #endif