root/ext/standard/head.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PHP_FUNCTION
  2. PHP_FUNCTION
  3. php_header
  4. php_setcookie
  5. PHP_FUNCTION
  6. PHP_FUNCTION
  7. PHP_FUNCTION
  8. php_head_apply_header_list_to_hash
  9. PHP_FUNCTION
  10. PHP_FUNCTION

   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: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
  16    +----------------------------------------------------------------------+
  17  */
  18 /* $Id$ */
  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 
  35 
  36 /* Implementation of the language Header() function */
  37 /* {{{ proto void header(string header [, bool replace, [int http_response_code]])
  38    Sends a raw HTTP header */
  39 PHP_FUNCTION(header)
  40 {
  41         zend_bool rep = 1;
  42         sapi_header_line ctr = {0};
  43 
  44         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
  45                                 &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
  46                 return;
  47 
  48         sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
  49 }
  50 /* }}} */
  51 
  52 /* {{{ proto void header_remove([string name])
  53    Removes an HTTP header previously set using header() */
  54 PHP_FUNCTION(header_remove)
  55 {
  56         sapi_header_line ctr = {0};
  57 
  58         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ctr.line,
  59                                   &ctr.line_len) == FAILURE)
  60                 return;
  61 
  62         sapi_header_op(ZEND_NUM_ARGS() == 0 ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr TSRMLS_CC);
  63 }
  64 /* }}} */
  65 
  66 PHPAPI int php_header(TSRMLS_D)
  67 {
  68         if (sapi_send_headers(TSRMLS_C)==FAILURE || SG(request_info).headers_only) {
  69                 return 0; /* don't allow output */
  70         } else {
  71                 return 1; /* allow output */
  72         }
  73 }
  74 
  75 
  76 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)
  77 {
  78         char *cookie, *encoded_value = NULL;
  79         int len=sizeof("Set-Cookie: ");
  80         char *dt;
  81         sapi_header_line ctr = {0};
  82         int result;
  83 
  84         if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) {   /* man isspace for \013 and \014 */
  85                 zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
  86                 return FAILURE;
  87         }
  88 
  89         if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
  90                 zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
  91                 return FAILURE;
  92         }
  93 
  94         len += name_len;
  95         if (value && url_encode) {
  96                 int encoded_value_len;
  97 
  98                 encoded_value = php_url_encode(value, value_len, &encoded_value_len);
  99                 len += encoded_value_len;
 100         } else if ( value ) {
 101                 encoded_value = estrdup(value);
 102                 len += value_len;
 103         }
 104         if (path) {
 105                 len += path_len;
 106         }
 107         if (domain) {
 108                 len += domain_len;
 109         }
 110 
 111         cookie = emalloc(len + 100);
 112 
 113         if (value == NULL || value_len == 0) {
 114                 /*
 115                  * MSIE doesn't delete a cookie when you set it to a null value
 116                  * so in order to force cookies to be deleted, even on MSIE, we
 117                  * pick an expiry date in the past
 118                  */
 119                 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);
 120                 snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt);
 121                 efree(dt);
 122         } else {
 123                 snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
 124                 if (expires > 0) {
 125                         const char *p;
 126                         char tsdelta[13];
 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 than 9999");
 136                                 return FAILURE;
 137                         }
 138                         strlcat(cookie, dt, len + 100);
 139                         efree(dt);
 140 
 141                         snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL)));
 142                         strlcat(cookie, "; Max-Age=", len + 100);
 143                         strlcat(cookie, tsdelta, len + 100);
 144                 }
 145         }
 146 
 147         if (encoded_value) {
 148                 efree(encoded_value);
 149         }
 150 
 151         if (path && path_len > 0) {
 152                 strlcat(cookie, "; path=", len + 100);
 153                 strlcat(cookie, path, len + 100);
 154         }
 155         if (domain && domain_len > 0) {
 156                 strlcat(cookie, "; domain=", len + 100);
 157                 strlcat(cookie, domain, len + 100);
 158         }
 159         if (secure) {
 160                 strlcat(cookie, "; secure", len + 100);
 161         }
 162         if (httponly) {
 163                 strlcat(cookie, "; httponly", len + 100);
 164         }
 165 
 166         ctr.line = cookie;
 167         ctr.line_len = strlen(cookie);
 168 
 169         result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
 170         efree(cookie);
 171         return result;
 172 }
 173 
 174 
 175 /* php_set_cookie(name, value, expires, path, domain, secure) */
 176 /* {{{ proto bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
 177    Send a cookie */
 178 PHP_FUNCTION(setcookie)
 179 {
 180         char *name, *value = NULL, *path = NULL, *domain = NULL;
 181         long expires = 0;
 182         zend_bool secure = 0, httponly = 0;
 183         int name_len, value_len = 0, path_len = 0, domain_len = 0;
 184 
 185         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
 186                                                           &name_len, &value, &value_len, &expires, &path,
 187                                                           &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
 188                 return;
 189         }
 190 
 191         if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 1, httponly TSRMLS_CC) == SUCCESS) {
 192                 RETVAL_TRUE;
 193         } else {
 194                 RETVAL_FALSE;
 195         }
 196 }
 197 /* }}} */
 198 
 199 /* {{{ proto bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
 200    Send a cookie with no url encoding of the value */
 201 PHP_FUNCTION(setrawcookie)
 202 {
 203         char *name, *value = NULL, *path = NULL, *domain = NULL;
 204         long expires = 0;
 205         zend_bool secure = 0, httponly = 0;
 206         int name_len, value_len = 0, path_len = 0, domain_len = 0;
 207 
 208         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
 209                                                           &name_len, &value, &value_len, &expires, &path,
 210                                                           &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
 211                 return;
 212         }
 213 
 214         if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 0, httponly TSRMLS_CC) == SUCCESS) {
 215                 RETVAL_TRUE;
 216         } else {
 217                 RETVAL_FALSE;
 218         }
 219 }
 220 /* }}} */
 221 
 222 
 223 /* {{{ proto bool headers_sent([string &$file [, int &$line]])
 224    Returns true if headers have already been sent, false otherwise */
 225 PHP_FUNCTION(headers_sent)
 226 {
 227         zval *arg1 = NULL, *arg2 = NULL;
 228         const char *file="";
 229         int line=0;
 230 
 231         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE)
 232                 return;
 233 
 234         if (SG(headers_sent)) {
 235                 line = php_output_get_start_lineno(TSRMLS_C);
 236                 file = php_output_get_start_filename(TSRMLS_C);
 237         }
 238 
 239         switch(ZEND_NUM_ARGS()) {
 240         case 2:
 241                 zval_dtor(arg2);
 242                 ZVAL_LONG(arg2, line);
 243         case 1:
 244                 zval_dtor(arg1);
 245                 if (file) {
 246                         ZVAL_STRING(arg1, file, 1);
 247                 } else {
 248                         ZVAL_STRING(arg1, "", 1);
 249                 }
 250                 break;
 251         }
 252 
 253         if (SG(headers_sent)) {
 254                 RETURN_TRUE;
 255         } else {
 256                 RETURN_FALSE;
 257         }
 258 }
 259 /* }}} */
 260 
 261 /* {{{ php_head_apply_header_list_to_hash
 262    Turn an llist of sapi_header_struct headers into a numerically indexed zval hash */
 263 static void php_head_apply_header_list_to_hash(void *data, void *arg TSRMLS_DC)
 264 {
 265         sapi_header_struct *sapi_header = (sapi_header_struct *)data;
 266 
 267         if (arg && sapi_header) {
 268                 add_next_index_string((zval *)arg, (char *)(sapi_header->header), 1);
 269         }
 270 }
 271 
 272 /* {{{ proto array headers_list(void)
 273    Return list of headers to be sent / already sent */
 274 PHP_FUNCTION(headers_list)
 275 {
 276         if (zend_parse_parameters_none() == FAILURE) {
 277                 return;
 278         }
 279 
 280         array_init(return_value);
 281         zend_llist_apply_with_argument(&SG(sapi_headers).headers, php_head_apply_header_list_to_hash, return_value TSRMLS_CC);
 282 }
 283 /* }}} */
 284 
 285 /* {{{ proto long http_response_code([int response_code])
 286    Sets a response code, or returns the current HTTP response code */
 287 PHP_FUNCTION(http_response_code)
 288 {
 289         long response_code = 0;
 290 
 291         if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &response_code) == FAILURE) {
 292                 return;
 293         }
 294 
 295         if (response_code)
 296         {
 297                 long old_response_code;
 298 
 299                 old_response_code = SG(sapi_headers).http_response_code;
 300                 SG(sapi_headers).http_response_code = response_code;
 301 
 302                 if (old_response_code) {
 303                         RETURN_LONG(old_response_code);
 304                 }
 305 
 306                 RETURN_TRUE;
 307         }
 308 
 309         if (!SG(sapi_headers).http_response_code) {
 310                 RETURN_FALSE;
 311         }
 312 
 313         RETURN_LONG(SG(sapi_headers).http_response_code);
 314 }
 315 /* }}} */
 316 
 317 /*
 318  * Local variables:
 319  * tab-width: 4
 320  * c-basic-offset: 4
 321  * vim600: sw=4 ts=4 fdm=marker
 322  * vim<600: sw=4 ts=4 * End:
 323  */

/* [<][>][^][v][top][bottom][index][help] */