You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2001 lines
56 KiB

18 years ago
18 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
22 years ago
19 years ago
19 years ago
19 years ago
19 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2008 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. | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
  16. | Stig Sther Bakken <ssb@php.net> |
  17. | David Sklar <sklar@student.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id$ */
  21. #include "php_apache_http.h"
  22. #if defined(PHP_WIN32) || defined(NETWARE)
  23. #include "zend.h"
  24. #include "ap_compat.h"
  25. #else
  26. #include <build-defs.h>
  27. #endif
  28. #ifdef ZTS
  29. int php_apache_info_id;
  30. #else
  31. php_apache_info_struct php_apache_info;
  32. #endif
  33. #define SECTION(name) PUTS("<H2 align=\"center\">" name "</H2>\n")
  34. #undef offsetof
  35. #define offsetof(s_type,field) ((size_t)&(((s_type*)0)->field))
  36. extern module *top_module;
  37. extern module **ap_loaded_modules;
  38. static int le_apachereq;
  39. static zend_class_entry *apacherequest_class_entry;
  40. static void apache_table_to_zval(table *, int safe_mode, zval *return_value);
  41. PHP_FUNCTION(virtual);
  42. PHP_FUNCTION(apache_request_headers);
  43. PHP_FUNCTION(apache_response_headers);
  44. PHP_FUNCTION(apachelog);
  45. PHP_FUNCTION(apache_note);
  46. PHP_FUNCTION(apache_lookup_uri);
  47. PHP_FUNCTION(apache_child_terminate);
  48. PHP_FUNCTION(apache_setenv);
  49. PHP_FUNCTION(apache_get_version);
  50. PHP_FUNCTION(apache_get_modules);
  51. PHP_MINFO_FUNCTION(apache);
  52. static
  53. ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_virtual, 0, 0, 1)
  54. ZEND_ARG_INFO(0, filename)
  55. ZEND_END_ARG_INFO()
  56. static
  57. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_request_headers, 0)
  58. ZEND_END_ARG_INFO()
  59. static
  60. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_response_headers, 0)
  61. ZEND_END_ARG_INFO()
  62. static
  63. ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_setenv, 0, 0, 2)
  64. ZEND_ARG_INFO(0, variable)
  65. ZEND_ARG_INFO(0, value)
  66. ZEND_ARG_INFO(0, walk_to_top)
  67. ZEND_END_ARG_INFO()
  68. static
  69. ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_lookup_uri, 0, 0, 1)
  70. ZEND_ARG_INFO(0, uri)
  71. ZEND_END_ARG_INFO()
  72. static
  73. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_get_version, 0)
  74. ZEND_END_ARG_INFO()
  75. static
  76. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_get_modules, 0)
  77. ZEND_END_ARG_INFO()
  78. static
  79. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_request_run, 0)
  80. ZEND_END_ARG_INFO()
  81. static
  82. ZEND_BEGIN_ARG_INFO(arginfo_apachehooks_child_terminate, 0)
  83. ZEND_END_ARG_INFO()
  84. static
  85. ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_note, 0, 0, 1)
  86. ZEND_ARG_INFO(0, note_name)
  87. ZEND_ARG_INFO(0, note_value)
  88. ZEND_END_ARG_INFO()
  89. const zend_function_entry apache_functions[] = {
  90. PHP_FE(virtual, arginfo_apachehooks_virtual)
  91. PHP_FE(apache_request_headers, arginfo_apachehooks_request_headers)
  92. PHP_FE(apache_note, arginfo_apachehooks_note)
  93. PHP_FE(apache_lookup_uri, arginfo_apachehooks_lookup_uri)
  94. PHP_FE(apache_child_terminate, arginfo_apachehooks_child_terminate)
  95. PHP_FE(apache_setenv, arginfo_apachehooks_setenv)
  96. PHP_FE(apache_response_headers, arginfo_apachehooks_response_headers)
  97. PHP_FE(apache_get_version, arginfo_apachehooks_get_version)
  98. PHP_FE(apache_get_modules, arginfo_apachehooks_get_modules)
  99. PHP_FALIAS(getallheaders, apache_request_headers, arginfo_apachehooks_request_headers)
  100. {NULL, NULL, NULL}
  101. };
  102. /* {{{ php_apache ini entries
  103. */
  104. PHP_INI_BEGIN()
  105. STD_PHP_INI_ENTRY("xbithack", "0", PHP_INI_ALL, OnUpdateLong, xbithack, php_apache_info_struct, php_apache_info)
  106. STD_PHP_INI_ENTRY("engine", "1", PHP_INI_ALL, OnUpdateLong, engine, php_apache_info_struct, php_apache_info)
  107. STD_PHP_INI_ENTRY("last_modified", "0", PHP_INI_ALL, OnUpdateLong, last_modified, php_apache_info_struct, php_apache_info)
  108. STD_PHP_INI_ENTRY("child_terminate", "0", PHP_INI_ALL, OnUpdateLong, terminate_child, php_apache_info_struct, php_apache_info)
  109. PHP_INI_END()
  110. /* }}} */
  111. static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC)
  112. {
  113. apache_globals->in_request = 0;
  114. }
  115. #define APREQ_GET_THIS(ZVAL) if (NULL == (ZVAL = getThis())) { \
  116. php_error(E_WARNING, "%s(): underlying ApacheRequest object missing", \
  117. get_active_function_name(TSRMLS_C)); \
  118. RETURN_FALSE; \
  119. }
  120. #define APREQ_GET_REQUEST(ZVAL, R) APREQ_GET_THIS(ZVAL); \
  121. R = get_apache_request(ZVAL TSRMLS_CC)
  122. static void php_apache_request_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  123. {
  124. zval *z = (zval *)rsrc->ptr;
  125. /* fprintf(stderr, "%s() %p\n", __FUNCTION__, z); */
  126. zval_ptr_dtor(&z);
  127. }
  128. static request_rec *get_apache_request(zval *z TSRMLS_DC)
  129. {
  130. request_rec *r;
  131. zval **addr;
  132. if (NULL == z) {
  133. php_error(E_WARNING, "get_apache_request() invalid wrapper passed");
  134. return NULL;
  135. }
  136. if (Z_TYPE_P(z) != IS_OBJECT) {
  137. php_error(E_WARNING, "%s(): wrapper is not an object", get_active_function_name(TSRMLS_C));
  138. return NULL;
  139. }
  140. if (zend_hash_index_find(Z_OBJPROP_P(z), 0, (void **)&addr) == FAILURE) {
  141. php_error(E_WARNING, "%s(): underlying object missing", get_active_function_name(TSRMLS_C));
  142. return NULL;
  143. }
  144. r = (request_rec *)Z_LVAL_PP(addr);
  145. if (!r) {
  146. php_error(E_WARNING, "%s(): request_rec invalid", get_active_function_name(TSRMLS_C));
  147. return NULL;
  148. }
  149. return r;
  150. }
  151. /* {{{ php_apache_request_new(request_rec *r)
  152. * create a new zval-instance for ApacheRequest that wraps request_rec
  153. */
  154. zval *php_apache_request_new(request_rec *r)
  155. {
  156. zval *req;
  157. zval *addr;
  158. TSRMLS_FETCH();
  159. MAKE_STD_ZVAL(addr);
  160. Z_TYPE_P(addr) = IS_LONG;
  161. Z_LVAL_P(addr) = (int) r;
  162. MAKE_STD_ZVAL(req);
  163. object_init_ex(req, apacherequest_class_entry);
  164. zend_hash_index_update(Z_OBJPROP_P(req), 0, &addr, sizeof(zval *), NULL);
  165. return req;
  166. }
  167. /* }}} */
  168. /* {{{ apache_request_read_string_slot()
  169. */
  170. static void apache_request_read_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  171. {
  172. zval *id;
  173. request_rec *r;
  174. char *s;
  175. if (zend_parse_parameters_none() == FAILURE) {
  176. return;
  177. }
  178. APREQ_GET_REQUEST(id, r);
  179. s = *(char **)((char*)r + offset);
  180. if (s)
  181. RETURN_STRING(s, 1);
  182. RETURN_EMPTY_STRING();
  183. }
  184. /* }}} */
  185. /* {{{ apache_request_string_slot()
  186. */
  187. static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  188. {
  189. zval *id, **new_value;
  190. request_rec *r;
  191. char *old_value;
  192. char **target;
  193. APREQ_GET_REQUEST(id, r);
  194. target = (char **)((char*)r + offset);
  195. old_value = *target;
  196. switch (ZEND_NUM_ARGS()) {
  197. case 0:
  198. break;
  199. case 1:
  200. if (zend_get_parameters_ex(1, &new_value) == FAILURE) {
  201. RETURN_FALSE;
  202. }
  203. convert_to_string_ex(new_value);
  204. *target = ap_pstrdup(r->pool, Z_STRVAL_PP(new_value));
  205. break;
  206. default:
  207. WRONG_PARAM_COUNT;
  208. break;
  209. }
  210. if (old_value)
  211. RETURN_STRING(old_value, 1);
  212. RETURN_EMPTY_STRING();
  213. }
  214. /* }}} */
  215. /* {{{ apache_request_read_int_slot()
  216. */
  217. static void apache_request_read_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  218. {
  219. zval *id;
  220. request_rec *r;
  221. long l;
  222. if (zend_parse_parameters_none() == FAILURE) {
  223. return;
  224. }
  225. APREQ_GET_REQUEST(id, r);
  226. l = *(long *)((char*)r + offset);
  227. RETURN_LONG(l);
  228. }
  229. /* }}} */
  230. /* {{{ apache_request_int_slot()
  231. */
  232. static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  233. {
  234. zval *id, **new_value;
  235. request_rec *r;
  236. long old_value;
  237. long *target;
  238. APREQ_GET_REQUEST(id, r);
  239. target = (long *)((char*)r + offset);
  240. old_value = *target;
  241. switch (ZEND_NUM_ARGS()) {
  242. case 0:
  243. break;
  244. case 1:
  245. if (zend_get_parameters_ex(1, &new_value) == FAILURE) {
  246. RETURN_FALSE;
  247. }
  248. convert_to_long_ex(new_value);
  249. *target = Z_LVAL_PP(new_value);
  250. break;
  251. default:
  252. WRONG_PARAM_COUNT;
  253. break;
  254. }
  255. RETURN_LONG(old_value);
  256. }
  257. /* }}} */
  258. /* {{{ access string slots of request rec
  259. */
  260. /* {{{ proto string ApacheRequest::filename([string new_filename])
  261. */
  262. PHP_FUNCTION(apache_request_filename)
  263. {
  264. apache_request_string_slot(offsetof(request_rec, filename), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  265. }
  266. /* }}} */
  267. /* {{{ proto string ApacheRequest::uri([string new_uri])
  268. */
  269. PHP_FUNCTION(apache_request_uri)
  270. {
  271. apache_request_string_slot(offsetof(request_rec, uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  272. }
  273. /* }}} */
  274. /* {{{ proto string ApacheRequest::unparsed_uri([string new_unparsed_uri])
  275. */
  276. PHP_FUNCTION(apache_request_unparsed_uri)
  277. {
  278. apache_request_string_slot(offsetof(request_rec, unparsed_uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  279. }
  280. /* }}} */
  281. /* {{{ proto string ApacheRequest::path_info([string new_path_info])
  282. */
  283. PHP_FUNCTION(apache_request_path_info)
  284. {
  285. apache_request_string_slot(offsetof(request_rec, path_info), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  286. }
  287. /* }}} */
  288. /* {{{ proto string ApacheRequest::args([string new_args])
  289. */
  290. PHP_FUNCTION(apache_request_args)
  291. {
  292. apache_request_string_slot(offsetof(request_rec, args), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  293. }
  294. /* }}} */
  295. /* {{{ proto string ApacheRequest::boundary()
  296. */
  297. PHP_FUNCTION(apache_request_boundary)
  298. {
  299. apache_request_read_string_slot(offsetof(request_rec, boundary), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  300. }
  301. /* }}} */
  302. /* {{{ proto string ApacheRequest::content_type([string new_type])
  303. */
  304. PHP_FUNCTION(apache_request_content_type)
  305. {
  306. apache_request_string_slot(offsetof(request_rec, content_type), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  307. }
  308. /* }}} */
  309. /* {{{ proto string ApacheRequest::content_encoding([string new_encoding])
  310. */
  311. PHP_FUNCTION(apache_request_content_encoding)
  312. {
  313. apache_request_string_slot(offsetof(request_rec, content_encoding), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  314. }
  315. /* }}} */
  316. /* {{{ proto string ApacheRequest::handler([string new_handler])
  317. */
  318. PHP_FUNCTION(apache_request_handler)
  319. {
  320. apache_request_string_slot(offsetof(request_rec, handler), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  321. }
  322. /* }}} */
  323. /* {{{ proto string ApacheRequest::the_request()
  324. */
  325. PHP_FUNCTION(apache_request_the_request)
  326. {
  327. apache_request_read_string_slot(offsetof(request_rec, the_request), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  328. }
  329. /* }}} */
  330. /* {{{ proto string ApacheRequest::protocol()
  331. */
  332. PHP_FUNCTION(apache_request_protocol)
  333. {
  334. apache_request_read_string_slot(offsetof(request_rec, protocol), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  335. }
  336. /* }}} */
  337. /* {{{ proto string ApacheRequest::hostname()
  338. */
  339. PHP_FUNCTION(apache_request_hostname)
  340. {
  341. apache_request_read_string_slot(offsetof(request_rec, hostname), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  342. }
  343. /* }}} */
  344. /* {{{ proto string ApacheRequest::status_line([string new_status_line])
  345. */
  346. PHP_FUNCTION(apache_request_status_line)
  347. {
  348. apache_request_string_slot(offsetof(request_rec, status_line), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  349. }
  350. /* }}} */
  351. /* {{{ proto string ApacheRequest::method()
  352. */
  353. PHP_FUNCTION(apache_request_method)
  354. {
  355. apache_request_read_string_slot(offsetof(request_rec, method), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  356. }
  357. /* }}} */
  358. /* }}} access string slots of request rec */
  359. /* {{{ access int slots of request_rec
  360. */
  361. /* {{{ proto int ApacheRequest::proto_num()
  362. */
  363. PHP_FUNCTION(apache_request_proto_num)
  364. {
  365. apache_request_read_int_slot(offsetof(request_rec, proto_num), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  366. }
  367. /* }}} */
  368. /* {{{ proto int ApacheRequest::assbackwards()
  369. */
  370. PHP_FUNCTION(apache_request_assbackwards)
  371. {
  372. apache_request_read_int_slot(offsetof(request_rec, assbackwards), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  373. }
  374. /* }}} */
  375. /* {{{ proto int ApacheRequest::proxyreq([int new_proxyreq])
  376. */
  377. PHP_FUNCTION(apache_request_proxyreq)
  378. {
  379. apache_request_int_slot(offsetof(request_rec, proxyreq), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  380. }
  381. /* }}} */
  382. /* {{{ proto int ApacheRequest::chunked()
  383. */
  384. PHP_FUNCTION(apache_request_chunked)
  385. {
  386. apache_request_read_int_slot(offsetof(request_rec, chunked), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  387. }
  388. /* }}} */
  389. /* {{{ proto int ApacheRequest::header_only()
  390. */
  391. PHP_FUNCTION(apache_request_header_only)
  392. {
  393. apache_request_read_int_slot(offsetof(request_rec, header_only), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  394. }
  395. /* }}} */
  396. /* {{{ proto int ApacheRequest::request_time()
  397. */
  398. PHP_FUNCTION(apache_request_request_time)
  399. {
  400. apache_request_read_int_slot(offsetof(request_rec, request_time), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  401. }
  402. /* }}} */
  403. /* {{{ proto int ApacheRequest::status([int new_status])
  404. */
  405. PHP_FUNCTION(apache_request_status)
  406. {
  407. apache_request_int_slot(offsetof(request_rec, status), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  408. }
  409. /* }}} */
  410. /* {{{ proto int ApacheRequest::method_number([int method_number])
  411. */
  412. PHP_FUNCTION(apache_request_method_number)
  413. {
  414. apache_request_read_int_slot(offsetof(request_rec, method_number), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  415. }
  416. /* }}} */
  417. /* {{{ proto int ApacheRequest::allowed([int allowed])
  418. */
  419. PHP_FUNCTION(apache_request_allowed)
  420. {
  421. apache_request_int_slot(offsetof(request_rec, allowed), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  422. }
  423. /* }}} */
  424. /* {{{ proto int ApacheRequest::bytes_sent()
  425. */
  426. PHP_FUNCTION(apache_request_bytes_sent)
  427. {
  428. apache_request_read_int_slot(offsetof(request_rec, bytes_sent), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  429. }
  430. /* }}} */
  431. /* {{{ proto int ApacheRequest::mtime()
  432. */
  433. PHP_FUNCTION(apache_request_mtime)
  434. {
  435. apache_request_read_int_slot(offsetof(request_rec, mtime), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  436. }
  437. /* }}} */
  438. /* {{{ proto int ApacheRequest::content_length([int new_content_length])
  439. */
  440. PHP_FUNCTION(apache_request_content_length)
  441. {
  442. zval *id, **zlen;
  443. request_rec *r;
  444. if (ZEND_NUM_ARGS() == 0) {
  445. apache_request_read_int_slot(offsetof(request_rec, clength), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  446. }
  447. else if (ZEND_NUM_ARGS() > 1) {
  448. WRONG_PARAM_COUNT;
  449. }
  450. else {
  451. if (zend_get_parameters_ex(1, &zlen) == FAILURE) {
  452. RETURN_FALSE;
  453. }
  454. APREQ_GET_REQUEST(id, r);
  455. convert_to_long_ex(zlen);
  456. (void)ap_set_content_length(r, Z_LVAL_PP(zlen));
  457. RETURN_TRUE;
  458. }
  459. }
  460. /* }}} */
  461. /* {{{ proto int ApacheRequest::remaining()
  462. */
  463. PHP_FUNCTION(apache_request_remaining)
  464. {
  465. apache_request_read_int_slot(offsetof(request_rec, remaining), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  466. }
  467. /* }}} */
  468. /* {{{ proto int ApacheRequest::no_cache()
  469. */
  470. PHP_FUNCTION(apache_request_no_cache)
  471. {
  472. apache_request_int_slot(offsetof(request_rec, no_cache), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  473. }
  474. /* }}} */
  475. /* {{{ proto int ApacheRequest::no_local_copy()
  476. */
  477. PHP_FUNCTION(apache_request_no_local_copy)
  478. {
  479. apache_request_int_slot(offsetof(request_rec, no_local_copy), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  480. }
  481. /* }}} */
  482. /* {{{ proto int ApacheRequest::read_body()
  483. */
  484. PHP_FUNCTION(apache_request_read_body)
  485. {
  486. apache_request_int_slot(offsetof(request_rec, read_body), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  487. }
  488. /* }}} */
  489. /* }}} access int slots of request_rec */
  490. /* {{{ proto array apache_request_headers_in()
  491. * fetch all incoming request headers
  492. */
  493. PHP_FUNCTION(apache_request_headers_in)
  494. {
  495. zval *id;
  496. request_rec *r;
  497. APREQ_GET_REQUEST(id, r);
  498. apache_table_to_zval(r->headers_in, 0, return_value);
  499. }
  500. /* }}} */
  501. /* {{{ add_header_to_table
  502. */
  503. static void add_header_to_table(table *t, INTERNAL_FUNCTION_PARAMETERS)
  504. {
  505. zval *first = NULL;
  506. zval *second = NULL;
  507. zval **entry, **value;
  508. char *string_key;
  509. uint string_key_len;
  510. ulong num_key;
  511. zend_bool replace = 0;
  512. HashPosition pos;
  513. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zb", &first, &second, &replace) == FAILURE)
  514. RETURN_FALSE;
  515. if (Z_TYPE_P(first) == IS_ARRAY) {
  516. switch(ZEND_NUM_ARGS()) {
  517. case 1:
  518. case 3:
  519. zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(first), &pos);
  520. while (zend_hash_get_current_data_ex(Z_ARRVAL_P(first), (void **)&entry, &pos) == SUCCESS) {
  521. switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(first), &string_key, &string_key_len, &num_key, 0, &pos)) {
  522. case HASH_KEY_IS_STRING:
  523. if (zend_hash_find(Z_ARRVAL_P(first), string_key, string_key_len, (void **)&value) == FAILURE) {
  524. zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  525. continue;
  526. }
  527. if (!value) {
  528. zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  529. continue;
  530. }
  531. convert_to_string_ex(value);
  532. if (replace)
  533. ap_table_set(t, string_key, Z_STRVAL_PP(value));
  534. else
  535. ap_table_merge(t, string_key, Z_STRVAL_PP(value));
  536. break;
  537. case HASH_KEY_IS_LONG:
  538. default:
  539. php_error(E_WARNING, "%s(): Can only add STRING keys to headers!", get_active_function_name(TSRMLS_C));
  540. break;
  541. }
  542. zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  543. }
  544. break;
  545. default:
  546. WRONG_PARAM_COUNT;
  547. break;
  548. }
  549. }
  550. else if (Z_TYPE_P(first) == IS_STRING) {
  551. switch(ZEND_NUM_ARGS()) {
  552. case 2:
  553. case 3:
  554. convert_to_string_ex(&second);
  555. if (replace)
  556. ap_table_set(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
  557. else
  558. ap_table_merge(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
  559. break;
  560. default:
  561. WRONG_PARAM_COUNT;
  562. break;
  563. }
  564. }
  565. else {
  566. RETURN_FALSE;
  567. }
  568. }
  569. /* }}} */
  570. /* {{{ proto array apache_request_headers_out([{string name|array list} [, string value [, bool replace = false]]])
  571. * fetch all outgoing request headers
  572. */
  573. PHP_FUNCTION(apache_request_headers_out)
  574. {
  575. zval *id;
  576. request_rec *r;
  577. APREQ_GET_REQUEST(id, r);
  578. if (ZEND_NUM_ARGS() > 0)
  579. add_header_to_table(r->headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  580. apache_table_to_zval(r->headers_out, 0, return_value);
  581. }
  582. /* }}} */
  583. /* {{{ proto array apache_request_err_headers_out([{string name|array list} [, string value [, bool replace = false]]])
  584. * fetch all headers that go out in case of an error or a subrequest
  585. */
  586. PHP_FUNCTION(apache_request_err_headers_out)
  587. {
  588. zval *id;
  589. request_rec *r;
  590. APREQ_GET_REQUEST(id, r);
  591. if (ZEND_NUM_ARGS() > 0)
  592. add_header_to_table(r->err_headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  593. apache_table_to_zval(r->err_headers_out, 0, return_value);
  594. }
  595. /* }}} */
  596. /* {{{ proxy functions for the ap_* functions family
  597. */
  598. /* {{{ proto int apache_request_server_port()
  599. */
  600. PHP_FUNCTION(apache_request_server_port)
  601. {
  602. zval *id;
  603. request_rec *r;
  604. if (zend_parse_parameters_none() == FAILURE) {
  605. return;
  606. }
  607. APREQ_GET_REQUEST(id, r);
  608. RETURN_LONG(ap_get_server_port(r));
  609. }
  610. /* }}} */
  611. /* {{{ proto int apache_request_remote_host([int type])
  612. */
  613. PHP_FUNCTION(apache_request_remote_host)
  614. {
  615. zval *id, **ztype;
  616. request_rec *r;
  617. char *res;
  618. int type = REMOTE_NAME;
  619. switch (ZEND_NUM_ARGS()) {
  620. case 0:
  621. break;
  622. case 1:
  623. if (zend_get_parameters_ex(1, &ztype) == FAILURE) {
  624. RETURN_FALSE;
  625. }
  626. convert_to_long_ex(ztype);
  627. type = Z_LVAL_PP(ztype);
  628. break;
  629. default:
  630. WRONG_PARAM_COUNT;
  631. break;
  632. }
  633. APREQ_GET_REQUEST(id, r);
  634. res = (char *)ap_get_remote_host(r->connection, r->per_dir_config, type);
  635. if (res)
  636. RETURN_STRING(res, 1);
  637. RETURN_EMPTY_STRING();
  638. }
  639. /* }}} */
  640. /* {{{ proto long apache_request_update_mtime([int dependency_mtime])
  641. */
  642. PHP_FUNCTION(apache_request_update_mtime)
  643. {
  644. zval *id, **zmtime;
  645. request_rec *r;
  646. int mtime = 0;
  647. switch (ZEND_NUM_ARGS()) {
  648. case 0:
  649. break;
  650. case 1:
  651. if (zend_get_parameters_ex(1, &zmtime) == FAILURE) {
  652. RETURN_FALSE;
  653. }
  654. convert_to_long_ex(zmtime);
  655. mtime = Z_LVAL_PP(zmtime);
  656. break;
  657. default:
  658. WRONG_PARAM_COUNT;
  659. break;
  660. }
  661. APREQ_GET_REQUEST(id, r);
  662. RETURN_LONG(ap_update_mtime(r, mtime));
  663. }
  664. /* }}} */
  665. /* {{{ proto void apache_request_set_etag()
  666. */
  667. PHP_FUNCTION(apache_request_set_etag)
  668. {
  669. zval *id;
  670. request_rec *r;
  671. if (zend_parse_parameters_none() == FAILURE) {
  672. return;
  673. }
  674. APREQ_GET_REQUEST(id, r);
  675. ap_set_etag(r);
  676. RETURN_TRUE;
  677. }
  678. /* }}} */
  679. /* {{{ proto void apache_request_set_last_modified()
  680. */
  681. PHP_FUNCTION(apache_request_set_last_modified)
  682. {
  683. zval *id;
  684. request_rec *r;
  685. if (zend_parse_parameters_none() == FAILURE) {
  686. return;
  687. }
  688. APREQ_GET_REQUEST(id, r);
  689. ap_set_last_modified(r);
  690. RETURN_TRUE;
  691. }
  692. /* }}} */
  693. /* {{{ proto long apache_request_meets_conditions()
  694. */
  695. PHP_FUNCTION(apache_request_meets_conditions)
  696. {
  697. zval *id;
  698. request_rec *r;
  699. if (zend_parse_parameters_none() == FAILURE) {
  700. return;
  701. }
  702. APREQ_GET_REQUEST(id, r);
  703. RETURN_LONG(ap_meets_conditions(r));
  704. }
  705. /* }}} */
  706. /* {{{ proto long apache_request_discard_request_body()
  707. */
  708. PHP_FUNCTION(apache_request_discard_request_body)
  709. {
  710. zval *id;
  711. request_rec *r;
  712. if (zend_parse_parameters_none() == FAILURE) {
  713. return;
  714. }
  715. APREQ_GET_REQUEST(id, r);
  716. RETURN_LONG(ap_discard_request_body(r));
  717. }
  718. /* }}} */
  719. /* {{{ proto long apache_request_satisfies()
  720. */
  721. PHP_FUNCTION(apache_request_satisfies)
  722. {
  723. zval *id;
  724. request_rec *r;
  725. if (zend_parse_parameters_none() == FAILURE) {
  726. return;
  727. }
  728. APREQ_GET_REQUEST(id, r);
  729. RETURN_LONG(ap_satisfies(r));
  730. }
  731. /* }}} */
  732. /* {{{ proto bool apache_request_is_initial_req()
  733. */
  734. PHP_FUNCTION(apache_request_is_initial_req)
  735. {
  736. zval *id;
  737. request_rec *r;
  738. if (zend_parse_parameters_none() == FAILURE) {
  739. return;
  740. }
  741. APREQ_GET_REQUEST(id, r);
  742. RETURN_BOOL(ap_is_initial_req(r));
  743. }
  744. /* }}} */
  745. /* {{{ proto bool apache_request_some_auth_required()
  746. */
  747. PHP_FUNCTION(apache_request_some_auth_required)
  748. {
  749. zval *id;
  750. request_rec *r;
  751. if (zend_parse_parameters_none() == FAILURE) {
  752. return;
  753. }
  754. APREQ_GET_REQUEST(id, r);
  755. RETURN_BOOL(ap_some_auth_required(r));
  756. }
  757. /* }}} */
  758. /* {{{ proto string apache_request_auth_type()
  759. */
  760. PHP_FUNCTION(apache_request_auth_type)
  761. {
  762. zval *id;
  763. request_rec *r;
  764. char *t;
  765. if (zend_parse_parameters_none() == FAILURE) {
  766. return;
  767. }
  768. APREQ_GET_REQUEST(id, r);
  769. t = (char *)ap_auth_type(r);
  770. if (!t)
  771. RETURN_NULL();
  772. RETURN_STRING(t, 1);
  773. }
  774. /* }}} */
  775. /* {{{ proto string apache_request_auth_name()
  776. */
  777. PHP_FUNCTION(apache_request_auth_name)
  778. {
  779. zval *id;
  780. request_rec *r;
  781. char *t;
  782. if (zend_parse_parameters_none() == FAILURE) {
  783. return;
  784. }
  785. APREQ_GET_REQUEST(id, r);
  786. t = (char *)ap_auth_name(r);
  787. if (!t)
  788. RETURN_NULL();
  789. RETURN_STRING(t, 1);
  790. }
  791. /* }}} */
  792. /* {{{ proto apache_request_basic_auth_pw()
  793. */
  794. PHP_FUNCTION(apache_request_basic_auth_pw)
  795. {
  796. zval *id, *zpw;
  797. request_rec *r;
  798. const char *pw;
  799. long status;
  800. if (ZEND_NUM_ARGS() != 1) {
  801. WRONG_PARAM_COUNT;
  802. }
  803. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zpw) == FAILURE) {
  804. RETURN_NULL();
  805. }
  806. if (!PZVAL_IS_REF(zpw)) {
  807. zend_error(E_WARNING, "Parameter wasn't passed by reference");
  808. RETURN_NULL();
  809. }
  810. APREQ_GET_REQUEST(id, r);
  811. pw = NULL;
  812. status = ap_get_basic_auth_pw(r, &pw);
  813. if (status == OK && pw) {
  814. ZVAL_STRING(zpw, (char *)pw, 1);
  815. }
  816. else
  817. ZVAL_NULL(zpw);
  818. RETURN_LONG(status);
  819. }
  820. /* }}} */
  821. /* http_protocol.h */
  822. PHP_FUNCTION(apache_request_send_http_header)
  823. {
  824. zval *id;
  825. request_rec *r;
  826. char *type = NULL;
  827. int typelen;
  828. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &type, &typelen) == FAILURE)
  829. return;
  830. APREQ_GET_REQUEST(id, r);
  831. if(type) {
  832. r->content_type = pstrdup(r->pool, type);
  833. }
  834. ap_send_http_header(r);
  835. SG(headers_sent) = 1;
  836. AP(headers_sent) = 1;
  837. RETURN_TRUE;
  838. }
  839. PHP_FUNCTION(apache_request_basic_http_header)
  840. {
  841. zval *id;
  842. request_rec *r;
  843. APREQ_GET_REQUEST(id, r);
  844. ap_basic_http_header((request_rec *)SG(server_context));
  845. SG(headers_sent) = 1;
  846. AP(headers_sent) = 1;
  847. RETURN_TRUE;
  848. }
  849. PHP_FUNCTION(apache_request_send_http_trace)
  850. {
  851. zval *id;
  852. request_rec *r;
  853. APREQ_GET_REQUEST(id, r);
  854. ap_send_http_trace((request_rec *)SG(server_context));
  855. SG(headers_sent) = 1;
  856. AP(headers_sent) = 1;
  857. RETURN_TRUE;
  858. }
  859. PHP_FUNCTION(apache_request_send_http_options)
  860. {
  861. zval *id;
  862. request_rec *r;
  863. APREQ_GET_REQUEST(id, r);
  864. ap_send_http_options((request_rec *)SG(server_context));
  865. SG(headers_sent) = 1;
  866. AP(headers_sent) = 1;
  867. RETURN_TRUE;
  868. }
  869. PHP_FUNCTION(apache_request_send_error_response)
  870. {
  871. zval **recursive;
  872. zval *id;
  873. request_rec *r;
  874. int rec;
  875. switch(ZEND_NUM_ARGS()) {
  876. case 0:
  877. rec = 0;
  878. break;
  879. case 1:
  880. if(zend_get_parameters_ex(1, &recursive) == FAILURE) {
  881. RETURN_FALSE;
  882. }
  883. convert_to_long_ex(recursive);
  884. rec = Z_LVAL_PP(recursive);
  885. break;
  886. default:
  887. WRONG_PARAM_COUNT;
  888. }
  889. APREQ_GET_REQUEST(id, r);
  890. ap_send_error_response(r, rec);
  891. RETURN_TRUE;
  892. }
  893. PHP_FUNCTION(apache_request_set_content_length)
  894. {
  895. zval **length;
  896. zval *id;
  897. request_rec *r;
  898. if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &length) == FAILURE) {
  899. WRONG_PARAM_COUNT;
  900. }
  901. APREQ_GET_REQUEST(id, r);
  902. convert_to_long_ex(length);
  903. ap_set_content_length(r, Z_LVAL_PP(length));
  904. RETURN_TRUE;
  905. }
  906. PHP_FUNCTION(apache_request_set_keepalive)
  907. {
  908. zval *id;
  909. request_rec *r;
  910. APREQ_GET_REQUEST(id, r);
  911. ap_set_keepalive(r);
  912. RETURN_TRUE;
  913. }
  914. /* This stuff should use streams or however this is implemented now
  915. PHP_FUNCTION(apache_request_send_fd)
  916. {
  917. }
  918. PHP_FUNCTION(apache_request_send_fd_length)
  919. {
  920. }
  921. */
  922. /* These are for overriding default output behaviour */
  923. PHP_FUNCTION(apache_request_rputs)
  924. {
  925. zval **buffer;
  926. zval *id;
  927. request_rec *r;
  928. if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &buffer) == FAILURE) {
  929. WRONG_PARAM_COUNT;
  930. }
  931. APREQ_GET_REQUEST(id, r);
  932. convert_to_string_ex(buffer);
  933. ap_rwrite(Z_STRVAL_PP(buffer), Z_STRLEN_PP(buffer), (request_rec*)SG(server_context));
  934. }
  935. /* This stuff would be useful for custom POST handlers,
  936. which should be supported. Probably by not using
  937. sapi_activate at all inside a phpResponseHandler
  938. and instead using a builtin composed of the below
  939. calls as a apache_read_request_body() and allow
  940. people to custom craft their own.
  941. PHP_FUNCTION(apache_request_setup_client_block)
  942. {
  943. }
  944. PHP_FUNCTION(apache_request_should_client_block)
  945. {
  946. }
  947. PHP_FUNCTION(apache_request_get_client_block)
  948. {
  949. }
  950. PHP_FUNCTION(apache_request_discard_request_body)
  951. {
  952. }
  953. */
  954. /* http_log.h */
  955. /* {{{ proto boolean apache_request_log_error(string message, [long facility])
  956. */
  957. PHP_FUNCTION(apache_request_log_error)
  958. {
  959. zval *id;
  960. zval **z_errstr, **z_facility;
  961. request_rec *r;
  962. int facility = APLOG_ERR;
  963. switch(ZEND_NUM_ARGS()) {
  964. case 1:
  965. if(zend_get_parameters_ex(1, &z_errstr) == FAILURE) {
  966. RETURN_FALSE;
  967. }
  968. break;
  969. case 2:
  970. if(zend_get_parameters_ex(1, &z_errstr, &z_facility) == FAILURE) {
  971. RETURN_FALSE;
  972. }
  973. convert_to_long_ex(z_facility);
  974. facility = Z_LVAL_PP(z_facility);
  975. break;
  976. default:
  977. WRONG_PARAM_COUNT;
  978. break;
  979. }
  980. APREQ_GET_REQUEST(id, r);
  981. convert_to_string_ex(z_errstr);
  982. ap_log_error(APLOG_MARK, facility, r->server, "%s", Z_STRVAL_PP(z_errstr));
  983. RETURN_TRUE;
  984. }
  985. /* }}} */
  986. /* http_main.h */
  987. /* {{{ proto object apache_request_sub_req_lookup_uri(string uri)
  988. Returns sub-request for the specified uri. You would
  989. need to run it yourself with run()
  990. */
  991. PHP_FUNCTION(apache_request_sub_req_lookup_uri)
  992. {
  993. zval *id;
  994. zval **file;
  995. request_rec *r, *sub_r;
  996. if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) {
  997. WRONG_PARAM_COUNT;
  998. }
  999. APREQ_GET_REQUEST(id, r);
  1000. convert_to_string_ex(file);
  1001. sub_r = ap_sub_req_lookup_uri(Z_STRVAL_PP(file), r);
  1002. if(!sub_r) {
  1003. RETURN_FALSE;
  1004. }
  1005. return_value = php_apache_request_new(sub_r);
  1006. }
  1007. /* }}} */
  1008. /* {{{ proto object apache_request_sub_req_lookup_file(string file)
  1009. Returns sub-request for the specified file. You would
  1010. need to run it yourself with run().
  1011. */
  1012. PHP_FUNCTION(apache_request_sub_req_lookup_file)
  1013. {
  1014. zval *id;
  1015. zval **file;
  1016. request_rec *r, *sub_r;
  1017. if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &file) == FAILURE) {
  1018. WRONG_PARAM_COUNT;
  1019. }
  1020. APREQ_GET_REQUEST(id, r);
  1021. convert_to_string_ex(file);
  1022. sub_r = ap_sub_req_lookup_file(Z_STRVAL_PP(file), r);
  1023. if(!sub_r) {
  1024. RETURN_FALSE;
  1025. }
  1026. return_value = php_apache_request_new(sub_r);
  1027. }
  1028. /* }}} */
  1029. /* {{{ proto object apache_request_sub_req_method_uri(string method, string uri)
  1030. Returns sub-request for the specified file. You would
  1031. need to run it yourself with run().
  1032. */
  1033. PHP_FUNCTION(apache_request_sub_req_method_uri)
  1034. {
  1035. zval *id;
  1036. zval **file, **method;
  1037. request_rec *r, *sub_r;
  1038. if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &method, &file) == FAILURE) {
  1039. WRONG_PARAM_COUNT;
  1040. }
  1041. APREQ_GET_REQUEST(id, r);
  1042. convert_to_string_ex(method);
  1043. convert_to_string_ex(file);
  1044. sub_r = ap_sub_req_method_uri(Z_STRVAL_PP(method),Z_STRVAL_PP(file), r);
  1045. if(!sub_r) {
  1046. RETURN_FALSE;
  1047. }
  1048. return_value = php_apache_request_new(sub_r);
  1049. }
  1050. /* }}} */
  1051. /* {{{ proto long apache_request_run()
  1052. This is a wrapper for ap_sub_run_req and ap_destory_sub_req. It takes
  1053. sub_request, runs it, destroys it, and returns it's status.
  1054. */
  1055. PHP_FUNCTION(apache_request_run)
  1056. {
  1057. zval *id;
  1058. request_rec *r;
  1059. int status;
  1060. APREQ_GET_REQUEST(id, r);
  1061. if(!r || ap_is_initial_req(r))
  1062. RETURN_FALSE;
  1063. status = ap_run_sub_req(r);
  1064. ap_destroy_sub_req(r);
  1065. RETURN_LONG(status);
  1066. }
  1067. /* }}} */
  1068. PHP_FUNCTION(apache_request_internal_redirect)
  1069. {
  1070. zval *id;
  1071. zval **new_uri;
  1072. request_rec *r;
  1073. if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &new_uri) == FAILURE) {
  1074. WRONG_PARAM_COUNT;
  1075. }
  1076. APREQ_GET_REQUEST(id, r);
  1077. convert_to_string_ex(new_uri);
  1078. ap_internal_redirect(Z_STRVAL_PP(new_uri), r);
  1079. }
  1080. PHP_FUNCTION(apache_request_send_header_field)
  1081. {
  1082. zval **fieldname;
  1083. zval **fieldval;
  1084. zval *id;
  1085. request_rec *r;
  1086. if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &fieldname, &fieldval) == FAILURE) {
  1087. WRONG_PARAM_COUNT;
  1088. }
  1089. convert_to_string_ex(fieldname);
  1090. convert_to_string_ex(fieldval);
  1091. APREQ_GET_REQUEST(id, r);
  1092. ap_send_header_field(r, Z_STRVAL_PP(fieldname), Z_STRVAL_PP(fieldval));
  1093. SG(headers_sent) = 1;
  1094. AP(headers_sent) = 1;
  1095. }
  1096. /* }}} */
  1097. /* {{{ php_apache_request_class_functions
  1098. */
  1099. const static zend_function_entry php_apache_request_class_functions[] = {
  1100. /* string slots */
  1101. PHP_FALIAS(args, apache_request_args, NULL)
  1102. PHP_FALIAS(boundary, apache_request_boundary, NULL)
  1103. PHP_FALIAS(content_encoding, apache_request_content_encoding, NULL)
  1104. PHP_FALIAS(content_type, apache_request_content_type, NULL)
  1105. PHP_FALIAS(filename, apache_request_filename, NULL)
  1106. PHP_FALIAS(handler, apache_request_handler, NULL)
  1107. PHP_FALIAS(hostname, apache_request_hostname, NULL)
  1108. PHP_FALIAS(method, apache_request_method, NULL)
  1109. PHP_FALIAS(path_info, apache_request_path_info, NULL)
  1110. PHP_FALIAS(protocol, apache_request_protocol, NULL)
  1111. PHP_FALIAS(status_line, apache_request_status_line, NULL)
  1112. PHP_FALIAS(the_request, apache_request_the_request, NULL)
  1113. PHP_FALIAS(unparsed_uri, apache_request_unparsed_uri, NULL)
  1114. PHP_FALIAS(uri, apache_request_uri, NULL)
  1115. /* int slots */
  1116. PHP_FALIAS(allowed, apache_request_allowed, NULL)
  1117. PHP_FALIAS(bytes_sent, apache_request_bytes_sent, NULL)
  1118. PHP_FALIAS(chunked, apache_request_chunked, NULL)
  1119. PHP_FALIAS(content_length, apache_request_content_length, NULL)
  1120. PHP_FALIAS(header_only, apache_request_header_only, NULL)
  1121. PHP_FALIAS(method_number, apache_request_method_number, NULL)
  1122. PHP_FALIAS(mtime, apache_request_mtime, NULL)
  1123. PHP_FALIAS(no_cache, apache_request_no_cache, NULL)
  1124. PHP_FALIAS(no_local_copy, apache_request_no_local_copy, NULL)
  1125. PHP_FALIAS(proto_num, apache_request_proto_num, NULL)
  1126. PHP_FALIAS(proxyreq, apache_request_proxyreq, NULL)
  1127. PHP_FALIAS(read_body, apache_request_read_body, NULL)
  1128. PHP_FALIAS(remaining, apache_request_remaining, NULL)
  1129. PHP_FALIAS(request_time, apache_request_request_time, NULL)
  1130. PHP_FALIAS(status, apache_request_status, NULL)
  1131. /* tables & arrays */
  1132. PHP_FALIAS(headers_in, apache_request_headers_in, NULL)
  1133. PHP_FALIAS(headers_out, apache_request_headers_out, NULL)
  1134. PHP_FALIAS(err_headers_out, apache_request_err_headers_out, NULL)
  1135. /* proxy functions for the ap_* functions family */
  1136. #undef auth_name
  1137. #undef auth_type
  1138. #undef discard_request_body
  1139. #undef is_initial_req
  1140. #undef meets_conditions
  1141. #undef satisfies
  1142. #undef set_etag
  1143. #undef set_last_modified
  1144. #undef some_auth_required
  1145. #undef update_mtime
  1146. #undef send_http_header
  1147. #undef send_header_field
  1148. #undef basic_http_header
  1149. #undef send_http_trace
  1150. #undef send_http_options
  1151. #undef send_error_response
  1152. #undef set_content_length
  1153. #undef set_keepalive
  1154. #undef rputs
  1155. #undef log_error
  1156. #undef lookup_uri
  1157. #undef lookup_file
  1158. #undef method_uri
  1159. #undef run
  1160. #undef internal_redirect
  1161. PHP_FALIAS(auth_name, apache_request_auth_name, NULL)
  1162. PHP_FALIAS(auth_type, apache_request_auth_type, NULL)
  1163. PHP_FALIAS(basic_auth_pw, apache_request_basic_auth_pw, NULL)
  1164. PHP_FALIAS(discard_request_body, apache_request_discard_request_body, NULL)
  1165. PHP_FALIAS(is_initial_req, apache_request_is_initial_req, NULL)
  1166. PHP_FALIAS(meets_conditions, apache_request_meets_conditions, NULL)
  1167. PHP_FALIAS(remote_host, apache_request_remote_host, NULL)
  1168. PHP_FALIAS(satisfies, apache_request_satisfies, NULL)
  1169. PHP_FALIAS(server_port, apache_request_server_port, NULL)
  1170. PHP_FALIAS(set_etag, apache_request_set_etag, NULL)
  1171. PHP_FALIAS(set_last_modified, apache_request_set_last_modified, NULL)
  1172. PHP_FALIAS(some_auth_required, apache_request_some_auth_required, NULL)
  1173. PHP_FALIAS(update_mtime, apache_request_update_mtime, NULL)
  1174. PHP_FALIAS(send_http_header, apache_request_send_http_header, NULL)
  1175. PHP_FALIAS(basic_http_header, apache_request_basic_http_header, NULL)
  1176. PHP_FALIAS(send_header_field, apache_request_send_header_field, NULL)
  1177. PHP_FALIAS(send_http_trace, apache_request_send_http_trace, NULL)
  1178. PHP_FALIAS(send_http_options, apache_request_send_http_trace, NULL)
  1179. PHP_FALIAS(send_error_response, apache_request_send_error_response, NULL)
  1180. PHP_FALIAS(set_content_length, apache_request_set_content_length, NULL)
  1181. PHP_FALIAS(set_keepalive, apache_request_set_keepalive, NULL)
  1182. PHP_FALIAS(rputs, apache_request_rputs, NULL)
  1183. PHP_FALIAS(log_error, apache_request_log_error, NULL)
  1184. PHP_FALIAS(lookup_uri, apache_request_sub_req_lookup_uri, NULL)
  1185. PHP_FALIAS(lookup_file, apache_request_sub_req_lookup_file, NULL)
  1186. PHP_FALIAS(method_uri, apache_request_sub_req_method_uri, NULL)
  1187. PHP_FALIAS(run, apache_request_run, NULL)
  1188. PHP_FALIAS(internal_redirect, apache_request_internal_redirect, NULL)
  1189. { NULL, NULL, NULL }
  1190. };
  1191. /* }}} */
  1192. static PHP_MINIT_FUNCTION(apache)
  1193. {
  1194. zend_class_entry ce;
  1195. #ifdef ZTS
  1196. ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), (ts_allocate_ctor) php_apache_globals_ctor, NULL);
  1197. #else
  1198. php_apache_globals_ctor(&php_apache_info TSRMLS_CC);
  1199. #endif
  1200. REGISTER_INI_ENTRIES();
  1201. le_apachereq = zend_register_list_destructors_ex(php_apache_request_free, NULL, "ApacheRequest", module_number);
  1202. INIT_OVERLOADED_CLASS_ENTRY(ce, "ApacheRequest", php_apache_request_class_functions, NULL, NULL, NULL);
  1203. apacherequest_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
  1204. REGISTER_LONG_CONSTANT("OK", OK, CONST_CS | CONST_PERSISTENT);
  1205. REGISTER_LONG_CONSTANT("DECLINED", DECLINED, CONST_CS | CONST_PERSISTENT);
  1206. REGISTER_LONG_CONSTANT("FORBIDDEN", FORBIDDEN, CONST_CS | CONST_PERSISTENT);
  1207. REGISTER_LONG_CONSTANT("AUTH_REQUIRED", AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
  1208. REGISTER_LONG_CONSTANT("DONE", DONE, CONST_CS | CONST_PERSISTENT);
  1209. REGISTER_LONG_CONSTANT("SERVER_ERROR", SERVER_ERROR, CONST_CS | CONST_PERSISTENT);
  1210. REGISTER_LONG_CONSTANT("REDIRECT", REDIRECT, CONST_CS | CONST_PERSISTENT);
  1211. REGISTER_LONG_CONSTANT("BAD_REQUEST", BAD_REQUEST, CONST_CS | CONST_PERSISTENT);
  1212. REGISTER_LONG_CONSTANT("NOT_FOUND", NOT_FOUND, CONST_CS | CONST_PERSISTENT);
  1213. REGISTER_LONG_CONSTANT("HTTP_CONTINUE", HTTP_CONTINUE, CONST_CS | CONST_PERSISTENT);
  1214. REGISTER_LONG_CONSTANT("HTTP_SWITCHING_PROTOCOLS", HTTP_SWITCHING_PROTOCOLS, CONST_CS | CONST_PERSISTENT);
  1215. REGISTER_LONG_CONSTANT("HTTP_PROCESSING", HTTP_PROCESSING, CONST_CS | CONST_PERSISTENT);
  1216. REGISTER_LONG_CONSTANT("HTTP_OK", HTTP_OK, CONST_CS | CONST_PERSISTENT);
  1217. REGISTER_LONG_CONSTANT("HTTP_CREATED", HTTP_CREATED, CONST_CS | CONST_PERSISTENT);
  1218. REGISTER_LONG_CONSTANT("HTTP_ACCEPTED", HTTP_ACCEPTED, CONST_CS | CONST_PERSISTENT);
  1219. REGISTER_LONG_CONSTANT("HTTP_NON_AUTHORITATIVE", HTTP_NON_AUTHORITATIVE, CONST_CS | CONST_PERSISTENT);
  1220. REGISTER_LONG_CONSTANT("HTTP_NO_CONTENT", HTTP_NO_CONTENT, CONST_CS | CONST_PERSISTENT);
  1221. REGISTER_LONG_CONSTANT("HTTP_RESET_CONTENT", HTTP_RESET_CONTENT, CONST_CS | CONST_PERSISTENT);
  1222. REGISTER_LONG_CONSTANT("HTTP_PARTIAL_CONTENT", HTTP_PARTIAL_CONTENT, CONST_CS | CONST_PERSISTENT);
  1223. REGISTER_LONG_CONSTANT("HTTP_MULTI_STATUS", HTTP_MULTI_STATUS, CONST_CS | CONST_PERSISTENT);
  1224. REGISTER_LONG_CONSTANT("HTTP_MULTIPLE_CHOICES", HTTP_MULTIPLE_CHOICES, CONST_CS | CONST_PERSISTENT);
  1225. REGISTER_LONG_CONSTANT("HTTP_MOVED_PERMANENTLY", HTTP_MOVED_PERMANENTLY, CONST_CS | CONST_PERSISTENT);
  1226. REGISTER_LONG_CONSTANT("HTTP_MOVED_TEMPORARILY", HTTP_MOVED_TEMPORARILY, CONST_CS | CONST_PERSISTENT);
  1227. REGISTER_LONG_CONSTANT("HTTP_SEE_OTHER", HTTP_SEE_OTHER, CONST_CS | CONST_PERSISTENT);
  1228. REGISTER_LONG_CONSTANT("HTTP_NOT_MODIFIED", HTTP_NOT_MODIFIED, CONST_CS | CONST_PERSISTENT);
  1229. REGISTER_LONG_CONSTANT("HTTP_USE_PROXY", HTTP_USE_PROXY, CONST_CS | CONST_PERSISTENT);
  1230. REGISTER_LONG_CONSTANT("HTTP_TEMPORARY_REDIRECT", HTTP_TEMPORARY_REDIRECT, CONST_CS | CONST_PERSISTENT);
  1231. REGISTER_LONG_CONSTANT("HTTP_BAD_REQUEST", HTTP_BAD_REQUEST, CONST_CS | CONST_PERSISTENT);
  1232. REGISTER_LONG_CONSTANT("HTTP_UNAUTHORIZED", HTTP_UNAUTHORIZED, CONST_CS | CONST_PERSISTENT);
  1233. REGISTER_LONG_CONSTANT("HTTP_PAYMENT_REQUIRED", HTTP_PAYMENT_REQUIRED, CONST_CS | CONST_PERSISTENT);
  1234. REGISTER_LONG_CONSTANT("HTTP_FORBIDDEN", HTTP_FORBIDDEN, CONST_CS | CONST_PERSISTENT);
  1235. REGISTER_LONG_CONSTANT("HTTP_NOT_FOUND", HTTP_NOT_FOUND, CONST_CS | CONST_PERSISTENT);
  1236. REGISTER_LONG_CONSTANT("HTTP_METHOD_NOT_ALLOWED", HTTP_METHOD_NOT_ALLOWED, CONST_CS | CONST_PERSISTENT);
  1237. REGISTER_LONG_CONSTANT("HTTP_NOT_ACCEPTABLE", HTTP_NOT_ACCEPTABLE, CONST_CS | CONST_PERSISTENT);
  1238. REGISTER_LONG_CONSTANT("HTTP_PROXY_AUTHENTICATION_REQUIRED", HTTP_PROXY_AUTHENTICATION_REQUIRED, CONST_CS | CONST_PERSISTENT);
  1239. REGISTER_LONG_CONSTANT("HTTP_REQUEST_TIME_OUT", HTTP_REQUEST_TIME_OUT, CONST_CS | CONST_PERSISTENT);
  1240. REGISTER_LONG_CONSTANT("HTTP_CONFLICT", HTTP_CONFLICT, CONST_CS | CONST_PERSISTENT);
  1241. REGISTER_LONG_CONSTANT("HTTP_GONE", HTTP_GONE, CONST_CS | CONST_PERSISTENT);REGISTER_LONG_CONSTANT("HTTP_LENGTH_REQUIRED", HTTP_LENGTH_REQUIRED, CONST_CS | CONST_PERSISTENT);
  1242. REGISTER_LONG_CONSTANT("HTTP_PRECONDITION_FAILED", HTTP_PRECONDITION_FAILED, CONST_CS | CONST_PERSISTENT);
  1243. REGISTER_LONG_CONSTANT("HTTP_REQUEST_ENTITY_TOO_LARGE", HTTP_REQUEST_ENTITY_TOO_LARGE, CONST_CS | CONST_PERSISTENT);
  1244. REGISTER_LONG_CONSTANT("HTTP_REQUEST_URI_TOO_LARGE", HTTP_REQUEST_URI_TOO_LARGE, CONST_CS | CONST_PERSISTENT);
  1245. REGISTER_LONG_CONSTANT("HTTP_UNSUPPORTED_MEDIA_TYPE", HTTP_UNSUPPORTED_MEDIA_TYPE, CONST_CS | CONST_PERSISTENT);
  1246. REGISTER_LONG_CONSTANT("HTTP_RANGE_NOT_SATISFIABLE", HTTP_RANGE_NOT_SATISFIABLE, CONST_CS | CONST_PERSISTENT);
  1247. REGISTER_LONG_CONSTANT("HTTP_EXPECTATION_FAILED", HTTP_EXPECTATION_FAILED, CONST_CS | CONST_PERSISTENT);
  1248. REGISTER_LONG_CONSTANT("HTTP_UNPROCESSABLE_ENTITY", HTTP_UNPROCESSABLE_ENTITY, CONST_CS | CONST_PERSISTENT);
  1249. REGISTER_LONG_CONSTANT("HTTP_LOCKED", HTTP_LOCKED, CONST_CS | CONST_PERSISTENT);
  1250. REGISTER_LONG_CONSTANT("HTTP_FAILED_DEPENDENCY", HTTP_FAILED_DEPENDENCY, CONST_CS | CONST_PERSISTENT);
  1251. REGISTER_LONG_CONSTANT("HTTP_INTERNAL_SERVER_ERROR", HTTP_INTERNAL_SERVER_ERROR, CONST_CS | CONST_PERSISTENT);
  1252. REGISTER_LONG_CONSTANT("HTTP_NOT_IMPLEMENTED", HTTP_NOT_IMPLEMENTED, CONST_CS | CONST_PERSISTENT);
  1253. REGISTER_LONG_CONSTANT("HTTP_BAD_GATEWAY", HTTP_BAD_GATEWAY, CONST_CS | CONST_PERSISTENT);
  1254. REGISTER_LONG_CONSTANT("HTTP_SERVICE_UNAVAILABLE", HTTP_SERVICE_UNAVAILABLE, CONST_CS | CONST_PERSISTENT);
  1255. REGISTER_LONG_CONSTANT("HTTP_GATEWAY_TIME_OUT", HTTP_GATEWAY_TIME_OUT, CONST_CS | CONST_PERSISTENT);
  1256. REGISTER_LONG_CONSTANT("HTTP_VERSION_NOT_SUPPORTED", HTTP_VERSION_NOT_SUPPORTED, CONST_CS | CONST_PERSISTENT);
  1257. REGISTER_LONG_CONSTANT("HTTP_VARIANT_ALSO_VARIES", HTTP_VARIANT_ALSO_VARIES, CONST_CS | CONST_PERSISTENT);
  1258. REGISTER_LONG_CONSTANT("HTTP_INSUFFICIENT_STORAGE", HTTP_INSUFFICIENT_STORAGE, CONST_CS | CONST_PERSISTENT);
  1259. REGISTER_LONG_CONSTANT("HTTP_NOT_EXTENDED", HTTP_NOT_EXTENDED, CONST_CS | CONST_PERSISTENT);
  1260. REGISTER_LONG_CONSTANT("APLOG_EMERG", APLOG_EMERG, CONST_CS | CONST_PERSISTENT);
  1261. REGISTER_LONG_CONSTANT("APLOG_ALERT", APLOG_ALERT, CONST_CS | CONST_PERSISTENT);
  1262. REGISTER_LONG_CONSTANT("APLOG_CRIT", APLOG_CRIT, CONST_CS | CONST_PERSISTENT);
  1263. REGISTER_LONG_CONSTANT("APLOG_ERR", APLOG_ERR, CONST_CS | CONST_PERSISTENT);
  1264. REGISTER_LONG_CONSTANT("APLOG_WARNING", APLOG_WARNING, CONST_CS | CONST_PERSISTENT);
  1265. REGISTER_LONG_CONSTANT("APLOG_NOTICE", APLOG_NOTICE, CONST_CS | CONST_PERSISTENT);
  1266. REGISTER_LONG_CONSTANT("APLOG_INFO", APLOG_INFO, CONST_CS | CONST_PERSISTENT);
  1267. REGISTER_LONG_CONSTANT("APLOG_DEBUG", APLOG_DEBUG, CONST_CS | CONST_PERSISTENT);
  1268. REGISTER_LONG_CONSTANT("M_GET", M_GET, CONST_CS | CONST_PERSISTENT);
  1269. REGISTER_LONG_CONSTANT("M_PUT", M_PUT, CONST_CS | CONST_PERSISTENT);
  1270. REGISTER_LONG_CONSTANT("M_POST", M_POST, CONST_CS | CONST_PERSISTENT);
  1271. REGISTER_LONG_CONSTANT("M_DELETE", M_DELETE, CONST_CS | CONST_PERSISTENT);
  1272. REGISTER_LONG_CONSTANT("M_CONNECT", M_CONNECT, CONST_CS | CONST_PERSISTENT);
  1273. REGISTER_LONG_CONSTANT("M_OPTIONS", M_OPTIONS, CONST_CS | CONST_PERSISTENT);
  1274. REGISTER_LONG_CONSTANT("M_TRACE", M_TRACE, CONST_CS | CONST_PERSISTENT);
  1275. REGISTER_LONG_CONSTANT("M_PATCH", M_PATCH, CONST_CS | CONST_PERSISTENT);
  1276. REGISTER_LONG_CONSTANT("M_PROPFIND", M_PROPFIND, CONST_CS | CONST_PERSISTENT);
  1277. REGISTER_LONG_CONSTANT("M_PROPPATCH", M_PROPPATCH, CONST_CS | CONST_PERSISTENT);
  1278. REGISTER_LONG_CONSTANT("M_MKCOL", M_MKCOL, CONST_CS | CONST_PERSISTENT);
  1279. REGISTER_LONG_CONSTANT("M_COPY", M_COPY, CONST_CS | CONST_PERSISTENT);
  1280. REGISTER_LONG_CONSTANT("M_MOVE", M_MOVE, CONST_CS | CONST_PERSISTENT);
  1281. REGISTER_LONG_CONSTANT("M_LOCK", M_LOCK, CONST_CS | CONST_PERSISTENT);
  1282. REGISTER_LONG_CONSTANT("M_UNLOCK", M_UNLOCK, CONST_CS | CONST_PERSISTENT);
  1283. REGISTER_LONG_CONSTANT("M_INVALID", M_INVALID, CONST_CS | CONST_PERSISTENT);
  1284. /* Possible values for request_rec.read_body (set by handling module):
  1285. * REQUEST_NO_BODY Send 413 error if message has any body
  1286. * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length
  1287. * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me.
  1288. * REQUEST_CHUNKED_PASS Pass the chunks to me without removal.
  1289. */
  1290. REGISTER_LONG_CONSTANT("REQUEST_NO_BODY", REQUEST_NO_BODY, CONST_CS | CONST_PERSISTENT);
  1291. REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_ERROR", REQUEST_CHUNKED_ERROR, CONST_CS | CONST_PERSISTENT);
  1292. REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_DECHUNK", REQUEST_CHUNKED_DECHUNK, CONST_CS | CONST_PERSISTENT);
  1293. REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_PASS", REQUEST_CHUNKED_PASS, CONST_CS | CONST_PERSISTENT);
  1294. /* resolve types for remote_host() */
  1295. REGISTER_LONG_CONSTANT("REMOTE_HOST", REMOTE_HOST, CONST_CS | CONST_PERSISTENT);
  1296. REGISTER_LONG_CONSTANT("REMOTE_NAME", REMOTE_NAME, CONST_CS | CONST_PERSISTENT);
  1297. REGISTER_LONG_CONSTANT("REMOTE_NOLOOKUP", REMOTE_NOLOOKUP, CONST_CS | CONST_PERSISTENT);
  1298. REGISTER_LONG_CONSTANT("REMOTE_DOUBLE_REV", REMOTE_DOUBLE_REV, CONST_CS | CONST_PERSISTENT);
  1299. return SUCCESS;
  1300. }
  1301. static PHP_MSHUTDOWN_FUNCTION(apache)
  1302. {
  1303. UNREGISTER_INI_ENTRIES();
  1304. return SUCCESS;
  1305. }
  1306. zend_module_entry apache_module_entry = {
  1307. STANDARD_MODULE_HEADER,
  1308. "apache",
  1309. apache_functions,
  1310. PHP_MINIT(apache),
  1311. PHP_MSHUTDOWN(apache),
  1312. NULL,
  1313. NULL,
  1314. PHP_MINFO(apache),
  1315. NO_VERSION_YET,
  1316. STANDARD_MODULE_PROPERTIES
  1317. };
  1318. /* {{{ proto bool apache_child_terminate(void)
  1319. Terminate apache process after this request */
  1320. PHP_FUNCTION(apache_child_terminate)
  1321. {
  1322. #ifndef MULTITHREAD
  1323. if (AP(terminate_child)) {
  1324. ap_child_terminate( ((request_rec *)SG(server_context)) );
  1325. RETURN_TRUE;
  1326. } else { /* tell them to get lost! */
  1327. php_error(E_WARNING, "apache.child_terminate is disabled");
  1328. RETURN_FALSE;
  1329. }
  1330. #else
  1331. php_error(E_WARNING, "apache_child_terminate() is not supported in this build");
  1332. RETURN_FALSE;
  1333. #endif
  1334. }
  1335. /* }}} */
  1336. /* {{{ proto string apache_note(string note_name [, string note_value])
  1337. Get and set Apache request notes */
  1338. PHP_FUNCTION(apache_note)
  1339. {
  1340. zval **arg_name, **arg_val;
  1341. char *note_val;
  1342. int arg_count = ZEND_NUM_ARGS();
  1343. if (arg_count<1 || arg_count>2 ||
  1344. zend_get_parameters_ex(arg_count, &arg_name, &arg_val) ==FAILURE ) {
  1345. WRONG_PARAM_COUNT;
  1346. }
  1347. convert_to_string_ex(arg_name);
  1348. note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val);
  1349. if (arg_count == 2) {
  1350. convert_to_string_ex(arg_val);
  1351. table_set(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val, (*arg_val)->value.str.val);
  1352. }
  1353. if (note_val) {
  1354. RETURN_STRING(note_val, 1);
  1355. } else {
  1356. RETURN_FALSE;
  1357. }
  1358. }
  1359. /* }}} */
  1360. /* {{{ PHP_MINFO_FUNCTION
  1361. */
  1362. PHP_MINFO_FUNCTION(apache)
  1363. {
  1364. module *modp = NULL;
  1365. char output_buf[128];
  1366. #if !defined(WIN32) && !defined(WINNT)
  1367. char name[64];
  1368. char modulenames[1024];
  1369. char *p;
  1370. #endif
  1371. server_rec *serv;
  1372. extern char server_root[MAX_STRING_LEN];
  1373. extern uid_t user_id;
  1374. extern char *user_name;
  1375. extern gid_t group_id;
  1376. extern int max_requests_per_child;
  1377. serv = ((request_rec *) SG(server_context))->server;
  1378. php_info_print_table_start();
  1379. #ifdef PHP_WIN32
  1380. php_info_print_table_row(1, "Apache for Windows 95/NT");
  1381. php_info_print_table_end();
  1382. php_info_print_table_start();
  1383. #elif defined(NETWARE)
  1384. php_info_print_table_row(1, "Apache for NetWare");
  1385. php_info_print_table_end();
  1386. php_info_print_table_start();
  1387. #else
  1388. php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE);
  1389. php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET);
  1390. #endif
  1391. php_info_print_table_row(2, "Apache Version", SERVER_VERSION);
  1392. #ifdef APACHE_RELEASE
  1393. snprintf(output_buf, sizeof(output_buf), "%d", APACHE_RELEASE);
  1394. php_info_print_table_row(2, "Apache Release", output_buf);
  1395. #endif
  1396. snprintf(output_buf, sizeof(output_buf), "%d", MODULE_MAGIC_NUMBER);
  1397. php_info_print_table_row(2, "Apache API Version", output_buf);
  1398. snprintf(output_buf, sizeof(output_buf), "%s:%u", serv->server_hostname, serv->port);
  1399. php_info_print_table_row(2, "Hostname:Port", output_buf);
  1400. #if !defined(WIN32) && !defined(WINNT)
  1401. snprintf(output_buf, sizeof(output_buf), "%s(%d)/%d", user_name, (int)user_id, (int)group_id);
  1402. php_info_print_table_row(2, "User/Group", output_buf);
  1403. snprintf(output_buf, sizeof(output_buf), "Per Child: %d - Keep Alive: %s - Max Per Connection: %d", max_requests_per_child, serv->keep_alive ? "on":"off", serv->keep_alive_max);
  1404. php_info_print_table_row(2, "Max Requests", output_buf);
  1405. #endif
  1406. snprintf(output_buf, sizeof(output_buf), "Connection: %d - Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout);
  1407. php_info_print_table_row(2, "Timeouts", output_buf);
  1408. #if !defined(WIN32) && !defined(WINNT)
  1409. /*
  1410. This block seems to be working on NetWare; But it seems to be showing
  1411. all modules instead of just the loaded ones
  1412. */
  1413. php_info_print_table_row(2, "Server Root", server_root);
  1414. strcpy(modulenames, "");
  1415. for(modp = top_module; modp; modp = modp->next) {
  1416. strlcpy(name, modp->name, sizeof(name));
  1417. if ((p = strrchr(name, '.'))) {
  1418. *p='\0'; /* Cut off ugly .c extensions on module names */
  1419. }
  1420. strlcat(modulenames, name, sizeof(modulenames));
  1421. if (modp->next) {
  1422. strlcat(modulenames, ", ", sizeof(modulenames));
  1423. }
  1424. }
  1425. php_info_print_table_row(2, "Loaded Modules", modulenames);
  1426. #endif
  1427. php_info_print_table_end();
  1428. DISPLAY_INI_ENTRIES();
  1429. {
  1430. register int i;
  1431. array_header *arr;
  1432. table_entry *elts;
  1433. request_rec *r;
  1434. r = ((request_rec *) SG(server_context));
  1435. arr = table_elts(r->subprocess_env);
  1436. elts = (table_entry *)arr->elts;
  1437. SECTION("Apache Environment");
  1438. php_info_print_table_start();
  1439. php_info_print_table_header(2, "Variable", "Value");
  1440. for (i=0; i < arr->nelts; i++) {
  1441. php_info_print_table_row(2, elts[i].key, elts[i].val);
  1442. }
  1443. php_info_print_table_end();
  1444. }
  1445. {
  1446. array_header *env_arr;
  1447. table_entry *env;
  1448. int i;
  1449. request_rec *r;
  1450. r = ((request_rec *) SG(server_context));
  1451. SECTION("HTTP Headers Information");
  1452. php_info_print_table_start();
  1453. php_info_print_table_colspan_header(2, "HTTP Request Headers");
  1454. php_info_print_table_row(2, "HTTP Request", r->the_request);
  1455. env_arr = table_elts(r->headers_in);
  1456. env = (table_entry *)env_arr->elts;
  1457. for (i = 0; i < env_arr->nelts; ++i) {
  1458. if (env[i].key && (!PG(safe_mode) || (PG(safe_mode) && strncasecmp(env[i].key, "authorization", 13)))) {
  1459. php_info_print_table_row(2, env[i].key, env[i].val);
  1460. }
  1461. }
  1462. php_info_print_table_colspan_header(2, "HTTP Response Headers");
  1463. env_arr = table_elts(r->headers_out);
  1464. env = (table_entry *)env_arr->elts;
  1465. for(i = 0; i < env_arr->nelts; ++i) {
  1466. if (env[i].key) {
  1467. php_info_print_table_row(2, env[i].key, env[i].val);
  1468. }
  1469. }
  1470. php_info_print_table_end();
  1471. }
  1472. }
  1473. /* }}} */
  1474. /* {{{ proto bool virtual(string filename)
  1475. Perform an Apache sub-request */
  1476. /* This function is equivalent to <!--#include virtual...-->
  1477. * in mod_include. It does an Apache sub-request. It is useful
  1478. * for including CGI scripts or .shtml files, or anything else
  1479. * that you'd parse through Apache (for .phtml files, you'd probably
  1480. * want to use <?Include>. This only works when PHP is compiled
  1481. * as an Apache module, since it uses the Apache API for doing
  1482. * sub requests.
  1483. */
  1484. PHP_FUNCTION(virtual)
  1485. {
  1486. zval **filename;
  1487. request_rec *rr = NULL;
  1488. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  1489. WRONG_PARAM_COUNT;
  1490. }
  1491. convert_to_string_ex(filename);
  1492. if (!(rr = sub_req_lookup_uri ((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  1493. php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", (*filename)->value.str.val);
  1494. if (rr) destroy_sub_req (rr);
  1495. RETURN_FALSE;
  1496. }
  1497. if (rr->status != 200) {
  1498. php_error(E_WARNING, "Unable to include '%s' - error finding URI", (*filename)->value.str.val);
  1499. if (rr) destroy_sub_req (rr);
  1500. RETURN_FALSE;
  1501. }
  1502. php_end_ob_buffers(1 TSRMLS_CC);
  1503. php_header(TSRMLS_C);
  1504. if (run_sub_req(rr)) {
  1505. php_error(E_WARNING, "Unable to include '%s' - request execution failed", (*filename)->value.str.val);
  1506. if (rr) destroy_sub_req (rr);
  1507. RETURN_FALSE;
  1508. } else {
  1509. if (rr) destroy_sub_req (rr);
  1510. RETURN_TRUE;
  1511. }
  1512. }
  1513. /* }}} */
  1514. /* {{{ apache_table_to_zval(table *, int safe_mode, zval *return_value)
  1515. Fetch all HTTP request headers */
  1516. static void apache_table_to_zval(table *t, int safe_mode, zval *return_value)
  1517. {
  1518. array_header *env_arr;
  1519. table_entry *tenv;
  1520. int i;
  1521. array_init(return_value);
  1522. env_arr = table_elts(t);
  1523. tenv = (table_entry *)env_arr->elts;
  1524. for (i = 0; i < env_arr->nelts; ++i) {
  1525. if (!tenv[i].key ||
  1526. (safe_mode && !strncasecmp(tenv[i].key, "authorization", 13))) {
  1527. continue;
  1528. }
  1529. if (add_assoc_string(return_value, tenv[i].key, (tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) {
  1530. RETURN_FALSE;
  1531. }
  1532. }
  1533. }
  1534. /* }}} */
  1535. /* {{{ proto array getallheaders(void)
  1536. */
  1537. /* Alias for apache_request_headers() */
  1538. /* }}} */
  1539. /* {{{ proto array apache_request_headers(void)
  1540. Fetch all HTTP request headers */
  1541. PHP_FUNCTION(apache_request_headers)
  1542. {
  1543. apache_table_to_zval(((request_rec *)SG(server_context))->headers_in, PG(safe_mode), return_value);
  1544. }
  1545. /* }}} */
  1546. /* {{{ proto array apache_response_headers(void)
  1547. Fetch all HTTP response headers */
  1548. PHP_FUNCTION(apache_response_headers)
  1549. {
  1550. apache_table_to_zval(((request_rec *) SG(server_context))->headers_out, 0, return_value);
  1551. }
  1552. /* }}} */
  1553. /* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top])
  1554. Set an Apache subprocess_env variable */
  1555. PHP_FUNCTION(apache_setenv)
  1556. {
  1557. int var_len, val_len;
  1558. zend_bool top=0;
  1559. char *var = NULL, *val = NULL;
  1560. request_rec *r = (request_rec *) SG(server_context);
  1561. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &var, &var_len, &val, &val_len, &top) == FAILURE) {
  1562. RETURN_FALSE;
  1563. }
  1564. while(top) {
  1565. if(r->prev) r = r->prev;
  1566. else break;
  1567. }
  1568. ap_table_setn(r->subprocess_env, ap_pstrndup(r->pool, var, var_len), ap_pstrndup(r->pool, val, val_len));
  1569. RETURN_TRUE;
  1570. }
  1571. /* }}} */
  1572. /* {{{ proto object apache_lookup_uri(string URI)
  1573. Perform a partial request of the given URI to obtain information about it */
  1574. PHP_FUNCTION(apache_lookup_uri)
  1575. {
  1576. zval **filename;
  1577. request_rec *rr=NULL;
  1578. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  1579. WRONG_PARAM_COUNT;
  1580. }
  1581. convert_to_string_ex(filename);
  1582. if(!(rr = sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  1583. php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
  1584. RETURN_FALSE;
  1585. }
  1586. object_init(return_value);
  1587. add_property_long(return_value,"status", rr->status);
  1588. if (rr->the_request) {
  1589. add_property_string(return_value,"the_request", rr->the_request, 1);
  1590. }
  1591. if (rr->status_line) {
  1592. add_property_string(return_value,"status_line", (char *)rr->status_line, 1);
  1593. }
  1594. if (rr->method) {
  1595. add_property_string(return_value,"method", (char *)rr->method, 1);
  1596. }
  1597. if (rr->content_type) {
  1598. add_property_string(return_value,"content_type", (char *)rr->content_type, 1);
  1599. }
  1600. if (rr->handler) {
  1601. add_property_string(return_value,"handler", (char *)rr->handler, 1);
  1602. }
  1603. if (rr->uri) {
  1604. add_property_string(return_value,"uri", rr->uri, 1);
  1605. }
  1606. if (rr->filename) {
  1607. add_property_string(return_value,"filename", rr->filename, 1);
  1608. }
  1609. if (rr->path_info) {
  1610. add_property_string(return_value,"path_info", rr->path_info, 1);
  1611. }
  1612. if (rr->args) {
  1613. add_property_string(return_value,"args", rr->args, 1);
  1614. }
  1615. if (rr->boundary) {
  1616. add_property_string(return_value,"boundary", rr->boundary, 1);
  1617. }
  1618. add_property_long(return_value,"no_cache", rr->no_cache);
  1619. add_property_long(return_value,"no_local_copy", rr->no_local_copy);
  1620. add_property_long(return_value,"allowed", rr->allowed);
  1621. add_property_long(return_value,"sent_bodyct", rr->sent_bodyct);
  1622. add_property_long(return_value,"bytes_sent", rr->bytes_sent);
  1623. add_property_long(return_value,"byterange", rr->byterange);
  1624. add_property_long(return_value,"clength", rr->clength);
  1625. #if MODULE_MAGIC_NUMBER >= 19980324
  1626. if (rr->unparsed_uri) {
  1627. add_property_string(return_value,"unparsed_uri", rr->unparsed_uri, 1);
  1628. }
  1629. if(rr->mtime) {
  1630. add_property_long(return_value,"mtime", rr->mtime);
  1631. }
  1632. #endif
  1633. if(rr->request_time) {
  1634. add_property_long(return_value,"request_time", rr->request_time);
  1635. }
  1636. destroy_sub_req(rr);
  1637. }
  1638. /* }}} */
  1639. #if 0
  1640. This function is most likely a bad idea. Just playing with it for now.
  1641. PHP_FUNCTION(apache_exec_uri)
  1642. {
  1643. zval **filename;
  1644. request_rec *rr=NULL;
  1645. TSRMLS_FETCH();
  1646. if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  1647. WRONG_PARAM_COUNT;
  1648. }
  1649. convert_to_string_ex(filename);
  1650. if(!(rr = ap_sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  1651. php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
  1652. RETURN_FALSE;
  1653. }
  1654. RETVAL_LONG(ap_run_sub_req(rr));
  1655. ap_destroy_sub_req(rr);
  1656. }
  1657. #endif
  1658. /* {{{ proto string apache_get_version(void)
  1659. Fetch Apache version */
  1660. PHP_FUNCTION(apache_get_version)
  1661. {
  1662. char *apv = (char *) ap_get_server_version();
  1663. if (apv && *apv) {
  1664. RETURN_STRING(apv, 1);
  1665. } else {
  1666. RETURN_FALSE;
  1667. }
  1668. }
  1669. /* }}} */
  1670. /* {{{ proto array apache_get_modules(void)
  1671. Get a list of loaded Apache modules */
  1672. PHP_FUNCTION(apache_get_modules)
  1673. {
  1674. int n;
  1675. char *p;
  1676. array_init(return_value);
  1677. for (n = 0; ap_loaded_modules[n]; ++n) {
  1678. char *s = (char *) ap_loaded_modules[n]->name;
  1679. if ((p = strchr(s, '.'))) {
  1680. add_next_index_stringl(return_value, s, (p - s), 1);
  1681. } else {
  1682. add_next_index_string(return_value, s, 1);
  1683. }
  1684. }
  1685. }
  1686. /* }}} */
  1687. /*
  1688. * Local variables:
  1689. * tab-width: 4
  1690. * c-basic-offset: 4
  1691. * End:
  1692. * vim600: sw=4 ts=4 fdm=marker
  1693. * vim<600: sw=4 ts=4
  1694. */