phttpd.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 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. | Author: Thies C. Arntzen <thies@thieso.net> |
  16. | Based on aolserver SAPI by Sascha Schumann <sascha@schumann.cx> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "php.h"
  20. #include "SAPI.h"
  21. #include "php_main.h"
  22. #ifdef HAVE_PHTTPD
  23. #include "ext/standard/info.h"
  24. #ifndef ZTS
  25. #error PHTTPD module is only useable in thread-safe mode
  26. #endif
  27. #include "php_phttpd.h"
  28. typedef struct {
  29. struct connectioninfo *cip;
  30. struct stat sb;
  31. } phttpd_globals_struct;
  32. static int ph_globals_id;
  33. #define PHG(v) TSRMG(ph_globals_id, phttpd_globals_struct *, v)
  34. static int
  35. php_phttpd_startup(sapi_module_struct *sapi_module)
  36. {
  37. fprintf(stderr,"***php_phttpd_startup\n");
  38. if (php_module_startup(sapi_module, NULL, 0)) {
  39. return FAILURE;
  40. } else {
  41. return SUCCESS;
  42. }
  43. }
  44. static int
  45. php_phttpd_sapi_ub_write(const char *str, uint str_length TSRMLS_DC)
  46. {
  47. int sent_bytes;
  48. sent_bytes = fd_write(PHG(cip)->fd, str, str_length);
  49. if (sent_bytes == -1) {
  50. php_handle_aborted_connection();
  51. }
  52. return sent_bytes;
  53. }
  54. static int
  55. php_phttpd_sapi_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC)
  56. {
  57. char *header_name, *header_content;
  58. char *p;
  59. http_sendheaders(PHG(cip)->fd, PHG(cip), SG(sapi_headers).http_response_code, NULL);
  60. header_name = sapi_header->header;
  61. header_content = p = strchr(header_name, ':');
  62. if (p) {
  63. *p = '\0';
  64. do {
  65. header_content++;
  66. } while (*header_content == ' ');
  67. fd_printf(PHG(cip)->fd,"%s: %s\n", header_name, header_content);
  68. *p = ':';
  69. }
  70. sapi_free_header(sapi_header);
  71. return 0;
  72. }
  73. static int
  74. php_phttpd_sapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
  75. {
  76. if (SG(sapi_headers).send_default_content_type) {
  77. fd_printf(PHG(cip)->fd,"Content-Type: text/html\n");
  78. }
  79. fd_putc('\n', PHG(cip)->fd);
  80. return SAPI_HEADER_SENT_SUCCESSFULLY;
  81. }
  82. static char *
  83. php_phttpd_sapi_read_cookies(TSRMLS_D)
  84. {
  85. /*
  86. int i;
  87. char *http_cookie = NULL;
  88. i = Ns_SetIFind(NSG(conn->headers), "cookie");
  89. if(i != -1) {
  90. http_cookie = Ns_SetValue(NSG(conn->headers), i);
  91. }
  92. return http_cookie;
  93. */
  94. fprintf(stderr,"***php_phttpd_sapi_read_cookies\n");
  95. return 0;
  96. }
  97. static int
  98. php_phttpd_sapi_read_post(char *buf, uint count_bytes TSRMLS_DC)
  99. {
  100. /*
  101. uint max_read;
  102. uint total_read = 0;
  103. max_read = MIN(NSG(data_avail), count_bytes);
  104. total_read = Ns_ConnRead(NSG(conn), buf, max_read);
  105. if(total_read == NS_ERROR) {
  106. total_read = -1;
  107. } else {
  108. NSG(data_avail) -= total_read;
  109. }
  110. return total_read;
  111. */
  112. fprintf(stderr,"***php_phttpd_sapi_read_post\n");
  113. return 0;
  114. }
  115. static sapi_module_struct phttpd_sapi_module = {
  116. "phttpd",
  117. "PHTTPD",
  118. php_phttpd_startup, /* startup */
  119. php_module_shutdown_wrapper, /* shutdown */
  120. NULL, /* activate */
  121. NULL, /* deactivate */
  122. php_phttpd_sapi_ub_write, /* unbuffered write */
  123. NULL, /* flush */
  124. NULL, /* get uid */
  125. NULL, /* getenv */
  126. php_error, /* error handler */
  127. php_phttpd_sapi_header_handler, /* header handler */
  128. php_phttpd_sapi_send_headers, /* send headers handler */
  129. NULL, /* send header handler */
  130. php_phttpd_sapi_read_post, /* read POST data */
  131. php_phttpd_sapi_read_cookies, /* read Cookies */
  132. NULL, /* register server variables */
  133. NULL, /* Log message */
  134. NULL, /* Get request time */
  135. NULL, /* Child terminate */
  136. STANDARD_SAPI_MODULE_PROPERTIES
  137. };
  138. static void
  139. php_phttpd_request_ctor(TSRMLS_D TSRMLS_DC)
  140. {
  141. memset(&SG(request_info), 0, sizeof(sapi_globals_struct)); /* pfusch! */
  142. SG(request_info).query_string = PHG(cip)->hip->request;
  143. SG(request_info).request_method = PHG(cip)->hip->method;
  144. SG(request_info).path_translated = malloc(MAXPATHLEN);
  145. SG(sapi_headers).http_response_code = 200;
  146. if (url_expand(PHG(cip)->hip->url, SG(request_info).path_translated, MAXPATHLEN, &PHG(sb), NULL, NULL) == NULL) {
  147. /* handle error */
  148. }
  149. #if 0
  150. char *server;
  151. Ns_DString ds;
  152. char *root;
  153. int index;
  154. char *tmp;
  155. server = Ns_ConnServer(NSG(conn));
  156. Ns_DStringInit(&ds);
  157. Ns_UrlToFile(&ds, server, NSG(conn->request->url));
  158. /* path_translated is the absolute path to the file */
  159. SG(request_info).path_translated = strdup(Ns_DStringValue(&ds));
  160. Ns_DStringFree(&ds);
  161. root = Ns_PageRoot(server);
  162. SG(request_info).request_uri = SG(request_info).path_translated + strlen(root);
  163. SG(request_info).content_length = Ns_ConnContentLength(NSG(conn));
  164. index = Ns_SetIFind(NSG(conn)->headers, "content-type");
  165. SG(request_info).content_type = index == -1 ? NULL :
  166. Ns_SetValue(NSG(conn)->headers, index);
  167. tmp = Ns_ConnAuthUser(NSG(conn));
  168. if(tmp) {
  169. tmp = estrdup(tmp);
  170. }
  171. SG(request_info).auth_user = tmp;
  172. tmp = Ns_ConnAuthPasswd(NSG(conn));
  173. if(tmp) {
  174. tmp = estrdup(tmp);
  175. }
  176. SG(request_info).auth_password = tmp;
  177. NSG(data_avail) = SG(request_info).content_length;
  178. #endif
  179. }
  180. static void
  181. php_phttpd_request_dtor(TSRMLS_D TSRMLS_DC)
  182. {
  183. free(SG(request_info).path_translated);
  184. }
  185. int php_doit(TSRMLS_D)
  186. {
  187. struct stat sb;
  188. zend_file_handle file_handle;
  189. struct httpinfo *hip = PHG(cip)->hip;
  190. if (php_request_startup(TSRMLS_C) == FAILURE) {
  191. return -1;
  192. }
  193. file_handle.type = ZEND_HANDLE_FILENAME;
  194. file_handle.filename = SG(request_info).path_translated;
  195. file_handle.free_filename = 0;
  196. /*
  197. php_phttpd_hash_environment(TSRMLS_C);
  198. */
  199. php_execute_script(&file_handle TSRMLS_CC);
  200. php_request_shutdown(NULL);
  201. return SG(sapi_headers).http_response_code;
  202. }
  203. int pm_init(const char **argv)
  204. {
  205. tsrm_startup(1, 1, 0, NULL);
  206. sapi_startup(&phttpd_sapi_module);
  207. phttpd_sapi_module.startup(&phttpd_sapi_module);
  208. ts_allocate_id(&ph_globals_id, sizeof(phttpd_globals_struct), NULL, NULL);
  209. return 0;
  210. }
  211. void pm_exit(void)
  212. {
  213. fprintf(stderr,"***pm_exit\n");
  214. }
  215. int pm_request(struct connectioninfo *cip)
  216. {
  217. struct httpinfo *hip = cip->hip;
  218. int status;
  219. TSRMLS_FETCH();
  220. if (strcasecmp(hip->method, "GET") == 0 ||
  221. strcasecmp(hip->method, "HEAD") == 0 ||
  222. strcasecmp(hip->method, "POST") == 0) {
  223. PHG(cip) = cip;
  224. php_phttpd_request_ctor(TSRMLS_C);
  225. status = php_doit(TSRMLS_C);
  226. php_phttpd_request_dtor(TSRMLS_C);
  227. return status;
  228. } else {
  229. return -2;
  230. }
  231. }
  232. #endif