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.

471 lines
14 KiB

25 years ago
25 years ago
24 years ago
26 years ago
25 years ago
25 years ago
24 years ago
25 years ago
26 years ago
25 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
26 years ago
25 years ago
26 years ago
26 years ago
26 years ago
25 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 4 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2002 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.02 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available at through the world-wide-web at |
  10. | http://www.php.net/license/2_02.txt. |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
  16. | Stig Sther Bakken <ssb@fast.no> |
  17. | David Sklar <sklar@student.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id$ */
  21. #include "php_apache_http.h"
  22. #ifdef PHP_WIN32
  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. extern module *top_module;
  35. PHP_FUNCTION(virtual);
  36. PHP_FUNCTION(getallheaders);
  37. PHP_FUNCTION(apachelog);
  38. PHP_FUNCTION(apache_note);
  39. PHP_FUNCTION(apache_lookup_uri);
  40. PHP_FUNCTION(apache_child_terminate);
  41. PHP_FUNCTION(apache_setenv);
  42. PHP_MINFO_FUNCTION(apache);
  43. function_entry apache_functions[] = {
  44. PHP_FE(virtual, NULL)
  45. PHP_FE(getallheaders, NULL)
  46. PHP_FE(apache_note, NULL)
  47. PHP_FE(apache_lookup_uri, NULL)
  48. PHP_FE(apache_child_terminate, NULL)
  49. PHP_FE(apache_setenv, NULL)
  50. {NULL, NULL, NULL}
  51. };
  52. PHP_INI_BEGIN()
  53. STD_PHP_INI_ENTRY("xbithack", "0", PHP_INI_ALL, OnUpdateInt, xbithack, php_apache_info_struct, php_apache_info)
  54. STD_PHP_INI_ENTRY("engine", "1", PHP_INI_ALL, OnUpdateInt, engine, php_apache_info_struct, php_apache_info)
  55. STD_PHP_INI_ENTRY("last_modified", "0", PHP_INI_ALL, OnUpdateInt, last_modified, php_apache_info_struct, php_apache_info)
  56. STD_PHP_INI_ENTRY("child_terminate", "0", PHP_INI_ALL, OnUpdateInt, terminate_child, php_apache_info_struct, php_apache_info)
  57. PHP_INI_END()
  58. static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC)
  59. {
  60. apache_globals->in_request = 0;
  61. }
  62. static PHP_MINIT_FUNCTION(apache)
  63. {
  64. #ifdef ZTS
  65. ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), php_apache_globals_ctor, NULL);
  66. #else
  67. php_apache_globals_ctor(&php_apache_info TSRMLS_CC);
  68. #endif
  69. REGISTER_INI_ENTRIES();
  70. return SUCCESS;
  71. }
  72. static PHP_MSHUTDOWN_FUNCTION(apache)
  73. {
  74. UNREGISTER_INI_ENTRIES();
  75. return SUCCESS;
  76. }
  77. zend_module_entry apache_module_entry = {
  78. STANDARD_MODULE_HEADER,
  79. "apache",
  80. apache_functions,
  81. PHP_MINIT(apache),
  82. PHP_MSHUTDOWN(apache),
  83. NULL,
  84. NULL,
  85. PHP_MINFO(apache),
  86. NO_VERSION_YET,
  87. STANDARD_MODULE_PROPERTIES
  88. };
  89. /* {{{ proto string apache_child_terminate()
  90. Terminate apache process after this request */
  91. PHP_FUNCTION(apache_child_terminate)
  92. {
  93. #ifndef MULTITHREAD
  94. if (AP(terminate_child)) {
  95. ap_child_terminate( ((request_rec *)SG(server_context)) );
  96. } else { /* tell them to get lost! */
  97. php_error(E_WARNING, "apache.child_terminate is disabled");
  98. }
  99. #else
  100. php_error(E_WARNING, "apache_child_terminate() is not supported in this build");
  101. #endif
  102. }
  103. /* }}} */
  104. /* {{{ proto string apache_note(string note_name [, string note_value])
  105. Get and set Apache request notes */
  106. PHP_FUNCTION(apache_note)
  107. {
  108. pval **arg_name, **arg_val;
  109. char *note_val;
  110. int arg_count = ARG_COUNT(ht);
  111. if (arg_count<1 || arg_count>2 ||
  112. zend_get_parameters_ex(arg_count, &arg_name, &arg_val) ==FAILURE ) {
  113. WRONG_PARAM_COUNT;
  114. }
  115. convert_to_string_ex(arg_name);
  116. note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val);
  117. if (arg_count == 2) {
  118. convert_to_string_ex(arg_val);
  119. table_set(((request_rec *)SG(server_context))->notes, (*arg_name)->value.str.val, (*arg_val)->value.str.val);
  120. }
  121. if (note_val) {
  122. RETURN_STRING(note_val, 1);
  123. } else {
  124. RETURN_FALSE;
  125. }
  126. }
  127. /* }}} */
  128. /* {{{ PHP_MINFO_FUNCTION
  129. */
  130. PHP_MINFO_FUNCTION(apache)
  131. {
  132. module *modp = NULL;
  133. char output_buf[128];
  134. #if !defined(WIN32) && !defined(WINNT)
  135. char name[64];
  136. char modulenames[1024];
  137. char *p;
  138. #endif
  139. server_rec *serv;
  140. extern char server_root[MAX_STRING_LEN];
  141. extern uid_t user_id;
  142. extern char *user_name;
  143. extern gid_t group_id;
  144. extern int max_requests_per_child;
  145. serv = ((request_rec *) SG(server_context))->server;
  146. php_info_print_table_start();
  147. #ifdef PHP_WIN32
  148. php_info_print_table_row(1, "Apache for Windows 95/NT");
  149. php_info_print_table_end();
  150. php_info_print_table_start();
  151. #else
  152. php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE);
  153. php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET);
  154. #endif
  155. php_info_print_table_row(2, "Apache Version", SERVER_VERSION);
  156. #ifdef APACHE_RELEASE
  157. sprintf(output_buf, "%d", APACHE_RELEASE);
  158. php_info_print_table_row(2, "Apache Release", output_buf);
  159. #endif
  160. sprintf(output_buf, "%d", MODULE_MAGIC_NUMBER);
  161. php_info_print_table_row(2, "Apache API Version", output_buf);
  162. sprintf(output_buf, "%s:%u", serv->server_hostname, serv->port);
  163. php_info_print_table_row(2, "Hostname:Port", output_buf);
  164. #if !defined(WIN32) && !defined(WINNT)
  165. sprintf(output_buf, "%s(%d)/%d", user_name, (int)user_id, (int)group_id);
  166. php_info_print_table_row(2, "User/Group", output_buf);
  167. sprintf(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);
  168. php_info_print_table_row(2, "Max Requests", output_buf);
  169. #endif
  170. sprintf(output_buf, "Connection: %d - Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout);
  171. php_info_print_table_row(2, "Timeouts", output_buf);
  172. #if !defined(WIN32) && !defined(WINNT)
  173. php_info_print_table_row(2, "Server Root", server_root);
  174. strcpy(modulenames, "");
  175. for(modp = top_module; modp; modp = modp->next) {
  176. strlcpy(name, modp->name, sizeof(name));
  177. if ((p = strrchr(name, '.'))) {
  178. *p='\0'; /* Cut off ugly .c extensions on module names */
  179. }
  180. strcat(modulenames, name);
  181. if (modp->next) {
  182. strcat(modulenames, ", ");
  183. }
  184. }
  185. php_info_print_table_row(2, "Loaded Modules", modulenames);
  186. #endif
  187. php_info_print_table_end();
  188. DISPLAY_INI_ENTRIES();
  189. {
  190. register int i;
  191. array_header *arr;
  192. table_entry *elts;
  193. request_rec *r;
  194. r = ((request_rec *) SG(server_context));
  195. arr = table_elts(r->subprocess_env);
  196. elts = (table_entry *)arr->elts;
  197. SECTION("Apache Environment");
  198. php_info_print_table_start();
  199. php_info_print_table_header(2, "Variable", "Value");
  200. for (i=0; i < arr->nelts; i++) {
  201. php_info_print_table_row(2, elts[i].key, elts[i].val);
  202. }
  203. php_info_print_table_end();
  204. }
  205. {
  206. array_header *env_arr;
  207. table_entry *env;
  208. int i;
  209. request_rec *r;
  210. r = ((request_rec *) SG(server_context));
  211. SECTION("HTTP Headers Information");
  212. php_info_print_table_start();
  213. php_info_print_table_colspan_header(2, "HTTP Request Headers");
  214. php_info_print_table_row(2, "HTTP Request", r->the_request);
  215. env_arr = table_elts(r->headers_in);
  216. env = (table_entry *)env_arr->elts;
  217. for (i = 0; i < env_arr->nelts; ++i) {
  218. if (env[i].key && (!PG(safe_mode) || (PG(safe_mode) && strncasecmp(env[i].key, "authorization", 13)))) {
  219. php_info_print_table_row(2, env[i].key, env[i].val);
  220. }
  221. }
  222. php_info_print_table_colspan_header(2, "HTTP Response Headers");
  223. env_arr = table_elts(r->headers_out);
  224. env = (table_entry *)env_arr->elts;
  225. for(i = 0; i < env_arr->nelts; ++i) {
  226. if (env[i].key) {
  227. php_info_print_table_row(2, env[i].key, env[i].val);
  228. }
  229. }
  230. php_info_print_table_end();
  231. }
  232. }
  233. /* }}} */
  234. /* {{{ proto int virtual(string filename)
  235. Perform an Apache sub-request */
  236. /* This function is equivalent to <!--#include virtual...-->
  237. * in mod_include. It does an Apache sub-request. It is useful
  238. * for including CGI scripts or .shtml files, or anything else
  239. * that you'd parse through Apache (for .phtml files, you'd probably
  240. * want to use <?Include>. This only works when PHP is compiled
  241. * as an Apache module, since it uses the Apache API for doing
  242. * sub requests.
  243. */
  244. PHP_FUNCTION(virtual)
  245. {
  246. pval **filename;
  247. request_rec *rr = NULL;
  248. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  249. WRONG_PARAM_COUNT;
  250. }
  251. convert_to_string_ex(filename);
  252. if (!(rr = sub_req_lookup_uri ((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  253. php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", (*filename)->value.str.val);
  254. if (rr) destroy_sub_req (rr);
  255. RETURN_FALSE;
  256. }
  257. if (rr->status != 200) {
  258. php_error(E_WARNING, "Unable to include '%s' - error finding URI", (*filename)->value.str.val);
  259. if (rr) destroy_sub_req (rr);
  260. RETURN_FALSE;
  261. }
  262. php_end_ob_buffers(1 TSRMLS_CC);
  263. php_header();
  264. if (run_sub_req(rr)) {
  265. php_error(E_WARNING, "Unable to include '%s' - request execution failed", (*filename)->value.str.val);
  266. if (rr) destroy_sub_req (rr);
  267. RETURN_FALSE;
  268. } else {
  269. if (rr) destroy_sub_req (rr);
  270. RETURN_TRUE;
  271. }
  272. }
  273. /* }}} */
  274. /* {{{ proto array getallheaders(void)
  275. Fetch all HTTP request headers */
  276. PHP_FUNCTION(getallheaders)
  277. {
  278. array_header *env_arr;
  279. table_entry *tenv;
  280. int i;
  281. if (array_init(return_value) == FAILURE) {
  282. RETURN_FALSE;
  283. }
  284. env_arr = table_elts(((request_rec *) SG(server_context))->headers_in);
  285. tenv = (table_entry *)env_arr->elts;
  286. for (i = 0; i < env_arr->nelts; ++i) {
  287. if (!tenv[i].key ||
  288. (PG(safe_mode) &&
  289. !strncasecmp(tenv[i].key, "authorization", 13))) {
  290. continue;
  291. }
  292. if (add_assoc_string(return_value, tenv[i].key, (tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) {
  293. RETURN_FALSE;
  294. }
  295. }
  296. }
  297. /* }}} */
  298. /* {{{ proto int apache_setenv(string variable, string value [, boolean walk_to_top])
  299. Set an Apache subprocess_env variable */
  300. PHP_FUNCTION(apache_setenv)
  301. {
  302. int var_len, val_len, top=0;
  303. char *var = NULL, *val = NULL;
  304. request_rec *r = (request_rec *) SG(server_context);
  305. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &var, &var_len, &val, &val_len, &top) == FAILURE) {
  306. RETURN_FALSE;
  307. }
  308. while(top) {
  309. if(r->prev) r = r->prev;
  310. else break;
  311. }
  312. ap_table_setn(r->subprocess_env, ap_pstrndup(r->pool, var, var_len), ap_pstrndup(r->pool, val, val_len));
  313. RETURN_TRUE;
  314. }
  315. /* }}} */
  316. /* {{{ proto class apache_lookup_uri(string URI)
  317. Perform a partial request of the given URI to obtain information about it */
  318. PHP_FUNCTION(apache_lookup_uri)
  319. {
  320. pval **filename;
  321. request_rec *rr=NULL;
  322. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  323. WRONG_PARAM_COUNT;
  324. }
  325. convert_to_string_ex(filename);
  326. if(!(rr = sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  327. php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
  328. RETURN_FALSE;
  329. }
  330. object_init(return_value);
  331. add_property_long(return_value,"status", rr->status);
  332. if (rr->the_request) {
  333. add_property_string(return_value,"the_request", rr->the_request, 1);
  334. }
  335. if (rr->status_line) {
  336. add_property_string(return_value,"status_line", (char *)rr->status_line, 1);
  337. }
  338. if (rr->method) {
  339. add_property_string(return_value,"method", (char *)rr->method, 1);
  340. }
  341. if (rr->content_type) {
  342. add_property_string(return_value,"content_type", (char *)rr->content_type, 1);
  343. }
  344. if (rr->handler) {
  345. add_property_string(return_value,"handler", (char *)rr->handler, 1);
  346. }
  347. if (rr->uri) {
  348. add_property_string(return_value,"uri", rr->uri, 1);
  349. }
  350. if (rr->filename) {
  351. add_property_string(return_value,"filename", rr->filename, 1);
  352. }
  353. if (rr->path_info) {
  354. add_property_string(return_value,"path_info", rr->path_info, 1);
  355. }
  356. if (rr->args) {
  357. add_property_string(return_value,"args", rr->args, 1);
  358. }
  359. if (rr->boundary) {
  360. add_property_string(return_value,"boundary", rr->boundary, 1);
  361. }
  362. add_property_long(return_value,"no_cache", rr->no_cache);
  363. add_property_long(return_value,"no_local_copy", rr->no_local_copy);
  364. add_property_long(return_value,"allowed", rr->allowed);
  365. add_property_long(return_value,"sent_bodyct", rr->sent_bodyct);
  366. add_property_long(return_value,"bytes_sent", rr->bytes_sent);
  367. add_property_long(return_value,"byterange", rr->byterange);
  368. add_property_long(return_value,"clength", rr->clength);
  369. #if MODULE_MAGIC_NUMBER >= 19980324
  370. if (rr->unparsed_uri) {
  371. add_property_string(return_value,"unparsed_uri", rr->unparsed_uri, 1);
  372. }
  373. if(rr->mtime) {
  374. add_property_long(return_value,"mtime", rr->mtime);
  375. }
  376. #endif
  377. if(rr->request_time) {
  378. add_property_long(return_value,"request_time", rr->request_time);
  379. }
  380. destroy_sub_req(rr);
  381. }
  382. /* }}} */
  383. #if 0
  384. This function is most likely a bad idea. Just playing with it for now.
  385. PHP_FUNCTION(apache_exec_uri)
  386. {
  387. pval **filename;
  388. request_rec *rr=NULL;
  389. TSRMLS_FETCH();
  390. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
  391. WRONG_PARAM_COUNT;
  392. }
  393. convert_to_string_ex(filename);
  394. if(!(rr = ap_sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
  395. php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
  396. RETURN_FALSE;
  397. }
  398. RETVAL_LONG(ap_run_sub_req(rr));
  399. ap_destroy_sub_req(rr);
  400. }
  401. #endif
  402. /*
  403. * Local variables:
  404. * tab-width: 4
  405. * c-basic-offset: 4
  406. * End:
  407. * vim600: sw=4 ts=4 fdm=marker
  408. * vim<600: sw=4 ts=4
  409. */