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.

450 lines
13 KiB

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP version 4.0 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997, 1998, 1999, 2000 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.01 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_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@guardian.no> |
  17. | David Sklar <sklar@student.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id$ */
  21. #define NO_REGEX_EXTRA_H
  22. #include "php.h"
  23. #include "ext/standard/head.h"
  24. #include "php_globals.h"
  25. #include "php_ini.h"
  26. #include "SAPI.h"
  27. #include "mod_php4.h"
  28. #include "ext/standard/info.h"
  29. #include <stdlib.h>
  30. #if HAVE_UNISTD_H
  31. #include <unistd.h>
  32. #endif
  33. #include <string.h>
  34. #include <errno.h>
  35. #include <ctype.h>
  36. #include "php_apache_http.h"
  37. #include "http_request.h"
  38. #include "build-defs.h"
  39. #define SECTION(name) PUTS("<hr><h2>" name "</h2>\n")
  40. extern module *top_module;
  41. PHP_FUNCTION(virtual);
  42. PHP_FUNCTION(getallheaders);
  43. PHP_FUNCTION(apachelog);
  44. PHP_FUNCTION(apache_note);
  45. PHP_FUNCTION(apache_lookup_uri);
  46. PHP_MINFO_FUNCTION(apache);
  47. function_entry apache_functions[] = {
  48. PHP_FE(virtual, NULL)
  49. PHP_FE(getallheaders, NULL)
  50. PHP_FE(apache_note, NULL)
  51. PHP_FE(apache_lookup_uri, NULL)
  52. {NULL, NULL, NULL}
  53. };
  54. static PHP_INI_MH(OnChangeApacheInt)
  55. {
  56. long *p;
  57. char *base = (char *) &php_apache_info;
  58. p = (long *) (base+(size_t) mh_arg1);
  59. if (new_value) {
  60. *p = atoi(new_value);
  61. return SUCCESS;
  62. } else {
  63. return FAILURE;
  64. }
  65. }
  66. static PHP_INI_MH(OnChangeApacheString)
  67. {
  68. char **p;
  69. char *base = (char *) &php_apache_info;
  70. p = (char **) (base+(size_t) mh_arg1);
  71. if (new_value) {
  72. *p = new_value;
  73. return SUCCESS;
  74. } else {
  75. return FAILURE;
  76. }
  77. }
  78. PHP_INI_BEGIN()
  79. PHP_INI_ENTRY1("xbithack", "0", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, xbithack))
  80. PHP_INI_ENTRY1("engine", "1", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, engine))
  81. PHP_INI_ENTRY1("last_modified", "0", PHP_INI_ALL, OnChangeApacheInt, (void *) XtOffsetOf(php_apache_info_struct, last_modified))
  82. PHP_INI_ENTRY1("dav_script", NULL, PHP_INI_ALL, OnChangeApacheString, (void *) XtOffsetOf(php_apache_info_struct, dav_script))
  83. PHP_INI_END()
  84. static PHP_MINIT_FUNCTION(apache)
  85. {
  86. REGISTER_INI_ENTRIES();
  87. return SUCCESS;
  88. }
  89. static PHP_MSHUTDOWN_FUNCTION(apache)
  90. {
  91. UNREGISTER_INI_ENTRIES();
  92. return SUCCESS;
  93. }
  94. zend_module_entry apache_module_entry = {
  95. "apache", apache_functions, PHP_MINIT(apache), PHP_MSHUTDOWN(apache), NULL, NULL, PHP_MINFO(apache), STANDARD_MODULE_PROPERTIES
  96. };
  97. /* {{{ proto string apache_note(string note_name [, string note_value])
  98. Get and set Apache request notes */
  99. PHP_FUNCTION(apache_note)
  100. {
  101. pval **arg_name,**arg_val;
  102. char *note_val;
  103. int arg_count = ARG_COUNT(ht);
  104. SLS_FETCH();
  105. if (arg_count<1 || arg_count>2 ||
  106. zend_get_parameters_ex(arg_count,&arg_name,&arg_val) ==FAILURE ) {
  107. WRONG_PARAM_COUNT;
  108. }
  109. convert_to_string_ex(arg_name);
  110. note_val = (char *) table_get(((request_rec *)SG(server_context))->notes,(*arg_name)->value.str.val);
  111. if (arg_count == 2) {
  112. convert_to_string_ex(arg_val);
  113. table_set(((request_rec *)SG(server_context))->notes,(*arg_name)->value.str.val,(*arg_val)->value.str.val);
  114. }
  115. if (note_val) {
  116. RETURN_STRING(note_val,1);
  117. } else {
  118. RETURN_FALSE;
  119. }
  120. }
  121. /* }}} */
  122. PHP_MINFO_FUNCTION(apache)
  123. {
  124. module *modp = NULL;
  125. char output_buf[128];
  126. #if !defined(WIN32) && !defined(WINNT)
  127. char name[64];
  128. char *p;
  129. #endif
  130. server_rec *serv;
  131. extern char server_root[MAX_STRING_LEN];
  132. extern uid_t user_id;
  133. extern char *user_name;
  134. extern gid_t group_id;
  135. extern int max_requests_per_child;
  136. SLS_FETCH();
  137. serv = ((request_rec *) SG(server_context))->server;
  138. PUTS("<table border=5 width=\"600\">\n");
  139. php_info_print_table_header(2, "Entry", "Value");
  140. #if WIN32|WINNT
  141. PUTS("Apache for Windows 95/NT<br>");
  142. #else
  143. php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE);
  144. php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET);
  145. #endif
  146. php_info_print_table_row(2, "Apache Version", SERVER_VERSION);
  147. #ifdef APACHE_RELEASE
  148. sprintf(output_buf, "%d", APACHE_RELEASE);
  149. php_info_print_table_row(2, "Apache Release", output_buf);
  150. #endif
  151. sprintf(output_buf, "%d", MODULE_MAGIC_NUMBER);
  152. php_info_print_table_row(2, "Apache API Version", output_buf);
  153. sprintf(output_buf, "%s:%u", serv->server_hostname,serv->port);
  154. php_info_print_table_row(2, "Hostname/Port", output_buf);
  155. #if !defined(WIN32) && !defined(WINNT)
  156. sprintf(output_buf, "%s(%d)/%d", user_name,(int)user_id,(int)group_id);
  157. php_info_print_table_row(2, "User/Group", output_buf);
  158. sprintf(output_buf, "per child: %d<br>keep alive: %s<br>max per connection: %d",max_requests_per_child,serv->keep_alive ? "on":"off", serv->keep_alive_max);
  159. php_info_print_table_row(2, "Max Requests", output_buf);
  160. #endif
  161. sprintf(output_buf, "connection: %d<br>keep-alive: %d",serv->timeout,serv->keep_alive_timeout);
  162. php_info_print_table_row(2, "Timeouts", output_buf);
  163. #if !defined(WIN32) && !defined(WINNT)
  164. php_info_print_table_row(2, "Server Root", server_root);
  165. PUTS("<tr><td valign=\"top\" bgcolor=\"" PHP_ENTRY_NAME_COLOR "\">Loaded modules</td><td bgcolor=\"" PHP_CONTENTS_COLOR "\">");
  166. for(modp = top_module; modp; modp = modp->next) {
  167. strlcpy(name, modp->name, sizeof(name));
  168. if ((p = strrchr(name, '.'))) {
  169. *p='\0'; /* Cut off ugly .c extensions on module names */
  170. }
  171. PUTS(name);
  172. if (modp->next) {
  173. PUTS(", ");
  174. }
  175. }
  176. #endif
  177. PUTS("</td></tr>\n");
  178. PUTS("</table>\n");
  179. {
  180. register int i;
  181. array_header *arr;
  182. table_entry *elts;
  183. request_rec *r;
  184. SLS_FETCH();
  185. r = ((request_rec *) SG(server_context));
  186. arr = table_elts(r->subprocess_env);
  187. elts = (table_entry *)arr->elts;
  188. SECTION("Apache Environment");
  189. PUTS("<table border=5 width=\"600\">\n");
  190. php_info_print_table_header(2, "Variable", "Value");
  191. for (i=0; i < arr->nelts; i++) {
  192. php_info_print_table_row(2, elts[i].key, elts[i].val);
  193. }
  194. PUTS("</table>\n");
  195. }
  196. {
  197. array_header *env_arr;
  198. table_entry *env;
  199. int i;
  200. request_rec *r;
  201. SLS_FETCH();
  202. r = ((request_rec *) SG(server_context));
  203. SECTION("HTTP Headers Information");
  204. PUTS("<table border=5 width=\"600\">\n");
  205. PUTS(" <tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Request Headers</th></tr>\n");
  206. php_info_print_table_row(2, "HTTP Request", r->the_request);
  207. env_arr = table_elts(r->headers_in);
  208. env = (table_entry *)env_arr->elts;
  209. for (i = 0; i < env_arr->nelts; ++i) {
  210. if (env[i].key) {
  211. php_info_print_table_row(2, env[i].key, env[i].val);
  212. }
  213. }
  214. PUTS(" <tr><th colspan=2 bgcolor=\"" PHP_HEADER_COLOR "\">HTTP Response Headers</th></tr>\n");
  215. env_arr = table_elts(r->headers_out);
  216. env = (table_entry *)env_arr->elts;
  217. for(i = 0; i < env_arr->nelts; ++i) {
  218. if (env[i].key) {
  219. php_info_print_table_row(2, env[i].key, env[i].val);
  220. }
  221. }
  222. PUTS("</table>\n\n");
  223. }
  224. }
  225. /* This function is equivalent to <!--#include virtual...-->
  226. * in mod_include. It does an Apache sub-request. It is useful
  227. * for including CGI scripts or .shtml files, or anything else
  228. * that you'd parse through Apache (for .phtml files, you'd probably
  229. * want to use <?Include>. This only works when PHP is compiled
  230. * as an Apache module, since it uses the Apache API for doing
  231. * sub requests.
  232. */
  233. /* {{{ proto int virtual(string filename)
  234. Perform an Apache sub-request */
  235. PHP_FUNCTION(virtual)
  236. {
  237. pval **filename;
  238. request_rec *rr = NULL;
  239. SLS_FETCH();
  240. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1,&filename) == FAILURE) {
  241. WRONG_PARAM_COUNT;
  242. }
  243. convert_to_string_ex(filename);
  244. if (!(rr = sub_req_lookup_uri ((*filename)->value.str.val,((request_rec *) SG(server_context))))) {
  245. php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", (*filename)->value.str.val);
  246. if (rr) destroy_sub_req (rr);
  247. RETURN_FALSE;
  248. }
  249. if (rr->status != 200) {
  250. php_error(E_WARNING, "Unable to include '%s' - error finding URI", (*filename)->value.str.val);
  251. if (rr) destroy_sub_req (rr);
  252. RETURN_FALSE;
  253. }
  254. /* Cannot include another PHP file because of global conflicts */
  255. if (rr->content_type &&
  256. !strcmp(rr->content_type, PHP_MIME_TYPE)) {
  257. php_error(E_WARNING, "Cannot include a PHP file "
  258. "(use <code>&lt;?include \"%s\"&gt;</code> instead)", (*filename)->value.str.val);
  259. if (rr) destroy_sub_req (rr);
  260. RETURN_FALSE;
  261. }
  262. if (run_sub_req(rr)) {
  263. php_error(E_WARNING, "Unable to include '%s' - request execution failed", (*filename)->value.str.val);
  264. if (rr) destroy_sub_req (rr);
  265. RETURN_FALSE;
  266. } else {
  267. if (rr) destroy_sub_req (rr);
  268. RETURN_TRUE;
  269. }
  270. }
  271. /* }}} */
  272. /* {{{ proto array getallheaders(void)
  273. Fetch all HTTP request headers */
  274. PHP_FUNCTION(getallheaders)
  275. {
  276. array_header *env_arr;
  277. table_entry *tenv;
  278. int i;
  279. SLS_FETCH();
  280. PLS_FETCH();
  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 class apache_lookup_uri(string URI)
  299. Perform a partial request of the given URI to obtain information about it */
  300. PHP_FUNCTION(apache_lookup_uri)
  301. {
  302. pval **filename;
  303. request_rec *rr=NULL;
  304. SLS_FETCH();
  305. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1,&filename) == FAILURE) {
  306. WRONG_PARAM_COUNT;
  307. }
  308. convert_to_string_ex(filename);
  309. if(!(rr = sub_req_lookup_uri((*filename)->value.str.val,((request_rec *) SG(server_context))))) {
  310. php_error(E_WARNING, "URI lookup failed",(*filename)->value.str.val);
  311. RETURN_FALSE;
  312. }
  313. object_init(return_value);
  314. add_property_long(return_value,"status",rr->status);
  315. if (rr->the_request) {
  316. add_property_string(return_value,"the_request",rr->the_request,1);
  317. }
  318. if (rr->status_line) {
  319. add_property_string(return_value,"status_line",(char *)rr->status_line,1);
  320. }
  321. if (rr->method) {
  322. add_property_string(return_value,"method",(char *)rr->method,1);
  323. }
  324. if (rr->content_type) {
  325. add_property_string(return_value,"content_type",(char *)rr->content_type,1);
  326. }
  327. if (rr->handler) {
  328. add_property_string(return_value,"handler",(char *)rr->handler,1);
  329. }
  330. if (rr->uri) {
  331. add_property_string(return_value,"uri",rr->uri,1);
  332. }
  333. if (rr->filename) {
  334. add_property_string(return_value,"filename",rr->filename,1);
  335. }
  336. if (rr->path_info) {
  337. add_property_string(return_value,"path_info",rr->path_info,1);
  338. }
  339. if (rr->args) {
  340. add_property_string(return_value,"args",rr->args,1);
  341. }
  342. if (rr->boundary) {
  343. add_property_string(return_value,"boundary",rr->boundary,1);
  344. }
  345. add_property_long(return_value,"no_cache",rr->no_cache);
  346. add_property_long(return_value,"no_local_copy",rr->no_local_copy);
  347. add_property_long(return_value,"allowed",rr->allowed);
  348. add_property_long(return_value,"sent_bodyct",rr->sent_bodyct);
  349. add_property_long(return_value,"bytes_sent",rr->bytes_sent);
  350. add_property_long(return_value,"byterange",rr->byterange);
  351. add_property_long(return_value,"clength",rr->clength);
  352. #if MODULE_MAGIC_NUMBER >= 19980324
  353. if (rr->unparsed_uri) {
  354. add_property_string(return_value,"unparsed_uri",rr->unparsed_uri,1);
  355. }
  356. if(rr->mtime) {
  357. add_property_long(return_value,"mtime",rr->mtime);
  358. }
  359. #endif
  360. if(rr->request_time) {
  361. add_property_long(return_value,"request_time",rr->request_time);
  362. }
  363. destroy_sub_req(rr);
  364. }
  365. /* }}} */
  366. #if 0
  367. This function is most likely a bad idea. Just playing with it for now.
  368. PHP_FUNCTION(apache_exec_uri)
  369. {
  370. pval **filename;
  371. request_rec *rr=NULL;
  372. SLS_FETCH();
  373. if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1,&filename) == FAILURE) {
  374. WRONG_PARAM_COUNT;
  375. }
  376. convert_to_string_ex(filename);
  377. if(!(rr = ap_sub_req_lookup_uri((*filename)->value.str.val,((request_rec *) SG(server_context))))) {
  378. php_error(E_WARNING, "URI lookup failed",(*filename)->value.str.val);
  379. RETURN_FALSE;
  380. }
  381. RETVAL_LONG(ap_run_sub_req(rr));
  382. ap_destroy_sub_req(rr);
  383. }
  384. #endif
  385. /*
  386. * Local variables:
  387. * tab-width: 4
  388. * c-basic-offset: 4
  389. * End:
  390. */