Annotation of embedaddon/php/ext/standard/head.c, revision 1.1.1.1
1.1 misho 1: /*
2: +----------------------------------------------------------------------+
3: | PHP Version 5 |
4: +----------------------------------------------------------------------+
5: | Copyright (c) 1997-2012 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: Rasmus Lerdorf <rasmus@lerdorf.on.ca> |
16: +----------------------------------------------------------------------+
17: */
18: /* $Id: head.c 321634 2012-01-01 13:15:04Z felipe $ */
19:
20: #include <stdio.h>
21: #include "php.h"
22: #include "ext/standard/php_standard.h"
23: #include "ext/date/php_date.h"
24: #include "SAPI.h"
25: #include "php_main.h"
26: #include "head.h"
27: #ifdef TM_IN_SYS_TIME
28: #include <sys/time.h>
29: #else
30: #include <time.h>
31: #endif
32:
33: #include "php_globals.h"
34: #include "safe_mode.h"
35:
36:
37: /* Implementation of the language Header() function */
38: /* {{{ proto void header(string header [, bool replace, [int http_response_code]])
39: Sends a raw HTTP header */
40: PHP_FUNCTION(header)
41: {
42: zend_bool rep = 1;
43: sapi_header_line ctr = {0};
44:
45: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
46: &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
47: return;
48:
49: sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
50: }
51: /* }}} */
52:
53: /* {{{ proto void header_remove([string name])
54: Removes an HTTP header previously set using header() */
55: PHP_FUNCTION(header_remove)
56: {
57: sapi_header_line ctr = {0};
58:
59: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ctr.line,
60: &ctr.line_len) == FAILURE)
61: return;
62:
63: sapi_header_op(ZEND_NUM_ARGS() == 0 ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr TSRMLS_CC);
64: }
65: /* }}} */
66:
67: PHPAPI int php_header(TSRMLS_D)
68: {
69: if (sapi_send_headers(TSRMLS_C)==FAILURE || SG(request_info).headers_only) {
70: return 0; /* don't allow output */
71: } else {
72: return 1; /* allow output */
73: }
74: }
75:
76:
77: PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, time_t expires, char *path, int path_len, char *domain, int domain_len, int secure, int url_encode, int httponly TSRMLS_DC)
78: {
79: char *cookie, *encoded_value = NULL;
80: int len=sizeof("Set-Cookie: ");
81: char *dt;
82: sapi_header_line ctr = {0};
83: int result;
84:
85: if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
86: zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
87: return FAILURE;
88: }
89:
90: if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
91: zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
92: return FAILURE;
93: }
94:
95: len += name_len;
96: if (value && url_encode) {
97: int encoded_value_len;
98:
99: encoded_value = php_url_encode(value, value_len, &encoded_value_len);
100: len += encoded_value_len;
101: } else if ( value ) {
102: encoded_value = estrdup(value);
103: len += value_len;
104: }
105: if (path) {
106: len += path_len;
107: }
108: if (domain) {
109: len += domain_len;
110: }
111:
112: cookie = emalloc(len + 100);
113:
114: if (value && value_len == 0) {
115: /*
116: * MSIE doesn't delete a cookie when you set it to a null value
117: * so in order to force cookies to be deleted, even on MSIE, we
118: * pick an expiry date in the past
119: */
120: dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, 1, 0 TSRMLS_CC);
121: snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
122: efree(dt);
123: } else {
124: snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
125: if (expires > 0) {
126: char *p;
127: strlcat(cookie, "; expires=", len + 100);
128: dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC);
129: /* check to make sure that the year does not exceed 4 digits in length */
130: p = zend_memrchr(dt, '-', strlen(dt));
131: if (!p || *(p + 5) != ' ') {
132: efree(dt);
133: efree(cookie);
134: efree(encoded_value);
135: zend_error(E_WARNING, "Expiry date cannot have a year greater then 9999");
136: return FAILURE;
137: }
138: strlcat(cookie, dt, len + 100);
139: efree(dt);
140: }
141: }
142:
143: if (encoded_value) {
144: efree(encoded_value);
145: }
146:
147: if (path && path_len > 0) {
148: strlcat(cookie, "; path=", len + 100);
149: strlcat(cookie, path, len + 100);
150: }
151: if (domain && domain_len > 0) {
152: strlcat(cookie, "; domain=", len + 100);
153: strlcat(cookie, domain, len + 100);
154: }
155: if (secure) {
156: strlcat(cookie, "; secure", len + 100);
157: }
158: if (httponly) {
159: strlcat(cookie, "; httponly", len + 100);
160: }
161:
162: ctr.line = cookie;
163: ctr.line_len = strlen(cookie);
164:
165: result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
166: efree(cookie);
167: return result;
168: }
169:
170:
171: /* php_set_cookie(name, value, expires, path, domain, secure) */
172: /* {{{ proto bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
173: Send a cookie */
174: PHP_FUNCTION(setcookie)
175: {
176: char *name, *value = NULL, *path = NULL, *domain = NULL;
177: long expires = 0;
178: zend_bool secure = 0, httponly = 0;
179: int name_len, value_len = 0, path_len = 0, domain_len = 0;
180:
181: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
182: &name_len, &value, &value_len, &expires, &path,
183: &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
184: return;
185: }
186:
187: if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 1, httponly TSRMLS_CC) == SUCCESS) {
188: RETVAL_TRUE;
189: } else {
190: RETVAL_FALSE;
191: }
192: }
193: /* }}} */
194:
195: /* {{{ proto bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
196: Send a cookie with no url encoding of the value */
197: PHP_FUNCTION(setrawcookie)
198: {
199: char *name, *value = NULL, *path = NULL, *domain = NULL;
200: long expires = 0;
201: zend_bool secure = 0, httponly = 0;
202: int name_len, value_len = 0, path_len = 0, domain_len = 0;
203:
204: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
205: &name_len, &value, &value_len, &expires, &path,
206: &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
207: return;
208: }
209:
210: if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 0, httponly TSRMLS_CC) == SUCCESS) {
211: RETVAL_TRUE;
212: } else {
213: RETVAL_FALSE;
214: }
215: }
216: /* }}} */
217:
218:
219: /* {{{ proto bool headers_sent([string &$file [, int &$line]])
220: Returns true if headers have already been sent, false otherwise */
221: PHP_FUNCTION(headers_sent)
222: {
223: zval *arg1 = NULL, *arg2 = NULL;
224: char *file="";
225: int line=0;
226:
227: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE)
228: return;
229:
230: if (SG(headers_sent)) {
231: line = php_get_output_start_lineno(TSRMLS_C);
232: file = php_get_output_start_filename(TSRMLS_C);
233: }
234:
235: switch(ZEND_NUM_ARGS()) {
236: case 2:
237: zval_dtor(arg2);
238: ZVAL_LONG(arg2, line);
239: case 1:
240: zval_dtor(arg1);
241: if (file) {
242: ZVAL_STRING(arg1, file, 1);
243: } else {
244: ZVAL_STRING(arg1, "", 1);
245: }
246: break;
247: }
248:
249: if (SG(headers_sent)) {
250: RETURN_TRUE;
251: } else {
252: RETURN_FALSE;
253: }
254: }
255: /* }}} */
256:
257: /* {{{ php_head_apply_header_list_to_hash
258: Turn an llist of sapi_header_struct headers into a numerically indexed zval hash */
259: static void php_head_apply_header_list_to_hash(void *data, void *arg TSRMLS_DC)
260: {
261: sapi_header_struct *sapi_header = (sapi_header_struct *)data;
262:
263: if (arg && sapi_header) {
264: add_next_index_string((zval *)arg, (char *)(sapi_header->header), 1);
265: }
266: }
267:
268: /* {{{ proto array headers_list(void)
269: Return list of headers to be sent / already sent */
270: PHP_FUNCTION(headers_list)
271: {
272: if (zend_parse_parameters_none() == FAILURE) {
273: return;
274: }
275:
276: if (!&SG(sapi_headers).headers) {
277: RETURN_FALSE;
278: }
279: array_init(return_value);
280: zend_llist_apply_with_argument(&SG(sapi_headers).headers, php_head_apply_header_list_to_hash, return_value TSRMLS_CC);
281: }
282: /* }}} */
283:
284: /*
285: * Local variables:
286: * tab-width: 4
287: * c-basic-offset: 4
288: * vim600: sw=4 ts=4 fdm=marker
289: * vim<600: sw=4 ts=4 * End:
290: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>