SAPI.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Copyright (c) The PHP Group |
  4. +----------------------------------------------------------------------+
  5. | This source file is subject to version 3.01 of the PHP license, |
  6. | that is bundled with this package in the file LICENSE, and is |
  7. | available through the world-wide-web at the following url: |
  8. | https://www.php.net/license/3_01.txt |
  9. | If you did not receive a copy of the PHP license and are unable to |
  10. | obtain it through the world-wide-web, please send a note to |
  11. | license@php.net so we can mail you a copy immediately. |
  12. +----------------------------------------------------------------------+
  13. | Original design: Shane Caraveo <shane@caraveo.com> |
  14. | Authors: Andi Gutmans <andi@php.net> |
  15. | Zeev Suraski <zeev@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #include <ctype.h>
  19. #include <sys/stat.h>
  20. #include "php.h"
  21. #include "SAPI.h"
  22. #include "php_variables.h"
  23. #include "php_ini.h"
  24. #include "ext/standard/php_string.h"
  25. #include "ext/standard/pageinfo.h"
  26. #include "ext/pcre/php_pcre.h"
  27. #ifdef ZTS
  28. #include "TSRM.h"
  29. #endif
  30. #ifdef HAVE_SYS_TIME_H
  31. #include <sys/time.h>
  32. #elif defined(PHP_WIN32)
  33. #include "win32/time.h"
  34. #endif
  35. #include "rfc1867.h"
  36. #include "php_content_types.h"
  37. #ifdef ZTS
  38. SAPI_API int sapi_globals_id;
  39. SAPI_API size_t sapi_globals_offset;
  40. #else
  41. sapi_globals_struct sapi_globals;
  42. #endif
  43. static void _type_dtor(zval *zv)
  44. {
  45. free(Z_PTR_P(zv));
  46. }
  47. static void sapi_globals_ctor(sapi_globals_struct *sapi_globals)
  48. {
  49. memset(sapi_globals, 0, sizeof(*sapi_globals));
  50. zend_hash_init(&sapi_globals->known_post_content_types, 8, NULL, _type_dtor, 1);
  51. php_setup_sapi_content_types();
  52. }
  53. static void sapi_globals_dtor(sapi_globals_struct *sapi_globals)
  54. {
  55. zend_hash_destroy(&sapi_globals->known_post_content_types);
  56. }
  57. /* True globals (no need for thread safety) */
  58. SAPI_API sapi_module_struct sapi_module;
  59. SAPI_API void sapi_startup(sapi_module_struct *sf)
  60. {
  61. sf->ini_entries = NULL;
  62. sapi_module = *sf;
  63. #ifdef ZTS
  64. ts_allocate_fast_id(&sapi_globals_id, &sapi_globals_offset, sizeof(sapi_globals_struct), (ts_allocate_ctor) sapi_globals_ctor, (ts_allocate_dtor) sapi_globals_dtor);
  65. # ifdef PHP_WIN32
  66. _configthreadlocale(_ENABLE_PER_THREAD_LOCALE);
  67. # endif
  68. #else
  69. sapi_globals_ctor(&sapi_globals);
  70. #endif
  71. #ifdef PHP_WIN32
  72. tsrm_win32_startup();
  73. #endif
  74. reentrancy_startup();
  75. }
  76. SAPI_API void sapi_shutdown(void)
  77. {
  78. #ifdef ZTS
  79. ts_free_id(sapi_globals_id);
  80. #else
  81. sapi_globals_dtor(&sapi_globals);
  82. #endif
  83. reentrancy_shutdown();
  84. #ifdef PHP_WIN32
  85. tsrm_win32_shutdown();
  86. #endif
  87. }
  88. SAPI_API void sapi_free_header(sapi_header_struct *sapi_header)
  89. {
  90. efree(sapi_header->header);
  91. }
  92. /* {{{ call a header function */
  93. PHP_FUNCTION(header_register_callback)
  94. {
  95. zend_fcall_info fci;
  96. zend_fcall_info_cache fcc;
  97. if (zend_parse_parameters(ZEND_NUM_ARGS(), "f", &fci, &fcc) == FAILURE) {
  98. RETURN_THROWS();
  99. }
  100. if (Z_TYPE(SG(callback_func)) != IS_UNDEF) {
  101. zval_ptr_dtor(&SG(callback_func));
  102. SG(fci_cache) = empty_fcall_info_cache;
  103. }
  104. /* Don't store callback if headers have already been sent:
  105. * It won't get used and we won't have a chance to release it. */
  106. if (!SG(headers_sent)) {
  107. ZVAL_COPY(&SG(callback_func), &fci.function_name);
  108. }
  109. RETURN_TRUE;
  110. }
  111. /* }}} */
  112. static void sapi_run_header_callback(zval *callback)
  113. {
  114. int error;
  115. zend_fcall_info fci;
  116. char *callback_error = NULL;
  117. zval retval;
  118. if (zend_fcall_info_init(callback, 0, &fci, &SG(fci_cache), NULL, &callback_error) == SUCCESS) {
  119. fci.retval = &retval;
  120. error = zend_call_function(&fci, &SG(fci_cache));
  121. if (error == FAILURE) {
  122. goto callback_failed;
  123. } else {
  124. zval_ptr_dtor(&retval);
  125. }
  126. } else {
  127. callback_failed:
  128. php_error_docref(NULL, E_WARNING, "Could not call the sapi_header_callback");
  129. }
  130. if (callback_error) {
  131. efree(callback_error);
  132. }
  133. }
  134. SAPI_API void sapi_handle_post(void *arg)
  135. {
  136. if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
  137. SG(request_info).post_entry->post_handler(SG(request_info).content_type_dup, arg);
  138. efree(SG(request_info).content_type_dup);
  139. SG(request_info).content_type_dup = NULL;
  140. }
  141. }
  142. static void sapi_read_post_data(void)
  143. {
  144. sapi_post_entry *post_entry;
  145. uint32_t content_type_length = (uint32_t)strlen(SG(request_info).content_type);
  146. char *content_type = estrndup(SG(request_info).content_type, content_type_length);
  147. char *p;
  148. char oldchar=0;
  149. void (*post_reader_func)(void) = NULL;
  150. /* dedicated implementation for increased performance:
  151. * - Make the content type lowercase
  152. * - Trim descriptive data, stay with the content-type only
  153. */
  154. for (p=content_type; p<content_type+content_type_length; p++) {
  155. switch (*p) {
  156. case ';':
  157. case ',':
  158. case ' ':
  159. content_type_length = p-content_type;
  160. oldchar = *p;
  161. *p = 0;
  162. break;
  163. default:
  164. *p = tolower(*p);
  165. break;
  166. }
  167. }
  168. /* now try to find an appropriate POST content handler */
  169. if ((post_entry = zend_hash_str_find_ptr(&SG(known_post_content_types), content_type,
  170. content_type_length)) != NULL) {
  171. /* found one, register it for use */
  172. SG(request_info).post_entry = post_entry;
  173. post_reader_func = post_entry->post_reader;
  174. } else {
  175. /* fallback */
  176. SG(request_info).post_entry = NULL;
  177. if (!sapi_module.default_post_reader) {
  178. /* no default reader ? */
  179. SG(request_info).content_type_dup = NULL;
  180. sapi_module.sapi_error(E_WARNING, "Unsupported content type: '%s'", content_type);
  181. return;
  182. }
  183. }
  184. if (oldchar) {
  185. *(p-1) = oldchar;
  186. }
  187. SG(request_info).content_type_dup = content_type;
  188. if(post_reader_func) {
  189. post_reader_func();
  190. }
  191. if(sapi_module.default_post_reader) {
  192. sapi_module.default_post_reader();
  193. }
  194. }
  195. SAPI_API size_t sapi_read_post_block(char *buffer, size_t buflen)
  196. {
  197. size_t read_bytes;
  198. if (!sapi_module.read_post) {
  199. return 0;
  200. }
  201. read_bytes = sapi_module.read_post(buffer, buflen);
  202. if (read_bytes > 0) {
  203. /* gogo */
  204. SG(read_post_bytes) += read_bytes;
  205. }
  206. if (read_bytes < buflen) {
  207. /* done */
  208. SG(post_read) = 1;
  209. }
  210. return read_bytes;
  211. }
  212. SAPI_API SAPI_POST_READER_FUNC(sapi_read_standard_form_data)
  213. {
  214. if ((SG(post_max_size) > 0) && (SG(request_info).content_length > SG(post_max_size))) {
  215. php_error_docref(NULL, E_WARNING, "POST Content-Length of " ZEND_LONG_FMT " bytes exceeds the limit of " ZEND_LONG_FMT " bytes",
  216. SG(request_info).content_length, SG(post_max_size));
  217. return;
  218. }
  219. SG(request_info).request_body = php_stream_temp_create_ex(TEMP_STREAM_DEFAULT, SAPI_POST_BLOCK_SIZE, PG(upload_tmp_dir));
  220. if (sapi_module.read_post) {
  221. size_t read_bytes;
  222. for (;;) {
  223. char buffer[SAPI_POST_BLOCK_SIZE];
  224. read_bytes = sapi_read_post_block(buffer, SAPI_POST_BLOCK_SIZE);
  225. if (read_bytes > 0) {
  226. if (php_stream_write(SG(request_info).request_body, buffer, read_bytes) != read_bytes) {
  227. /* if parts of the stream can't be written, purge it completely */
  228. php_stream_truncate_set_size(SG(request_info).request_body, 0);
  229. php_error_docref(NULL, E_WARNING, "POST data can't be buffered; all data discarded");
  230. break;
  231. }
  232. }
  233. if ((SG(post_max_size) > 0) && (SG(read_post_bytes) > SG(post_max_size))) {
  234. php_error_docref(NULL, E_WARNING, "Actual POST length does not match Content-Length, and exceeds " ZEND_LONG_FMT " bytes", SG(post_max_size));
  235. break;
  236. }
  237. if (read_bytes < SAPI_POST_BLOCK_SIZE) {
  238. /* done */
  239. break;
  240. }
  241. }
  242. php_stream_rewind(SG(request_info).request_body);
  243. }
  244. }
  245. static inline char *get_default_content_type(uint32_t prefix_len, uint32_t *len)
  246. {
  247. char *mimetype, *charset, *content_type;
  248. uint32_t mimetype_len, charset_len;
  249. if (SG(default_mimetype)) {
  250. mimetype = SG(default_mimetype);
  251. mimetype_len = (uint32_t)strlen(SG(default_mimetype));
  252. } else {
  253. mimetype = SAPI_DEFAULT_MIMETYPE;
  254. mimetype_len = sizeof(SAPI_DEFAULT_MIMETYPE) - 1;
  255. }
  256. if (SG(default_charset)) {
  257. charset = SG(default_charset);
  258. charset_len = (uint32_t)strlen(SG(default_charset));
  259. } else {
  260. charset = SAPI_DEFAULT_CHARSET;
  261. charset_len = sizeof(SAPI_DEFAULT_CHARSET) - 1;
  262. }
  263. if (*charset && strncasecmp(mimetype, "text/", 5) == 0) {
  264. char *p;
  265. *len = prefix_len + mimetype_len + sizeof("; charset=") - 1 + charset_len;
  266. content_type = (char*)emalloc(*len + 1);
  267. p = content_type + prefix_len;
  268. memcpy(p, mimetype, mimetype_len);
  269. p += mimetype_len;
  270. memcpy(p, "; charset=", sizeof("; charset=") - 1);
  271. p += sizeof("; charset=") - 1;
  272. memcpy(p, charset, charset_len + 1);
  273. } else {
  274. *len = prefix_len + mimetype_len;
  275. content_type = (char*)emalloc(*len + 1);
  276. memcpy(content_type + prefix_len, mimetype, mimetype_len + 1);
  277. }
  278. return content_type;
  279. }
  280. SAPI_API char *sapi_get_default_content_type(void)
  281. {
  282. uint32_t len;
  283. return get_default_content_type(0, &len);
  284. }
  285. SAPI_API void sapi_get_default_content_type_header(sapi_header_struct *default_header)
  286. {
  287. uint32_t len;
  288. default_header->header = get_default_content_type(sizeof("Content-type: ")-1, &len);
  289. default_header->header_len = len;
  290. memcpy(default_header->header, "Content-type: ", sizeof("Content-type: ") - 1);
  291. }
  292. /*
  293. * Add charset on content-type header if the MIME type starts with
  294. * "text/", the default_charset directive is not empty and
  295. * there is not already a charset option in there.
  296. *
  297. * If "mimetype" is non-NULL, it should point to a pointer allocated
  298. * with emalloc(). If a charset is added, the string will be
  299. * re-allocated and the new length is returned. If mimetype is
  300. * unchanged, 0 is returned.
  301. *
  302. */
  303. SAPI_API size_t sapi_apply_default_charset(char **mimetype, size_t len)
  304. {
  305. char *charset, *newtype;
  306. size_t newlen;
  307. charset = SG(default_charset) ? SG(default_charset) : SAPI_DEFAULT_CHARSET;
  308. if (*mimetype != NULL) {
  309. if (*charset && strncmp(*mimetype, "text/", 5) == 0 && strstr(*mimetype, "charset=") == NULL) {
  310. newlen = len + (sizeof(";charset=")-1) + strlen(charset);
  311. newtype = emalloc(newlen + 1);
  312. PHP_STRLCPY(newtype, *mimetype, newlen + 1, len);
  313. strlcat(newtype, ";charset=", newlen + 1);
  314. strlcat(newtype, charset, newlen + 1);
  315. efree(*mimetype);
  316. *mimetype = newtype;
  317. return newlen;
  318. }
  319. }
  320. return 0;
  321. }
  322. SAPI_API void sapi_activate_headers_only(void)
  323. {
  324. if (SG(request_info).headers_read == 1)
  325. return;
  326. SG(request_info).headers_read = 1;
  327. zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct),
  328. (void (*)(void *)) sapi_free_header, 0);
  329. SG(sapi_headers).send_default_content_type = 1;
  330. /* SG(sapi_headers).http_response_code = 200; */
  331. SG(sapi_headers).http_status_line = NULL;
  332. SG(sapi_headers).mimetype = NULL;
  333. SG(read_post_bytes) = 0;
  334. SG(request_info).request_body = NULL;
  335. SG(request_info).current_user = NULL;
  336. SG(request_info).current_user_length = 0;
  337. SG(request_info).no_headers = 0;
  338. SG(request_info).post_entry = NULL;
  339. SG(global_request_time) = 0;
  340. /*
  341. * It's possible to override this general case in the activate() callback,
  342. * if necessary.
  343. */
  344. if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
  345. SG(request_info).headers_only = 1;
  346. } else {
  347. SG(request_info).headers_only = 0;
  348. }
  349. if (SG(server_context)) {
  350. SG(request_info).cookie_data = sapi_module.read_cookies();
  351. if (sapi_module.activate) {
  352. sapi_module.activate();
  353. }
  354. }
  355. if (sapi_module.input_filter_init ) {
  356. sapi_module.input_filter_init();
  357. }
  358. }
  359. /*
  360. * Called from php_request_startup() for every request.
  361. */
  362. SAPI_API void sapi_activate(void)
  363. {
  364. zend_llist_init(&SG(sapi_headers).headers, sizeof(sapi_header_struct), (void (*)(void *)) sapi_free_header, 0);
  365. SG(sapi_headers).send_default_content_type = 1;
  366. /*
  367. SG(sapi_headers).http_response_code = 200;
  368. */
  369. SG(sapi_headers).http_status_line = NULL;
  370. SG(sapi_headers).mimetype = NULL;
  371. SG(headers_sent) = 0;
  372. ZVAL_UNDEF(&SG(callback_func));
  373. SG(read_post_bytes) = 0;
  374. SG(request_info).request_body = NULL;
  375. SG(request_info).current_user = NULL;
  376. SG(request_info).current_user_length = 0;
  377. SG(request_info).no_headers = 0;
  378. SG(request_info).post_entry = NULL;
  379. SG(request_info).proto_num = 1000; /* Default to HTTP 1.0 */
  380. SG(global_request_time) = 0;
  381. SG(post_read) = 0;
  382. /* It's possible to override this general case in the activate() callback, if necessary. */
  383. if (SG(request_info).request_method && !strcmp(SG(request_info).request_method, "HEAD")) {
  384. SG(request_info).headers_only = 1;
  385. } else {
  386. SG(request_info).headers_only = 0;
  387. }
  388. SG(rfc1867_uploaded_files) = NULL;
  389. /* Handle request method */
  390. if (SG(server_context)) {
  391. if (PG(enable_post_data_reading)
  392. && SG(request_info).content_type
  393. && SG(request_info).request_method
  394. && !strcmp(SG(request_info).request_method, "POST")) {
  395. /* HTTP POST may contain form data to be processed into variables
  396. * depending on given content type */
  397. sapi_read_post_data();
  398. } else {
  399. SG(request_info).content_type_dup = NULL;
  400. }
  401. /* Cookies */
  402. SG(request_info).cookie_data = sapi_module.read_cookies();
  403. }
  404. if (sapi_module.activate) {
  405. sapi_module.activate();
  406. }
  407. if (sapi_module.input_filter_init) {
  408. sapi_module.input_filter_init();
  409. }
  410. }
  411. static void sapi_send_headers_free(void)
  412. {
  413. if (SG(sapi_headers).http_status_line) {
  414. efree(SG(sapi_headers).http_status_line);
  415. SG(sapi_headers).http_status_line = NULL;
  416. }
  417. }
  418. SAPI_API void sapi_deactivate(void)
  419. {
  420. zend_llist_destroy(&SG(sapi_headers).headers);
  421. if (SG(request_info).request_body) {
  422. SG(request_info).request_body = NULL;
  423. } else if (SG(server_context)) {
  424. if (!SG(post_read)) {
  425. /* make sure we've consumed all request input data */
  426. char dummy[SAPI_POST_BLOCK_SIZE];
  427. size_t read_bytes;
  428. do {
  429. read_bytes = sapi_read_post_block(dummy, SAPI_POST_BLOCK_SIZE);
  430. } while (SAPI_POST_BLOCK_SIZE == read_bytes);
  431. }
  432. }
  433. if (SG(request_info).auth_user) {
  434. efree(SG(request_info).auth_user);
  435. }
  436. if (SG(request_info).auth_password) {
  437. efree(SG(request_info).auth_password);
  438. }
  439. if (SG(request_info).auth_digest) {
  440. efree(SG(request_info).auth_digest);
  441. }
  442. if (SG(request_info).content_type_dup) {
  443. efree(SG(request_info).content_type_dup);
  444. }
  445. if (SG(request_info).current_user) {
  446. efree(SG(request_info).current_user);
  447. }
  448. if (sapi_module.deactivate) {
  449. sapi_module.deactivate();
  450. }
  451. if (SG(rfc1867_uploaded_files)) {
  452. destroy_uploaded_files_hash();
  453. }
  454. if (SG(sapi_headers).mimetype) {
  455. efree(SG(sapi_headers).mimetype);
  456. SG(sapi_headers).mimetype = NULL;
  457. }
  458. sapi_send_headers_free();
  459. SG(sapi_started) = 0;
  460. SG(headers_sent) = 0;
  461. SG(request_info).headers_read = 0;
  462. SG(global_request_time) = 0;
  463. }
  464. SAPI_API void sapi_initialize_empty_request(void)
  465. {
  466. SG(server_context) = NULL;
  467. SG(request_info).request_method = NULL;
  468. SG(request_info).auth_digest = SG(request_info).auth_user = SG(request_info).auth_password = NULL;
  469. SG(request_info).content_type_dup = NULL;
  470. }
  471. static int sapi_extract_response_code(const char *header_line)
  472. {
  473. int code = 200;
  474. const char *ptr;
  475. for (ptr = header_line; *ptr; ptr++) {
  476. if (*ptr == ' ' && *(ptr + 1) != ' ') {
  477. code = atoi(ptr + 1);
  478. break;
  479. }
  480. }
  481. return code;
  482. }
  483. static void sapi_update_response_code(int ncode)
  484. {
  485. /* if the status code did not change, we do not want
  486. to change the status line, and no need to change the code */
  487. if (SG(sapi_headers).http_response_code == ncode) {
  488. return;
  489. }
  490. if (SG(sapi_headers).http_status_line) {
  491. efree(SG(sapi_headers).http_status_line);
  492. SG(sapi_headers).http_status_line = NULL;
  493. }
  494. SG(sapi_headers).http_response_code = ncode;
  495. }
  496. /*
  497. * since zend_llist_del_element only removes one matched item once,
  498. * we should remove them manually
  499. */
  500. static void sapi_remove_header(zend_llist *l, char *name, size_t len) {
  501. sapi_header_struct *header;
  502. zend_llist_element *next;
  503. zend_llist_element *current=l->head;
  504. while (current) {
  505. header = (sapi_header_struct *)(current->data);
  506. next = current->next;
  507. if (header->header_len > len && header->header[len] == ':'
  508. && !strncasecmp(header->header, name, len)) {
  509. if (current->prev) {
  510. current->prev->next = next;
  511. } else {
  512. l->head = next;
  513. }
  514. if (next) {
  515. next->prev = current->prev;
  516. } else {
  517. l->tail = current->prev;
  518. }
  519. sapi_free_header(header);
  520. efree(current);
  521. --l->count;
  522. }
  523. current = next;
  524. }
  525. }
  526. SAPI_API int sapi_add_header_ex(const char *header_line, size_t header_line_len, bool duplicate, bool replace)
  527. {
  528. sapi_header_line ctr = {0};
  529. int r;
  530. ctr.line = header_line;
  531. ctr.line_len = header_line_len;
  532. r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD,
  533. &ctr);
  534. if (!duplicate)
  535. efree((void *) header_line);
  536. return r;
  537. }
  538. static void sapi_header_add_op(sapi_header_op_enum op, sapi_header_struct *sapi_header)
  539. {
  540. if (!sapi_module.header_handler ||
  541. (SAPI_HEADER_ADD & sapi_module.header_handler(sapi_header, op, &SG(sapi_headers)))) {
  542. if (op == SAPI_HEADER_REPLACE) {
  543. char *colon_offset = strchr(sapi_header->header, ':');
  544. if (colon_offset) {
  545. char sav = *colon_offset;
  546. *colon_offset = 0;
  547. sapi_remove_header(&SG(sapi_headers).headers, sapi_header->header, strlen(sapi_header->header));
  548. *colon_offset = sav;
  549. }
  550. }
  551. zend_llist_add_element(&SG(sapi_headers).headers, (void *) sapi_header);
  552. } else {
  553. sapi_free_header(sapi_header);
  554. }
  555. }
  556. SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg)
  557. {
  558. sapi_header_struct sapi_header;
  559. char *colon_offset;
  560. char *header_line;
  561. size_t header_line_len;
  562. int http_response_code;
  563. if (SG(headers_sent) && !SG(request_info).no_headers) {
  564. const char *output_start_filename = php_output_get_start_filename();
  565. int output_start_lineno = php_output_get_start_lineno();
  566. if (output_start_filename) {
  567. sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent by (output started at %s:%d)",
  568. output_start_filename, output_start_lineno);
  569. } else {
  570. sapi_module.sapi_error(E_WARNING, "Cannot modify header information - headers already sent");
  571. }
  572. return FAILURE;
  573. }
  574. switch (op) {
  575. case SAPI_HEADER_SET_STATUS:
  576. sapi_update_response_code((int)(zend_intptr_t) arg);
  577. return SUCCESS;
  578. case SAPI_HEADER_ADD:
  579. case SAPI_HEADER_REPLACE:
  580. case SAPI_HEADER_DELETE: {
  581. sapi_header_line *p = arg;
  582. if (!p->line || !p->line_len) {
  583. return FAILURE;
  584. }
  585. header_line = estrndup(p->line, p->line_len);
  586. header_line_len = p->line_len;
  587. http_response_code = p->response_code;
  588. break;
  589. }
  590. case SAPI_HEADER_DELETE_ALL:
  591. if (sapi_module.header_handler) {
  592. sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers));
  593. }
  594. zend_llist_clean(&SG(sapi_headers).headers);
  595. return SUCCESS;
  596. default:
  597. return FAILURE;
  598. }
  599. /* cut off trailing spaces, linefeeds and carriage-returns */
  600. if (header_line_len && isspace(header_line[header_line_len-1])) {
  601. do {
  602. header_line_len--;
  603. } while(header_line_len && isspace(header_line[header_line_len-1]));
  604. header_line[header_line_len]='\0';
  605. }
  606. if (op == SAPI_HEADER_DELETE) {
  607. if (strchr(header_line, ':')) {
  608. efree(header_line);
  609. sapi_module.sapi_error(E_WARNING, "Header to delete may not contain colon.");
  610. return FAILURE;
  611. }
  612. if (sapi_module.header_handler) {
  613. sapi_header.header = header_line;
  614. sapi_header.header_len = header_line_len;
  615. sapi_module.header_handler(&sapi_header, op, &SG(sapi_headers));
  616. }
  617. sapi_remove_header(&SG(sapi_headers).headers, header_line, header_line_len);
  618. efree(header_line);
  619. return SUCCESS;
  620. } else {
  621. /* new line/NUL character safety check */
  622. uint32_t i;
  623. for (i = 0; i < header_line_len; i++) {
  624. /* RFC 7230 ch. 3.2.4 deprecates folding support */
  625. if (header_line[i] == '\n' || header_line[i] == '\r') {
  626. efree(header_line);
  627. sapi_module.sapi_error(E_WARNING, "Header may not contain "
  628. "more than a single header, new line detected");
  629. return FAILURE;
  630. }
  631. if (header_line[i] == '\0') {
  632. efree(header_line);
  633. sapi_module.sapi_error(E_WARNING, "Header may not contain NUL bytes");
  634. return FAILURE;
  635. }
  636. }
  637. }
  638. sapi_header.header = header_line;
  639. sapi_header.header_len = header_line_len;
  640. /* Check the header for a few cases that we have special support for in SAPI */
  641. if (header_line_len>=5
  642. && !strncasecmp(header_line, "HTTP/", 5)) {
  643. /* filter out the response code */
  644. sapi_update_response_code(sapi_extract_response_code(header_line));
  645. /* sapi_update_response_code doesn't free the status line if the code didn't change */
  646. if (SG(sapi_headers).http_status_line) {
  647. efree(SG(sapi_headers).http_status_line);
  648. }
  649. SG(sapi_headers).http_status_line = header_line;
  650. return SUCCESS;
  651. } else {
  652. colon_offset = strchr(header_line, ':');
  653. if (colon_offset) {
  654. *colon_offset = 0;
  655. if (!strcasecmp(header_line, "Content-Type")) {
  656. char *ptr = colon_offset+1, *mimetype = NULL, *newheader;
  657. size_t len = header_line_len - (ptr - header_line), newlen;
  658. while (*ptr == ' ') {
  659. ptr++;
  660. len--;
  661. }
  662. mimetype = estrdup(ptr);
  663. newlen = sapi_apply_default_charset(&mimetype, len);
  664. if (!SG(sapi_headers).mimetype){
  665. SG(sapi_headers).mimetype = estrdup(mimetype);
  666. }
  667. if (newlen != 0) {
  668. newlen += sizeof("Content-type: ");
  669. newheader = emalloc(newlen);
  670. PHP_STRLCPY(newheader, "Content-type: ", newlen, sizeof("Content-type: ")-1);
  671. strlcat(newheader, mimetype, newlen);
  672. sapi_header.header = newheader;
  673. sapi_header.header_len = (uint32_t)(newlen - 1);
  674. efree(header_line);
  675. }
  676. efree(mimetype);
  677. SG(sapi_headers).send_default_content_type = 0;
  678. } else if (!strcasecmp(header_line, "Content-Length")) {
  679. /* Script is setting Content-length. The script cannot reasonably
  680. * know the size of the message body after compression, so it's best
  681. * do disable compression altogether. This contributes to making scripts
  682. * portable between setups that have and don't have zlib compression
  683. * enabled globally. See req #44164 */
  684. zend_string *key = zend_string_init("zlib.output_compression", sizeof("zlib.output_compression")-1, 0);
  685. zend_alter_ini_entry_chars(key,
  686. "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME);
  687. zend_string_release_ex(key, 0);
  688. } else if (!strcasecmp(header_line, "Location")) {
  689. if ((SG(sapi_headers).http_response_code < 300 ||
  690. SG(sapi_headers).http_response_code > 399) &&
  691. SG(sapi_headers).http_response_code != 201) {
  692. /* Return a Found Redirect if one is not already specified */
  693. if (http_response_code) { /* user specified redirect code */
  694. sapi_update_response_code(http_response_code);
  695. } else if (SG(request_info).proto_num > 1000 &&
  696. SG(request_info).request_method &&
  697. strcmp(SG(request_info).request_method, "HEAD") &&
  698. strcmp(SG(request_info).request_method, "GET")) {
  699. sapi_update_response_code(303);
  700. } else {
  701. sapi_update_response_code(302);
  702. }
  703. }
  704. } else if (!strcasecmp(header_line, "WWW-Authenticate")) { /* HTTP Authentication */
  705. sapi_update_response_code(401); /* authentication-required */
  706. }
  707. if (sapi_header.header==header_line) {
  708. *colon_offset = ':';
  709. }
  710. }
  711. }
  712. if (http_response_code) {
  713. sapi_update_response_code(http_response_code);
  714. }
  715. sapi_header_add_op(op, &sapi_header);
  716. return SUCCESS;
  717. }
  718. SAPI_API int sapi_send_headers(void)
  719. {
  720. int retval;
  721. int ret = FAILURE;
  722. if (SG(headers_sent) || SG(request_info).no_headers) {
  723. return SUCCESS;
  724. }
  725. /* Success-oriented. We set headers_sent to 1 here to avoid an infinite loop
  726. * in case of an error situation.
  727. */
  728. if (SG(sapi_headers).send_default_content_type && sapi_module.send_headers) {
  729. uint32_t len = 0;
  730. char *default_mimetype = get_default_content_type(0, &len);
  731. if (default_mimetype && len) {
  732. sapi_header_struct default_header;
  733. SG(sapi_headers).mimetype = default_mimetype;
  734. default_header.header_len = sizeof("Content-type: ") - 1 + len;
  735. default_header.header = emalloc(default_header.header_len + 1);
  736. memcpy(default_header.header, "Content-type: ", sizeof("Content-type: ") - 1);
  737. memcpy(default_header.header + sizeof("Content-type: ") - 1, SG(sapi_headers).mimetype, len + 1);
  738. sapi_header_add_op(SAPI_HEADER_ADD, &default_header);
  739. } else {
  740. efree(default_mimetype);
  741. }
  742. SG(sapi_headers).send_default_content_type = 0;
  743. }
  744. if (Z_TYPE(SG(callback_func)) != IS_UNDEF) {
  745. zval cb;
  746. ZVAL_COPY_VALUE(&cb, &SG(callback_func));
  747. ZVAL_UNDEF(&SG(callback_func));
  748. sapi_run_header_callback(&cb);
  749. zval_ptr_dtor(&cb);
  750. }
  751. SG(headers_sent) = 1;
  752. if (sapi_module.send_headers) {
  753. retval = sapi_module.send_headers(&SG(sapi_headers));
  754. } else {
  755. retval = SAPI_HEADER_DO_SEND;
  756. }
  757. switch (retval) {
  758. case SAPI_HEADER_SENT_SUCCESSFULLY:
  759. ret = SUCCESS;
  760. break;
  761. case SAPI_HEADER_DO_SEND: {
  762. sapi_header_struct http_status_line;
  763. char buf[255];
  764. if (SG(sapi_headers).http_status_line) {
  765. http_status_line.header = SG(sapi_headers).http_status_line;
  766. http_status_line.header_len = (uint32_t)strlen(SG(sapi_headers).http_status_line);
  767. } else {
  768. http_status_line.header = buf;
  769. http_status_line.header_len = slprintf(buf, sizeof(buf), "HTTP/1.0 %d X", SG(sapi_headers).http_response_code);
  770. }
  771. sapi_module.send_header(&http_status_line, SG(server_context));
  772. }
  773. zend_llist_apply_with_argument(&SG(sapi_headers).headers, (llist_apply_with_arg_func_t) sapi_module.send_header, SG(server_context));
  774. if(SG(sapi_headers).send_default_content_type) {
  775. sapi_header_struct default_header;
  776. sapi_get_default_content_type_header(&default_header);
  777. sapi_module.send_header(&default_header, SG(server_context));
  778. sapi_free_header(&default_header);
  779. }
  780. sapi_module.send_header(NULL, SG(server_context));
  781. ret = SUCCESS;
  782. break;
  783. case SAPI_HEADER_SEND_FAILED:
  784. SG(headers_sent) = 0;
  785. ret = FAILURE;
  786. break;
  787. }
  788. sapi_send_headers_free();
  789. return ret;
  790. }
  791. SAPI_API int sapi_register_post_entries(const sapi_post_entry *post_entries)
  792. {
  793. const sapi_post_entry *p=post_entries;
  794. while (p->content_type) {
  795. if (sapi_register_post_entry(p) == FAILURE) {
  796. return FAILURE;
  797. }
  798. p++;
  799. }
  800. return SUCCESS;
  801. }
  802. SAPI_API int sapi_register_post_entry(const sapi_post_entry *post_entry)
  803. {
  804. int ret;
  805. zend_string *key;
  806. if (SG(sapi_started) && EG(current_execute_data)) {
  807. return FAILURE;
  808. }
  809. key = zend_string_init(post_entry->content_type, post_entry->content_type_len, 1);
  810. GC_MAKE_PERSISTENT_LOCAL(key);
  811. ret = zend_hash_add_mem(&SG(known_post_content_types), key,
  812. (void *) post_entry, sizeof(sapi_post_entry)) ? SUCCESS : FAILURE;
  813. zend_string_release_ex(key, 1);
  814. return ret;
  815. }
  816. SAPI_API void sapi_unregister_post_entry(const sapi_post_entry *post_entry)
  817. {
  818. if (SG(sapi_started) && EG(current_execute_data)) {
  819. return;
  820. }
  821. zend_hash_str_del(&SG(known_post_content_types), post_entry->content_type,
  822. post_entry->content_type_len);
  823. }
  824. SAPI_API int sapi_register_default_post_reader(void (*default_post_reader)(void))
  825. {
  826. if (SG(sapi_started) && EG(current_execute_data)) {
  827. return FAILURE;
  828. }
  829. sapi_module.default_post_reader = default_post_reader;
  830. return SUCCESS;
  831. }
  832. SAPI_API int sapi_register_treat_data(void (*treat_data)(int arg, char *str, zval *destArray))
  833. {
  834. if (SG(sapi_started) && EG(current_execute_data)) {
  835. return FAILURE;
  836. }
  837. sapi_module.treat_data = treat_data;
  838. return SUCCESS;
  839. }
  840. SAPI_API int sapi_register_input_filter(unsigned int (*input_filter)(int arg, const char *var, char **val, size_t val_len, size_t *new_val_len), unsigned int (*input_filter_init)(void))
  841. {
  842. if (SG(sapi_started) && EG(current_execute_data)) {
  843. return FAILURE;
  844. }
  845. sapi_module.input_filter = input_filter;
  846. sapi_module.input_filter_init = input_filter_init;
  847. return SUCCESS;
  848. }
  849. SAPI_API int sapi_flush(void)
  850. {
  851. if (sapi_module.flush) {
  852. sapi_module.flush(SG(server_context));
  853. return SUCCESS;
  854. } else {
  855. return FAILURE;
  856. }
  857. }
  858. SAPI_API zend_stat_t *sapi_get_stat(void)
  859. {
  860. if (sapi_module.get_stat) {
  861. return sapi_module.get_stat();
  862. } else {
  863. if (!SG(request_info).path_translated || (VCWD_STAT(SG(request_info).path_translated, &SG(global_stat)) == -1)) {
  864. return NULL;
  865. }
  866. return &SG(global_stat);
  867. }
  868. }
  869. SAPI_API char *sapi_getenv(const char *name, size_t name_len)
  870. {
  871. if (!strncasecmp(name, "HTTP_PROXY", name_len)) {
  872. /* Ugly fix for HTTP_PROXY issue, see bug #72573 */
  873. return NULL;
  874. }
  875. if (sapi_module.getenv) {
  876. char *value, *tmp = sapi_module.getenv(name, name_len);
  877. if (tmp) {
  878. value = estrdup(tmp);
  879. #ifdef PHP_WIN32
  880. if (strlen(sapi_module.name) == sizeof("cgi-fcgi") - 1 && !strcmp(sapi_module.name, "cgi-fcgi")) {
  881. /* XXX more modules to go, if needed. */
  882. free(tmp);
  883. }
  884. #endif
  885. } else {
  886. return NULL;
  887. }
  888. if (sapi_module.input_filter) {
  889. sapi_module.input_filter(PARSE_STRING, name, &value, strlen(value), NULL);
  890. }
  891. return value;
  892. }
  893. return NULL;
  894. }
  895. SAPI_API int sapi_get_fd(int *fd)
  896. {
  897. if (sapi_module.get_fd) {
  898. return sapi_module.get_fd(fd);
  899. } else {
  900. return FAILURE;
  901. }
  902. }
  903. SAPI_API int sapi_force_http_10(void)
  904. {
  905. if (sapi_module.force_http_10) {
  906. return sapi_module.force_http_10();
  907. } else {
  908. return FAILURE;
  909. }
  910. }
  911. SAPI_API int sapi_get_target_uid(uid_t *obj)
  912. {
  913. if (sapi_module.get_target_uid) {
  914. return sapi_module.get_target_uid(obj);
  915. } else {
  916. return FAILURE;
  917. }
  918. }
  919. SAPI_API int sapi_get_target_gid(gid_t *obj)
  920. {
  921. if (sapi_module.get_target_gid) {
  922. return sapi_module.get_target_gid(obj);
  923. } else {
  924. return FAILURE;
  925. }
  926. }
  927. SAPI_API double sapi_get_request_time(void)
  928. {
  929. if(SG(global_request_time)) return SG(global_request_time);
  930. if (sapi_module.get_request_time && SG(server_context)) {
  931. SG(global_request_time) = sapi_module.get_request_time();
  932. } else {
  933. struct timeval tp = {0};
  934. if (!gettimeofday(&tp, NULL)) {
  935. SG(global_request_time) = (double)(tp.tv_sec + tp.tv_usec / 1000000.00);
  936. } else {
  937. SG(global_request_time) = (double)time(0);
  938. }
  939. }
  940. return SG(global_request_time);
  941. }
  942. SAPI_API void sapi_terminate_process(void) {
  943. if (sapi_module.terminate_process) {
  944. sapi_module.terminate_process();
  945. }
  946. }
  947. SAPI_API void sapi_add_request_header(const char *var, unsigned int var_len, char *val, unsigned int val_len, void *arg) /* {{{ */
  948. {
  949. zval *return_value = (zval*)arg;
  950. char *buf = NULL;
  951. ALLOCA_FLAG(use_heap)
  952. if (var_len > 5 &&
  953. var[0] == 'H' &&
  954. var[1] == 'T' &&
  955. var[2] == 'T' &&
  956. var[3] == 'P' &&
  957. var[4] == '_') {
  958. const char *p;
  959. char *str;
  960. var_len -= 5;
  961. p = var + 5;
  962. var = str = buf = do_alloca(var_len + 1, use_heap);
  963. *str++ = *p++;
  964. while (*p) {
  965. if (*p == '_') {
  966. *str++ = '-';
  967. p++;
  968. if (*p) {
  969. *str++ = *p++;
  970. }
  971. } else if (*p >= 'A' && *p <= 'Z') {
  972. *str++ = (*p++ - 'A' + 'a');
  973. } else {
  974. *str++ = *p++;
  975. }
  976. }
  977. *str = 0;
  978. } else if (var_len == sizeof("CONTENT_TYPE")-1 &&
  979. memcmp(var, "CONTENT_TYPE", sizeof("CONTENT_TYPE")-1) == 0) {
  980. var = "Content-Type";
  981. } else if (var_len == sizeof("CONTENT_LENGTH")-1 &&
  982. memcmp(var, "CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1) == 0) {
  983. var = "Content-Length";
  984. } else {
  985. return;
  986. }
  987. add_assoc_stringl_ex(return_value, var, var_len, val, val_len);
  988. if (buf) {
  989. free_alloca(buf, use_heap);
  990. }
  991. }
  992. /* }}} */