/** * Sends the headers to the client * * @return boolean */ PHP_METHOD(Phalcon_Http_Response_Headers, send){ zval *headers, *value = NULL, *header = NULL; zval *http_header = NULL; zval copy; int use_copy; HashTable *ah0; HashPosition hp0; zval **hd; sapi_header_line ctr = { NULL, 0, 0 }; PHALCON_MM_GROW(); if (!SG(headers_sent)) { PHALCON_OBS_VAR(headers); phalcon_read_property_this(&headers, this_ptr, SL("_headers"), PH_NOISY_CC); phalcon_is_iterable(headers, &ah0, &hp0, 0, 0); while (zend_hash_get_current_data_ex(ah0, (void**) &hd, &hp0) == SUCCESS) { PHALCON_GET_HKEY(header, ah0, hp0); PHALCON_GET_HVALUE(value); if (PHALCON_IS_NOT_EMPTY(value)) { PHALCON_INIT_NVAR(http_header); PHALCON_CONCAT_VSV(http_header, header, ": ", value); ctr.line = Z_STRVAL_P(http_header); ctr.line_len = Z_STRLEN_P(http_header); sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); } else { zend_make_printable_zval(header, ©, &use_copy); if (unlikely(use_copy)) { header = © } ctr.line = Z_STRVAL_P(header); ctr.line_len = Z_STRLEN_P(header); sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); if (unlikely(use_copy)) { zval_dtor(©); } } zend_hash_move_forward_ex(ah0, &hp0); } RETURN_MM_TRUE; } RETURN_MM_FALSE; }
/** {{{ int yaf_response_set_redirect(yaf_response_t *response, char *url, int len TSRMLS_DC) */ int yaf_response_set_redirect(yaf_response_t *response, char *url, int len TSRMLS_DC) { sapi_header_line ctr = {0}; ctr.line_len = spprintf(&(ctr.line), 0, "%s %s", "Location:", url); ctr.response_code = 0; if (sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC) == SUCCESS) { efree(ctr.line); return 1; } efree(ctr.line); return 0; }
SAPI_API int sapi_add_header_ex(char *header_line, size_t header_line_len, zend_bool duplicate, zend_bool replace) { sapi_header_line ctr = {0}; int r; ctr.line = header_line; ctr.line_len = header_line_len; r = sapi_header_op(replace ? SAPI_HEADER_REPLACE : SAPI_HEADER_ADD, &ctr); if (!duplicate) efree(header_line); return r; }
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) { char *cookie, *encoded_value = NULL; int len=sizeof("Set-Cookie: "); char *dt; sapi_header_line ctr = {0}; int result; if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie names can not contain any of the folllowing '=,; \\t\\r\\n\\013\\014' (%s)", name ); return FAILURE; } if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie values can not contain any of the folllowing ',; \\t\\r\\n\\013\\014' (%s)", value ); return FAILURE; } len += name_len; if (value && url_encode) { int encoded_value_len; encoded_value = php_url_encode(value, value_len, &encoded_value_len); len += encoded_value_len; } else if ( value ) { encoded_value = estrdup(value); len += value_len; } if (path) { len += path_len; } if (domain) { len += domain_len; } cookie = emalloc(len + 100); if (value && value_len == 0) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date 1 year and 1 second in the past */ time_t t = time(NULL) - 31536001; dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, t, 0 TSRMLS_CC); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s", name, dt); efree(dt); } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : ""); if (expires > 0) { strlcat(cookie, "; expires=", len + 100); 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); strlcat(cookie, dt, len + 100); efree(dt); } } if (encoded_value) { efree(encoded_value); } if (path && path_len > 0) { strlcat(cookie, "; path=", len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { strlcat(cookie, "; domain=", len + 100); strlcat(cookie, domain, len + 100); } if (secure) { strlcat(cookie, "; secure", len + 100); } if (httponly) { strlcat(cookie, "; httponly", len + 100); } ctr.line = cookie; ctr.line_len = strlen(cookie); result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); efree(cookie); return result; }
PHP_METHOD(jsonrpc_server, execute) { zval *object; zval *func; zval **func_params, **exec_params; zval *data, *payload, *error, *response; zval **payload_method, **payload_params; zval **id = NULL; sapi_header_line ctr = {0}; smart_str buf = {0}; zend_bool response_type = 0; // type:0 =>json type:1 => array object = getThis(); if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &response_type) == FAILURE) { return ; } payload = zend_read_property( php_jsonrpc_server_entry, getThis(), "payload", sizeof("payload")-1, 0 TSRMLS_CC ); MAKE_STD_ZVAL(error); array_init(error); MAKE_STD_ZVAL(func); ZVAL_STRINGL(func, "jsonformat", sizeof("jsonformat") - 1, 0); if (call_user_function(NULL, &object, func, return_value, 0, NULL TSRMLS_CC) == FAILURE){ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed calling Jsonrpc_Server::jsonformat()"); return ; } if (!Z_BVAL_P(return_value)){ add_assoc_long(error, "code", -32700); add_assoc_string(error, "message", "Parse error", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; } ZVAL_STRINGL(func, "rpcformat", sizeof("rpcformat") - 1, 0); if (call_user_function(NULL, &object, func, return_value, 0, NULL TSRMLS_CC) == FAILURE){ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed calling Jsonrpc_Server::rpcformat()"); return ; } if (Z_LVAL_P(return_value) == -32600){ add_assoc_long(error, "code", -32600); add_assoc_string(error, "message", "Invalid Request", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; }else if (Z_LVAL_P(return_value) == -32601){ add_assoc_long(error, "code", -32601); add_assoc_string(error, "message", "Method not found", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; }else if (Z_LVAL_P(return_value) == -32602){ add_assoc_long(error, "code", -32602); add_assoc_string(error, "message", "Invalid params", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; }else if (Z_LVAL_P(return_value) == -32603){ add_assoc_long(error, "code", -32603); add_assoc_string(error, "message", "Internal error", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; } exec_params = emalloc(sizeof(zval *) * 2); payload = zend_read_property( php_jsonrpc_server_entry, getThis(), "payload", sizeof("payload")-1, 0 TSRMLS_CC ); if (zend_hash_find(Z_ARRVAL_P(payload), "method", strlen("method")+1, (void **)&payload_method) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "method is not find"); return ; } //jsr_dump_zval(*payload_method); exec_params[0] = *payload_method; if (zend_hash_find(Z_ARRVAL_P(payload), "params", strlen("params")+1, (void **)&payload_params) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "params is not find"); return ; } //shurrik_dump_zval(*payload_params); exec_params[1] = *payload_params; MAKE_STD_ZVAL(data); ZVAL_STRINGL(func, "executeprocedure", sizeof("executeprocedure") - 1, 0); if (call_user_function(NULL, &object, func, data, 2, exec_params TSRMLS_CC) == FAILURE){ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed calling Jsonrpc_Server::executeprocedure()"); return ; } efree(exec_params); if (Z_LVAL_P(data) == -32601){ add_assoc_long(error, "code", -32601); add_assoc_string(error, "message", "Method not found", 1); zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "error", error); goto getresponse; } zval_dtor(return_value); array_init(return_value); add_assoc_string(return_value, "jsonrpc", "2.0", 1); add_assoc_zval(return_value, "result", data); goto getresponse; return ; getresponse: if (Z_TYPE_P(payload) == IS_ARRAY){ if (!zend_symtable_exists(Z_ARRVAL_P(payload), "id", strlen("id")+1)) { }else { if (zend_hash_find(Z_ARRVAL_P(payload), "id", strlen("id")+1, (void **)&id ) == FAILURE) { //php_error_docref(NULL TSRMLS_CC, E_WARNING, "closeure is not expected to be a valid callback"); //return ; } if (Z_TYPE_PP(id) == IS_NULL){ add_assoc_null(return_value, "id"); }else if(Z_TYPE_PP(id) == IS_STRING){ convert_to_string(*id); add_assoc_string(return_value, "id", Z_STRVAL_PP(id), 0); }else if (Z_TYPE_PP(id) == IS_LONG){ convert_to_long(*id); add_assoc_long(return_value, "id", Z_LVAL_PP(id)); } } }else { add_assoc_null(return_value, "id"); } ctr.line = "Content-Type: application/json"; ctr.line_len = strlen(ctr.line); sapi_header_op(SAPI_HEADER_REPLACE, &ctr TSRMLS_CC); /*if (!response_type){ php_json_encode(&buf, return_value, 0 TSRMLS_CC); zval_dtor(return_value); zval_dtor(error); ZVAL_STRINGL(return_value, buf.c, buf.len, 1); smart_str_free(&buf); }*/ if (!response_type){ exec_params = emalloc(sizeof(zval *) * 1); exec_params[0] = return_value; ZVAL_STRINGL(func, "Jsonrpc_Yajl::generate", sizeof("Jsonrpc_Yajl::generate") - 1, 0); if (call_user_function(EG(function_table), NULL, func, return_value, 1, exec_params TSRMLS_CC) == FAILURE) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed calling Jsonrpc_Yajl::generate()"); return ; } //ZVAL_STRINGL(return_value, Z_STRVAL_P(return_value), Z_STRLEN_P(return_value), 1); zval_dtor(error); efree(exec_params); } efree(func); return ; }
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) { char *cookie; int len=sizeof("Set-Cookie: "); zend_string *dt; sapi_header_line ctr = {0}; int result; zend_string *encoded_value = NULL; if (name && strpbrk(name, "=,; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie names cannot contain any of the following '=,; \\t\\r\\n\\013\\014'" ); return FAILURE; } if (!url_encode && value && strpbrk(value, ",; \t\r\n\013\014") != NULL) { /* man isspace for \013 and \014 */ zend_error( E_WARNING, "Cookie values cannot contain any of the following ',; \\t\\r\\n\\013\\014'" ); return FAILURE; } len += name_len; if (value && url_encode) { encoded_value = php_url_encode(value, value_len); len += encoded_value->len; } else if (value) { encoded_value = zend_string_init(value, value_len, 0); len += encoded_value->len; } if (path) { len += path_len; } if (domain) { len += domain_len; } cookie = emalloc(len + 100); if (value && value_len == 0) { /* * MSIE doesn't delete a cookie when you set it to a null value * so in order to force cookies to be deleted, even on MSIE, we * pick an expiry date in the past */ 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); snprintf(cookie, len + 100, "Set-Cookie: %s=deleted; expires=%s; Max-Age=0", name, dt->val); zend_string_free(dt); } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value->val : ""); if (expires > 0) { const char *p; char tsdelta[13]; strlcat(cookie, COOKIE_EXPIRES, len + 100); 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); /* check to make sure that the year does not exceed 4 digits in length */ p = zend_memrchr(dt->val, '-', dt->len); if (!p || *(p + 5) != ' ') { zend_string_free(dt); efree(cookie); zend_string_free(encoded_value); zend_error(E_WARNING, "Expiry date cannot have a year greater than 9999"); return FAILURE; } strlcat(cookie, dt->val, len + 100); zend_string_free(dt); snprintf(tsdelta, sizeof(tsdelta), "%li", (long) difftime(expires, time(NULL))); strlcat(cookie, COOKIE_MAX_AGE, len + 100); strlcat(cookie, tsdelta, len + 100); } } if (encoded_value) { zend_string_free(encoded_value); } if (path && path_len > 0) { strlcat(cookie, COOKIE_PATH, len + 100); strlcat(cookie, path, len + 100); } if (domain && domain_len > 0) { strlcat(cookie, COOKIE_DOMAIN, len + 100); strlcat(cookie, domain, len + 100); } if (secure) { strlcat(cookie, COOKIE_SECURE, len + 100); } if (httponly) { strlcat(cookie, COOKIE_HTTPONLY, len + 100); } ctr.line = cookie; ctr.line_len = strlen(cookie); result = sapi_header_op(SAPI_HEADER_ADD, &ctr TSRMLS_CC); efree(cookie); return result; }
/** * Writes the log to the stream itself * * @param string $message * @param int $type * @param int $time * @param array $context * @see http://www.firephp.org/Wiki/Reference/Protocol */ PHP_METHOD(Phalcon_Logger_Adapter_Firephp, logInternal){ zval *message, *type, *time, *context, *formatter = NULL, *applied_format = NULL; zval *initialized, *index; sapi_header_line h = { NULL, 0, 0 }; smart_str str = { 0 }; int size, offset; int separate_index = 0; size_t num_bytes; const int chunk = 4500; /* If headers has already been sent, we can do nothing. Exit early. */ if (SG(headers_sent)) { RETURN_FALSE; } PHALCON_MM_GROW(); phalcon_fetch_params(1, 4, 0, &message, &type, &time, &context); PHALCON_CALL_METHOD(&formatter, getThis(), "getformatter"); initialized = phalcon_read_static_property_ce(phalcon_logger_adapter_firephp_ce, SL("_initialized")); if (!zend_is_true(initialized)) { /** * Send the required initialization headers. * Use Zend API here so that the user can see the progress and because * if we delegate this to Phalcon and there will be a fatal errors, * chances are that the headers will never ne sent. */ h.line = "X-Wf-Protocol-1: http://meta.wildfirehq.org/Protocol/JsonStream/0.2"; h.line_len = sizeof("X-Wf-Protocol-1: http://meta.wildfirehq.org/Protocol/JsonStream/0.2")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h); h.line = "X-Wf-1-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3"; h.line_len = sizeof("X-Wf-1-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h); h.line = "X-Wf-1-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1"; h.line_len = sizeof("X-Wf-1-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h); ZVAL_TRUE(initialized); /* This will also update the property because "initialized" was not separated */ } PHALCON_CALL_METHOD(&applied_format, formatter, "format", message, type, time, context); convert_to_string(applied_format); index = phalcon_read_static_property_ce(phalcon_logger_adapter_firephp_ce, SL("_index")); assert(Z_TYPE_P(index) == IS_LONG); size = Z_STRLEN_P(applied_format); offset = 0; /** * We need to send the data in chunks not exceeding 5,000 bytes. * Allocate the smart string once to avoid performance penalties. */ num_bytes = smart_str_alloc(&str, (uint)(size > chunk ? chunk : size), 0); while (size > 0) { smart_str_appends(&str, "X-Wf-1-1-1-"); smart_str_append_long(&str, Z_LVAL_P(index)); smart_str_appends(&str, ": "); num_bytes = size > chunk ? chunk : size; if (offset) { /* This is not the first chunk, prepend the payload with "|" */ smart_str_appendc(&str, '|'); } /* Grab the chunk from the encoded string */ smart_str_appendl(&str, Z_STRVAL_P(applied_format) + offset, num_bytes); size -= num_bytes; offset += num_bytes; if (size) { /* If we have more data to send, append "|/" */ smart_str_appendl(&str, "|\\", 2); } smart_str_0(&str); /* Not strictly necessary but just to be safe */ /* Send the result */ h.line = str.s->val; h.line_len = str.s->len; sapi_header_op(SAPI_HEADER_REPLACE, &h); ZVAL_LONG(index, Z_LVAL_P(index)+1); /** * Do not free and then reallocate memory. Just pretend the string * is empty. We will take care of deallocation later. */ str.s->len = 0; } if (separate_index) { phalcon_update_static_property_ce(phalcon_logger_adapter_firephp_ce, SL("_index"), index); } /* Deallocate the smnart string if it is not empty */ smart_str_free(&str); PHALCON_MM_RESTORE(); }
/** * Writes the log to the stream itself * * @param string $message * @param int $type * @param int $time * @see http://www.firephp.org/Wiki/Reference/Protocol */ PHP_METHOD(Phalcon_Logger_Adapter_Firephp, logInternal){ zval *message, *type, *time, *formatter, *applied_format; zval *initialized, *index; sapi_header_line h = { NULL, 0, 0 }; smart_str str = { NULL, 0, 0 }; int size, offset, num_bytes; const int chunk = 4960; /* If headers has already been sent, we can do nothing. Exit early. */ if (SG(headers_sent)) { RETURN_FALSE; } PHALCON_MM_GROW(); phalcon_fetch_params(1, 3, 0, &message, &type, &time); PHALCON_INIT_VAR(formatter); phalcon_call_method(formatter, this_ptr, "getformatter"); PHALCON_OBS_VAR(initialized); phalcon_read_static_property(&initialized, SL("phalcon\\logger\\adapter\\firephp"), SL("_initialized") TSRMLS_CC); if (!zend_is_true(initialized)) { /** * Send the required initialization headers. * Use Zend API here so that the user can see the progress and because * if we delegate this to Phalcon and there will be a fatal errors, * chances are that the headers will never ne sent. */ h.line = "X-Wf-Protocol-1: http://meta.wildfirehq.org/Protocol/JsonStream/0.2"; h.line_len = sizeof("X-Wf-Protocol-1: http://meta.wildfirehq.org/Protocol/JsonStream/0.2")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC); h.line = "X-Wf-1-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3"; h.line_len = sizeof("X-Wf-1-Plugin-1: http://meta.firephp.org/Wildfire/Plugin/FirePHP/Library-FirePHPCore/0.3")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC); h.line = "X-Wf-1-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1"; h.line_len = sizeof("X-Wf-1-Structure-1: http://meta.firephp.org/Wildfire/Structure/FirePHP/FirebugConsole/0.1")-1; sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC); ZVAL_TRUE(initialized); /* This will also update the property because "initialized" was not separated */ } PHALCON_INIT_VAR(applied_format); phalcon_call_method_p3(applied_format, formatter, "format", message, type, time); if (Z_TYPE_P(applied_format) != IS_STRING) { PHALCON_THROW_EXCEPTION_STR(phalcon_logger_exception_ce, "The formatted message is not valid"); return; } PHALCON_OBS_VAR(index); phalcon_read_static_property(&index, SL("phalcon\\logger\\adapter\\firephp"), SL("_index") TSRMLS_CC); size = Z_STRLEN_P(applied_format); offset = 0; /** * We need to send the data in chunks not exceeding 5,000 bytes. * Allocate the smart string once to avoid performance penalties. */ smart_str_alloc4(&str, (size > chunk ? chunk : size), 0, num_bytes); while (size > 0) { smart_str_appends(&str, "X-Wf-1-1-1-"); smart_str_append_long(&str, Z_LVAL_P(index)); smart_str_appends(&str, ": "); num_bytes = size > chunk ? chunk : size; if (offset) { /* This is not the first chunk, prepend the payload with "|" */ smart_str_appendc(&str, '|'); } /* Grab the chunk from the encoded string */ smart_str_appendl(&str, Z_STRVAL_P(applied_format) + offset, num_bytes); size -= num_bytes; offset += num_bytes; if (size) { /* If we have more data to send, append "|/" */ smart_str_appendl(&str, "|\\", 2); } smart_str_0(&str); /* Not strictly necessary but just to be safe */ /* Send the result */ h.line = str.c; h.line_len = str.len; sapi_header_op(SAPI_HEADER_REPLACE, &h TSRMLS_CC); /* Update header index; this will update Phalcon\Logger\Adapter\Firephp as well */ ZVAL_LONG(index, Z_LVAL_P(index)+1); /** * Do not free and then reallocate memory. Just pretend the string * is empty. We will take care of deallocation later. */ str.len = 0; } /* Deallocate the smnart string if it is not empty */ if (str.c) { smart_str_free(&str); } PHALCON_MM_RESTORE(); }