- add pers. handles test
[m6w6/ext-http] / http.c
1 /*
2 +--------------------------------------------------------------------+
3 | PECL :: http |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2007, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
11 */
12
13 /* $Id$ */
14
15 #define HTTP_WANT_SAPI
16 #define HTTP_WANT_CURL
17 #define HTTP_WANT_ZLIB
18 #define HTTP_WANT_MAGIC
19 #include "php_http.h"
20
21 #include "php_ini.h"
22 #include "ext/standard/info.h"
23 #include "zend_extensions.h"
24
25 #include "php_http_api.h"
26 #include "php_http_send_api.h"
27 #include "php_http_cookie_api.h"
28 #include "php_http_cache_api.h"
29 #include "php_http_send_api.h"
30 #include "php_http_message_api.h"
31 #include "php_http_request_method_api.h"
32 #ifdef HTTP_HAVE_CURL
33 # include "php_http_request_api.h"
34 # include "php_http_request_pool_api.h"
35 # include "php_http_request_datashare_api.h"
36 # ifdef HTTP_HAVE_PERSISTENT_HANDLES
37 # include "php_http_persistent_handle_api.h"
38 # endif
39 #endif
40 #ifdef HTTP_HAVE_ZLIB
41 # include "php_http_encoding_api.h"
42 #endif
43 #include "php_http_url_api.h"
44
45 #ifdef ZEND_ENGINE_2
46 # include "php_http_filter_api.h"
47 # include "php_http_util_object.h"
48 # include "php_http_message_object.h"
49 # include "php_http_querystring_object.h"
50 # ifndef WONKY
51 # include "php_http_response_object.h"
52 # endif
53 # ifdef HTTP_HAVE_CURL
54 # include "php_http_request_object.h"
55 # include "php_http_requestpool_object.h"
56 # include "php_http_requestdatashare_object.h"
57 # endif
58 # ifdef HTTP_HAVE_ZLIB
59 # include "php_http_deflatestream_object.h"
60 # include "php_http_inflatestream_object.h"
61 # endif
62 # include "php_http_exception_object.h"
63 #endif
64
65
66 ZEND_DECLARE_MODULE_GLOBALS(http);
67 HTTP_DECLARE_ARG_PASS_INFO();
68
69 #ifdef COMPILE_DL_HTTP
70 ZEND_GET_MODULE(http)
71 #endif
72
73 /* {{{ http_functions[] */
74 zend_function_entry http_functions[] = {
75 PHP_FE(http_date, NULL)
76 PHP_FE(http_build_url, http_arg_pass_ref_4)
77 PHP_FE(http_build_str, NULL)
78 #ifndef ZEND_ENGINE_2
79 PHP_FALIAS(http_build_query, http_build_str, NULL)
80 #endif
81 PHP_FE(http_negotiate_language, http_arg_pass_ref_2)
82 PHP_FE(http_negotiate_charset, http_arg_pass_ref_2)
83 PHP_FE(http_negotiate_content_type, http_arg_pass_ref_2)
84 PHP_FE(http_redirect, NULL)
85 PHP_FE(http_throttle, NULL)
86 PHP_FE(http_send_status, NULL)
87 PHP_FE(http_send_last_modified, NULL)
88 PHP_FE(http_send_content_type, NULL)
89 PHP_FE(http_send_content_disposition, NULL)
90 PHP_FE(http_match_modified, NULL)
91 PHP_FE(http_match_etag, NULL)
92 PHP_FE(http_cache_last_modified, NULL)
93 PHP_FE(http_cache_etag, NULL)
94 PHP_FE(http_send_data, NULL)
95 PHP_FE(http_send_file, NULL)
96 PHP_FE(http_send_stream, NULL)
97 PHP_FE(http_chunked_decode, NULL)
98 PHP_FE(http_parse_message, NULL)
99 PHP_FE(http_parse_headers, NULL)
100 PHP_FE(http_parse_cookie, NULL)
101 PHP_FE(http_build_cookie, NULL)
102 PHP_FE(http_parse_params, NULL)
103 PHP_FE(http_get_request_headers, NULL)
104 PHP_FE(http_get_request_body, NULL)
105 PHP_FE(http_get_request_body_stream, NULL)
106 PHP_FE(http_match_request_header, NULL)
107 #ifdef HTTP_HAVE_CURL
108 # ifdef HTTP_HAVE_PERSISTENT_HANDLES
109 PHP_FE(http_persistent_handles_count, NULL)
110 PHP_FE(http_persistent_handles_clean, NULL)
111 PHP_FE(http_persistent_handles_ident, NULL)
112 # endif
113 PHP_FE(http_get, http_arg_pass_ref_3)
114 PHP_FE(http_head, http_arg_pass_ref_3)
115 PHP_FE(http_post_data, http_arg_pass_ref_4)
116 PHP_FE(http_post_fields, http_arg_pass_ref_5)
117 PHP_FE(http_put_data, http_arg_pass_ref_4)
118 PHP_FE(http_put_file, http_arg_pass_ref_4)
119 PHP_FE(http_put_stream, http_arg_pass_ref_4)
120 PHP_FE(http_request, http_arg_pass_ref_5)
121 PHP_FE(http_request_body_encode, NULL)
122 #endif
123 PHP_FE(http_request_method_register, NULL)
124 PHP_FE(http_request_method_unregister, NULL)
125 PHP_FE(http_request_method_exists, NULL)
126 PHP_FE(http_request_method_name, NULL)
127 PHP_FE(ob_etaghandler, NULL)
128 #ifdef HTTP_HAVE_ZLIB
129 PHP_FE(http_deflate, NULL)
130 PHP_FE(http_inflate, NULL)
131 PHP_FE(ob_deflatehandler, NULL)
132 PHP_FE(ob_inflatehandler, NULL)
133 #endif
134 PHP_FE(http_support, NULL)
135
136 EMPTY_FUNCTION_ENTRY
137 };
138 /* }}} */
139
140 PHP_MINIT_FUNCTION(http);
141 PHP_MSHUTDOWN_FUNCTION(http);
142 PHP_RINIT_FUNCTION(http);
143 PHP_RSHUTDOWN_FUNCTION(http);
144 PHP_MINFO_FUNCTION(http);
145
146 /* {{{ http_module_dep */
147 #if ZEND_EXTENSION_API_NO >= 220050617
148 static zend_module_dep http_module_deps[] = {
149 # ifdef HTTP_HAVE_SPL
150 ZEND_MOD_REQUIRED("spl")
151 # endif
152 # ifdef HTTP_HAVE_HASH
153 ZEND_MOD_REQUIRED("hash")
154 # endif
155 # ifdef HTTP_HAVE_SESSION
156 ZEND_MOD_REQUIRED("session")
157 # endif
158 # ifdef HTTP_HAVE_ICONV
159 ZEND_MOD_REQUIRED("iconv")
160 # endif
161 {NULL, NULL, NULL, 0}
162 };
163 #endif
164 /* }}} */
165
166 /* {{{ http_module_entry */
167 zend_module_entry http_module_entry = {
168 #if ZEND_EXTENSION_API_NO >= 220050617
169 STANDARD_MODULE_HEADER_EX, NULL,
170 http_module_deps,
171 #else
172 STANDARD_MODULE_HEADER,
173 #endif
174 "http",
175 http_functions,
176 PHP_MINIT(http),
177 PHP_MSHUTDOWN(http),
178 PHP_RINIT(http),
179 PHP_RSHUTDOWN(http),
180 PHP_MINFO(http),
181 PHP_EXT_HTTP_VERSION,
182 STANDARD_MODULE_PROPERTIES
183 };
184 /* }}} */
185
186 int http_module_number;
187
188 /* {{{ http_globals */
189 static void http_globals_init_once(zend_http_globals *G)
190 {
191 memset(G, 0, sizeof(zend_http_globals));
192 }
193
194 #define http_globals_init(g) _http_globals_init((g) TSRMLS_CC)
195 static inline void _http_globals_init(zend_http_globals *G TSRMLS_DC)
196 {
197 #ifdef HTTP_HAVE_SAPI_RTIME
198 G->request.time = sapi_get_request_time(TSRMLS_C);
199 #else
200 G->request.time = time(NULL);
201 #endif
202 G->send.buffer_size = 0;
203 G->read_post_data = 0;
204 }
205
206 #define http_globals_free(g) _http_globals_free((g) TSRMLS_CC)
207 static inline void _http_globals_free(zend_http_globals *G TSRMLS_DC)
208 {
209 if (G->request.headers) {
210 zend_hash_destroy(G->request.headers);
211 FREE_HASHTABLE(G->request.headers);
212 G->request.headers = NULL;
213 }
214 STR_SET(G->send.content_type, NULL);
215 STR_SET(G->send.unquoted_etag, NULL);
216 if (G->server_var) {
217 zval_ptr_dtor(&G->server_var);
218 G->server_var = NULL;
219 }
220 }
221 /* }}} */
222
223 /* {{{ static inline void http_check_allowed_methods(char *, int) */
224 #define http_check_allowed_methods(m, l) _http_check_allowed_methods((m), (l) TSRMLS_CC)
225 static inline void _http_check_allowed_methods(char *methods, int length TSRMLS_DC)
226 {
227 if (length && SG(request_info).request_method) {
228 if (SUCCESS != http_check_method_ex(SG(request_info).request_method, methods)) {
229 char *header = emalloc(length + sizeof("Allow: "));
230 sprintf(header, "Allow: %s", methods);
231 http_exit(405, header);
232 }
233 }
234 }
235 /* }}} */
236
237 /* {{{ PHP_INI */
238 PHP_INI_MH(http_update_allowed_methods)
239 {
240 http_check_allowed_methods(new_value, new_value_length);
241 return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
242 }
243 #ifdef HTTP_HAVE_PERSISTENT_HANDLES
244 PHP_INI_MH(http_update_persistent_handle_ident)
245 {
246 HTTP_G->persistent.handles.ident.h = zend_hash_func(new_value, HTTP_G->persistent.handles.ident.l = new_value_length+1);
247 return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
248 }
249 #endif
250
251 #ifndef ZEND_ENGINE_2
252 # define OnUpdateLong OnUpdateInt
253 #endif
254
255 PHP_INI_BEGIN()
256 HTTP_PHP_INI_ENTRY("http.etag.mode", "MD5", PHP_INI_ALL, OnUpdateString, etag.mode)
257 HTTP_PHP_INI_ENTRY("http.log.cache", "", PHP_INI_ALL, OnUpdateString, log.cache)
258 HTTP_PHP_INI_ENTRY("http.log.redirect", "", PHP_INI_ALL, OnUpdateString, log.redirect)
259 HTTP_PHP_INI_ENTRY("http.log.not_found", "", PHP_INI_ALL, OnUpdateString, log.not_found)
260 HTTP_PHP_INI_ENTRY("http.log.allowed_methods", "", PHP_INI_ALL, OnUpdateString, log.allowed_methods)
261 HTTP_PHP_INI_ENTRY("http.log.composite", "", PHP_INI_ALL, OnUpdateString, log.composite)
262 HTTP_PHP_INI_ENTRY("http.request.methods.allowed", "", PHP_INI_ALL, http_update_allowed_methods, request.methods.allowed)
263 HTTP_PHP_INI_ENTRY("http.request.methods.custom", "", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateString, request.methods.custom.ini)
264 #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
265 HTTP_PHP_INI_ENTRY("http.request.datashare.cookie", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.cookie)
266 HTTP_PHP_INI_ENTRY("http.request.datashare.dns", "1", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.dns)
267 HTTP_PHP_INI_ENTRY("http.request.datashare.ssl", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.ssl)
268 HTTP_PHP_INI_ENTRY("http.request.datashare.connect", "0", PHP_INI_SYSTEM, OnUpdateBool, request.datashare.connect)
269 #endif
270 #ifdef HTTP_HAVE_ZLIB
271 HTTP_PHP_INI_ENTRY("http.send.inflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.inflate.start_auto)
272 HTTP_PHP_INI_ENTRY("http.send.inflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.inflate.start_flags)
273 HTTP_PHP_INI_ENTRY("http.send.deflate.start_auto", "0", PHP_INI_PERDIR|PHP_INI_SYSTEM, OnUpdateBool, send.deflate.start_auto)
274 HTTP_PHP_INI_ENTRY("http.send.deflate.start_flags", "0", PHP_INI_ALL, OnUpdateLong, send.deflate.start_flags)
275 #endif
276 #ifdef HTTP_HAVE_PERSISTENT_HANDLES
277 HTTP_PHP_INI_ENTRY("http.persistent.handles.ident", "GLOBAL", PHP_INI_ALL, http_update_persistent_handle_ident, persistent.handles.ident.s)
278 #endif
279 HTTP_PHP_INI_ENTRY("http.send.not_found_404", "1", PHP_INI_ALL, OnUpdateBool, send.not_found_404)
280 #ifdef ZEND_ENGINE_2
281 HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions)
282 #endif
283 HTTP_PHP_INI_ENTRY("http.force_exit", "1", PHP_INI_ALL, OnUpdateBool, force_exit)
284 PHP_INI_END()
285 /* }}} */
286
287 /* {{{ PHP_MINIT_FUNCTION */
288 PHP_MINIT_FUNCTION(http)
289 {
290 http_module_number = module_number;
291
292 ZEND_INIT_MODULE_GLOBALS(http, http_globals_init_once, NULL)
293
294 REGISTER_INI_ENTRIES();
295
296 if ( (SUCCESS != PHP_MINIT_CALL(http_support)) ||
297 (SUCCESS != PHP_MINIT_CALL(http_cookie)) ||
298 (SUCCESS != PHP_MINIT_CALL(http_send)) ||
299 (SUCCESS != PHP_MINIT_CALL(http_url)) ||
300 #ifdef HTTP_HAVE_CURL
301 # ifdef HTTP_HAVE_PERSISTENT_HANDLES
302 (SUCCESS != PHP_MINIT_CALL(http_persistent_handle)) ||
303 # ifdef ZEND_ENGINE_2
304 (SUCCESS != PHP_MINIT_CALL(http_request_pool)) ||
305 # endif
306 # endif
307 (SUCCESS != PHP_MINIT_CALL(http_request)) ||
308 # ifdef ZEND_ENGINE_2
309 (SUCCESS != PHP_MINIT_CALL(http_request_datashare)) ||
310 # endif
311 #endif /* HTTP_HAVE_CURL */
312 #ifdef HTTP_HAVE_ZLIB
313 (SUCCESS != PHP_MINIT_CALL(http_encoding)) ||
314 #endif
315 (SUCCESS != PHP_MINIT_CALL(http_request_method))) {
316 return FAILURE;
317 }
318
319 #ifdef ZEND_ENGINE_2
320 if ( (SUCCESS != PHP_MINIT_CALL(http_filter)) ||
321 (SUCCESS != PHP_MINIT_CALL(http_util_object)) ||
322 (SUCCESS != PHP_MINIT_CALL(http_message_object)) ||
323 (SUCCESS != PHP_MINIT_CALL(http_querystring_object))||
324 # ifndef WONKY
325 (SUCCESS != PHP_MINIT_CALL(http_response_object)) ||
326 # endif /* WONKY */
327 # ifdef HTTP_HAVE_CURL
328 (SUCCESS != PHP_MINIT_CALL(http_request_object)) ||
329 (SUCCESS != PHP_MINIT_CALL(http_requestpool_object))||
330 (SUCCESS != PHP_MINIT_CALL(http_requestdatashare_object))||
331 # endif /* HTTP_HAVE_CURL */
332 # ifdef HTTP_HAVE_ZLIB
333 (SUCCESS != PHP_MINIT_CALL(http_deflatestream_object)) ||
334 (SUCCESS != PHP_MINIT_CALL(http_inflatestream_object)) ||
335 # endif /* HTTP_HAVE_ZLIB */
336 (SUCCESS != PHP_MINIT_CALL(http_exception_object))) {
337 return FAILURE;
338 }
339 #endif /* ZEND_ENGINE_2 */
340
341 return SUCCESS;
342 }
343 /* }}} */
344
345 /* {{{ PHP_MSHUTDOWN_FUNCTION */
346 PHP_MSHUTDOWN_FUNCTION(http)
347 {
348 UNREGISTER_INI_ENTRIES();
349 #ifdef HTTP_HAVE_CURL
350 if (
351 # ifdef ZEND_ENGINE_2
352 (SUCCESS != PHP_MSHUTDOWN_CALL(http_request_datashare)) ||
353 # endif
354 (SUCCESS != PHP_MSHUTDOWN_CALL(http_request))
355 # ifdef HTTP_HAVE_PERSISTENT_HANDLES
356 || (SUCCESS != PHP_MSHUTDOWN_CALL(http_persistent_handle))
357 # endif
358 ) {
359 return FAILURE;
360 }
361 #endif
362 return SUCCESS;
363 }
364 /* }}} */
365
366 /* {{{ PHP_RINIT_FUNCTION */
367 PHP_RINIT_FUNCTION(http)
368 {
369 http_globals_init(HTTP_G);
370
371 if (HTTP_G->request.methods.allowed) {
372 http_check_allowed_methods(HTTP_G->request.methods.allowed,
373 strlen(HTTP_G->request.methods.allowed));
374 }
375
376 if ( (SUCCESS != PHP_RINIT_CALL(http_request_method))
377 #ifdef HTTP_HAVE_ZLIB
378 || (SUCCESS != PHP_RINIT_CALL(http_encoding))
379 #endif
380 #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
381 || (SUCCESS != PHP_RINIT_CALL(http_request_datashare))
382 #endif
383 ) {
384 return FAILURE;
385 }
386
387 return SUCCESS;
388 }
389 /* }}} */
390
391 /* {{{ PHP_RSHUTDOWN_FUNCTION */
392 PHP_RSHUTDOWN_FUNCTION(http)
393 {
394 STATUS status = SUCCESS;
395
396 if ( (SUCCESS != PHP_RSHUTDOWN_CALL(http_request_method))
397 #ifdef HTTP_HAVE_ZLIB
398 || (SUCCESS != PHP_RSHUTDOWN_CALL(http_encoding))
399 #endif
400 #if defined(ZEND_ENGINE_2) && defined(HTTP_HAVE_CURL)
401 || (SUCCESS != PHP_RSHUTDOWN_CALL(http_request_datashare))
402 #endif
403 ) {
404 status = FAILURE;
405 }
406
407 http_globals_free(HTTP_G);
408 return status;
409 }
410 /* }}} */
411
412 /* {{{ PHP_MINFO_FUNCTION */
413 PHP_MINFO_FUNCTION(http)
414 {
415 php_info_print_table_start();
416 {
417 php_info_print_table_row(2, "HTTP Support", "enabled");
418 php_info_print_table_row(2, "Extension Version", PHP_EXT_HTTP_VERSION);
419 php_info_print_table_row(2, "Registered Classes",
420 #ifndef ZEND_ENGINE_2
421 "none"
422 #else
423 "HttpUtil, "
424 "HttpMessage, "
425 # ifdef HTTP_HAVE_CURL
426 "HttpRequest, "
427 "HttpRequestPool, "
428 "HttpRequestDataShare, "
429 # endif
430 # ifdef HTTP_HAVE_ZLIB
431 "HttpDeflateStream, "
432 "HttpInflateStream, "
433 # endif
434 # ifndef WONKY
435 "HttpResponse, "
436 # endif
437 "HttpQueryString"
438 #endif
439 );
440 php_info_print_table_row(2, "Output Handlers", "ob_deflatehandler, ob_inflatehandler, ob_etaghandler");
441 php_info_print_table_row(2, "Stream Filters",
442 #ifndef ZEND_ENGINE_2
443 "none"
444 #else
445 "http.chunked_decode, http.chunked_encode, http.deflate, http.inflate"
446 #endif
447 );
448 #ifdef HTTP_HAVE_PERSISTENT_HANDLES
449 {
450 phpstr s;
451 HashTable *ht;
452 HashPosition pos1, pos2;
453 HashKey key1 = initHashKey(0), key2 = initHashKey(0);
454 zval **val1, **val2;
455
456 if ((ht = http_persistent_handle_statall()) && zend_hash_num_elements(ht)) {
457 phpstr_init(&s);
458
459 FOREACH_HASH_KEYVAL(pos1, ht, key1, val1) {
460 phpstr_append(&s, key1.str, key1.len-1);
461 phpstr_appends(&s, " (");
462 if (zend_hash_num_elements(Z_ARRVAL_PP(val1))) {
463 FOREACH_KEYVAL(pos2, *val1, key2, val2) {
464 phpstr_append(&s, key2.str, key2.len-1);
465 phpstr_appendf(&s, ":%ld, ", Z_LVAL_PP(val2));
466 }
467 PHPSTR_LEN(&s) -= 2;
468 } else {
469 phpstr_appends(&s, "0");
470 }
471 phpstr_appends(&s, "), ");
472 }
473 zend_hash_destroy(ht);
474 FREE_HASHTABLE(ht);
475
476 PHPSTR_LEN(&s) -= 2; /* get rid of last ", " */
477 phpstr_fix(&s);
478
479 php_info_print_table_row(2, "Persistent Handles", PHPSTR_VAL(&s));
480 phpstr_dtor(&s);
481 } else {
482 php_info_print_table_row(2, "Persistent Handles", "none");
483 }
484 }
485 #else
486 php_info_print_table_row(2, "Persistent Handles", "disabled");
487 #endif
488 }
489 php_info_print_table_end();
490
491 php_info_print_table_start();
492 php_info_print_table_header(3, "Used Library", "Compiled", "Linked");
493 {
494 #ifdef HTTP_HAVE_CURL
495 curl_version_info_data *cv = curl_version_info(CURLVERSION_NOW);
496 php_info_print_table_row(3, "libcurl", LIBCURL_VERSION, cv->version);
497 #else
498 php_info_print_table_row(2, "libcurl", "disabled", "disabled");
499 #endif
500 #ifdef HTTP_HAVE_ZLIB
501 php_info_print_table_row(3, "libz", ZLIB_VERSION, zlibVersion());
502 #else
503 php_info_print_table_row(3, "libz", "disabled", "disabled");
504 #endif
505 #if defined(HTTP_HAVE_MAGIC)
506 php_info_print_table_row(3, "libmagic", "unknown", "unknown");
507 #else
508 php_info_print_table_row(3, "libmagic", "disabled", "disabled");
509 #endif
510 }
511 php_info_print_table_end();
512
513 php_info_print_table_start();
514 php_info_print_table_colspan_header(2, "Request Methods");
515 {
516 int i;
517 phpstr *custom_request_methods = phpstr_new();
518 phpstr *known_request_methods = phpstr_from_string(HTTP_KNOWN_METHODS, lenof(HTTP_KNOWN_METHODS));
519 http_request_method_entry **ptr = HTTP_G->request.methods.custom.entries;
520
521 for (i = 0; i < HTTP_G->request.methods.custom.count; ++i) {
522 if (ptr[i]) {
523 phpstr_appendf(custom_request_methods, "%s, ", ptr[i]->name);
524 }
525 }
526
527 phpstr_append(known_request_methods, PHPSTR_VAL(custom_request_methods), PHPSTR_LEN(custom_request_methods));
528 phpstr_fix(known_request_methods);
529 phpstr_fix(custom_request_methods);
530
531 php_info_print_table_row(2, "Known", PHPSTR_VAL(known_request_methods));
532 php_info_print_table_row(2, "Custom",
533 PHPSTR_LEN(custom_request_methods) ? PHPSTR_VAL(custom_request_methods) : "none registered");
534 php_info_print_table_row(2, "Allowed", strlen(HTTP_G->request.methods.allowed) ? HTTP_G->request.methods.allowed : "(ANY)");
535
536 phpstr_free(&known_request_methods);
537 phpstr_free(&custom_request_methods);
538 }
539 php_info_print_table_end();
540
541 DISPLAY_INI_ENTRIES();
542 }
543 /* }}} */
544
545 /*
546 * Local variables:
547 * tab-width: 4
548 * c-basic-offset: 4
549 * End:
550 * vim600: noet sw=4 ts=4 fdm=marker
551 * vim<600: noet sw=4 ts=4
552 */
553