Back to index

php5  5.3.10
head.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                        |
00016    +----------------------------------------------------------------------+
00017  */
00018 /* $Id: head.c 321634 2012-01-01 13:15:04Z felipe $ */
00019 
00020 #include <stdio.h>
00021 #include "php.h"
00022 #include "ext/standard/php_standard.h"
00023 #include "ext/date/php_date.h"
00024 #include "SAPI.h"
00025 #include "php_main.h"
00026 #include "head.h"
00027 #ifdef TM_IN_SYS_TIME
00028 #include <sys/time.h>
00029 #else
00030 #include <time.h>
00031 #endif
00032 
00033 #include "php_globals.h"
00034 #include "safe_mode.h"
00035 
00036 
00037 /* Implementation of the language Header() function */
00038 /* {{{ proto void header(string header [, bool replace, [int http_response_code]])
00039    Sends a raw HTTP header */
00040 PHP_FUNCTION(header)
00041 {
00042        zend_bool rep = 1;
00043        sapi_header_line ctr = {0};
00044        
00045        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|bl", &ctr.line,
00046                             &ctr.line_len, &rep, &ctr.response_code) == FAILURE)
00047               return;
00048        
00049        sapi_header_op(rep ? SAPI_HEADER_REPLACE:SAPI_HEADER_ADD, &ctr TSRMLS_CC);
00050 }
00051 /* }}} */
00052 
00053 /* {{{ proto void header_remove([string name])
00054    Removes an HTTP header previously set using header() */
00055 PHP_FUNCTION(header_remove)
00056 {
00057        sapi_header_line ctr = {0};
00058 
00059        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &ctr.line,
00060                                  &ctr.line_len) == FAILURE)
00061               return;
00062 
00063        sapi_header_op(ZEND_NUM_ARGS() == 0 ? SAPI_HEADER_DELETE_ALL : SAPI_HEADER_DELETE, &ctr TSRMLS_CC);
00064 }
00065 /* }}} */
00066 
00067 PHPAPI int php_header(TSRMLS_D)
00068 {
00069        if (sapi_send_headers(TSRMLS_C)==FAILURE || SG(request_info).headers_only) {
00070               return 0; /* don't allow output */
00071        } else {
00072               return 1; /* allow output */
00073        }
00074 }
00075 
00076 
00077 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)
00078 {
00079        char *cookie, *encoded_value = NULL;
00080        int len=sizeof("Set-Cookie: ");
00081        char *dt;
00082        sapi_header_line ctr = {0};
00083        int result;
00084        
00085        if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) {   /* man isspace for \013 and \014 */
00086               zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" );
00087               return FAILURE;
00088        }
00089 
00090        if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */
00091               zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" );
00092               return FAILURE;
00093        }
00094 
00095        len += name_len;
00096        if (value && url_encode) {
00097               int encoded_value_len;
00098 
00099               encoded_value = php_url_encode(value, value_len, &encoded_value_len);
00100               len += encoded_value_len;
00101        } else if ( value ) {
00102               encoded_value = estrdup(value);
00103               len += value_len;
00104        }
00105        if (path) {
00106               len += path_len;
00107        }
00108        if (domain) {
00109               len += domain_len;
00110        }
00111 
00112        cookie = emalloc(len + 100);
00113 
00114        if (value && value_len == 0) {
00115               /* 
00116                * MSIE doesn't delete a cookie when you set it to a null value
00117                * so in order to force cookies to be deleted, even on MSIE, we
00118                * pick an expiry date in the past
00119                */
00120               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);
00121               snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt);
00122               efree(dt);
00123        } else {
00124               snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : "");
00125               if (expires > 0) {
00126                      char *p;
00127                      strlcat(cookie, "; expires=", len + 100);
00128                      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);
00129                      /* check to make sure that the year does not exceed 4 digits in length */
00130                      p = zend_memrchr(dt, '-', strlen(dt));
00131                      if (!p || *(p + 5) != ' ') {
00132                             efree(dt);
00133                             efree(cookie);
00134                             efree(encoded_value);
00135                             zend_error(E_WARNING, "Expiry date cannot have a year greater then 9999");
00136                             return FAILURE;
00137                      }
00138                      strlcat(cookie, dt, len + 100);
00139                      efree(dt);
00140               }
00141        }
00142 
00143        if (encoded_value) {
00144               efree(encoded_value);
00145        }
00146 
00147        if (path && path_len > 0) {
00148               strlcat(cookie, "; path=", len + 100);
00149               strlcat(cookie, path, len + 100);
00150        }
00151        if (domain && domain_len > 0) {
00152               strlcat(cookie, "; domain=", len + 100);
00153               strlcat(cookie, domain, len + 100);
00154        }
00155        if (secure) {
00156               strlcat(cookie, "; secure", len + 100);
00157        }
00158        if (httponly) {
00159               strlcat(cookie, "; httponly", len + 100);
00160        }
00161 
00162        ctr.line = cookie;
00163        ctr.line_len = strlen(cookie);
00164 
00165        result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC);
00166        efree(cookie);
00167        return result;
00168 }
00169 
00170 
00171 /* php_set_cookie(name, value, expires, path, domain, secure) */
00172 /* {{{ proto bool setcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
00173    Send a cookie */
00174 PHP_FUNCTION(setcookie)
00175 {
00176        char *name, *value = NULL, *path = NULL, *domain = NULL;
00177        long expires = 0;
00178        zend_bool secure = 0, httponly = 0;
00179        int name_len, value_len = 0, path_len = 0, domain_len = 0;
00180 
00181        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
00182                                                    &name_len, &value, &value_len, &expires, &path,
00183                                                    &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
00184               return;
00185        }
00186 
00187        if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 1, httponly TSRMLS_CC) == SUCCESS) {
00188               RETVAL_TRUE;
00189        } else {
00190               RETVAL_FALSE;
00191        }
00192 }
00193 /* }}} */
00194 
00195 /* {{{ proto bool setrawcookie(string name [, string value [, int expires [, string path [, string domain [, bool secure[, bool httponly]]]]]])
00196    Send a cookie with no url encoding of the value */
00197 PHP_FUNCTION(setrawcookie)
00198 {
00199        char *name, *value = NULL, *path = NULL, *domain = NULL;
00200        long expires = 0;
00201        zend_bool secure = 0, httponly = 0;
00202        int name_len, value_len = 0, path_len = 0, domain_len = 0;
00203 
00204        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|slssbb", &name,
00205                                                    &name_len, &value, &value_len, &expires, &path,
00206                                                    &path_len, &domain, &domain_len, &secure, &httponly) == FAILURE) {
00207               return;
00208        }
00209 
00210        if (php_setcookie(name, name_len, value, value_len, expires, path, path_len, domain, domain_len, secure, 0, httponly TSRMLS_CC) == SUCCESS) {
00211               RETVAL_TRUE;
00212        } else {
00213               RETVAL_FALSE;
00214        }
00215 }
00216 /* }}} */
00217 
00218 
00219 /* {{{ proto bool headers_sent([string &$file [, int &$line]])
00220    Returns true if headers have already been sent, false otherwise */
00221 PHP_FUNCTION(headers_sent)
00222 {
00223        zval *arg1 = NULL, *arg2 = NULL;
00224        char *file="";
00225        int line=0;
00226 
00227        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|zz", &arg1, &arg2) == FAILURE)
00228               return;
00229 
00230        if (SG(headers_sent)) {
00231               line = php_get_output_start_lineno(TSRMLS_C);
00232               file = php_get_output_start_filename(TSRMLS_C);
00233        }
00234 
00235        switch(ZEND_NUM_ARGS()) {
00236        case 2:
00237               zval_dtor(arg2);
00238               ZVAL_LONG(arg2, line);
00239        case 1:
00240               zval_dtor(arg1);
00241               if (file) { 
00242                      ZVAL_STRING(arg1, file, 1);
00243               } else {
00244                      ZVAL_STRING(arg1, "", 1);
00245               }      
00246               break;
00247        }
00248 
00249        if (SG(headers_sent)) {
00250               RETURN_TRUE;
00251        } else {
00252               RETURN_FALSE;
00253        }
00254 }
00255 /* }}} */
00256 
00257 /* {{{ php_head_apply_header_list_to_hash
00258    Turn an llist of sapi_header_struct headers into a numerically indexed zval hash */
00259 static void php_head_apply_header_list_to_hash(void *data, void *arg TSRMLS_DC)
00260 {
00261        sapi_header_struct *sapi_header = (sapi_header_struct *)data;
00262 
00263        if (arg && sapi_header) {
00264               add_next_index_string((zval *)arg, (char *)(sapi_header->header), 1);
00265        }
00266 }
00267 
00268 /* {{{ proto array headers_list(void)
00269    Return list of headers to be sent / already sent */
00270 PHP_FUNCTION(headers_list)
00271 {
00272        if (zend_parse_parameters_none() == FAILURE) {
00273               return;
00274        }
00275 
00276        if (!&SG(sapi_headers).headers) {
00277               RETURN_FALSE;
00278        }
00279        array_init(return_value);
00280        zend_llist_apply_with_argument(&SG(sapi_headers).headers, php_head_apply_header_list_to_hash, return_value TSRMLS_CC);
00281 }
00282 /* }}} */
00283 
00284 /*
00285  * Local variables:
00286  * tab-width: 4
00287  * c-basic-offset: 4
00288  * vim600: sw=4 ts=4 fdm=marker
00289  * vim<600: sw=4 ts=4 * End:
00290  */