static void browscap_entry_dtor_persistent(zval *zvalue) /* {{{ */ { if (Z_TYPE_P(zvalue) == IS_ARRAY) { zend_hash_destroy(Z_ARRVAL_P(zvalue)); free(Z_ARR_P(zvalue)); } else if (Z_TYPE_P(zvalue) == IS_STRING) { zend_string_release(Z_STR_P(zvalue)); } }
static void zend_file_cache_serialize_zval(zval *zv, zend_persistent_script *script, zend_file_cache_metainfo *info, void *buf) { switch (Z_TYPE_P(zv)) { case IS_STRING: case IS_CONSTANT: if (!IS_SERIALIZED(Z_STR_P(zv))) { SERIALIZE_STR(Z_STR_P(zv)); } break; case IS_ARRAY: if (!IS_SERIALIZED(Z_ARR_P(zv))) { HashTable *ht; SERIALIZE_PTR(Z_ARR_P(zv)); ht = Z_ARR_P(zv); UNSERIALIZE_PTR(ht); zend_file_cache_serialize_hash(ht, script, info, buf, zend_file_cache_serialize_zval); } break; case IS_REFERENCE: if (!IS_SERIALIZED(Z_REF_P(zv))) { zend_reference *ref; SERIALIZE_PTR(Z_REF_P(zv)); ref = Z_REF_P(zv); UNSERIALIZE_PTR(ref); zend_file_cache_serialize_zval(&ref->val, script, info, buf); } break; case IS_CONSTANT_AST: if (!IS_SERIALIZED(Z_AST_P(zv))) { zend_ast_ref *ast; SERIALIZE_PTR(Z_AST_P(zv)); ast = Z_AST_P(zv); UNSERIALIZE_PTR(ast); if (!IS_SERIALIZED(ast->ast)) { ast->ast = zend_file_cache_serialize_ast(ast->ast, script, info, buf); } } break; } }
/* {{{ config_zval_dtor */ PHPAPI void config_zval_dtor(zval *zvalue) { if (Z_TYPE_P(zvalue) == IS_ARRAY) { zend_hash_destroy(Z_ARRVAL_P(zvalue)); free(Z_ARR_P(zvalue)); } else if (Z_TYPE_P(zvalue) == IS_STRING) { zend_string_release(Z_STR_P(zvalue)); } }
static inline void zend_clone_zval(zval *src, int bind) { void *ptr; if (Z_IMMUTABLE_P(src)) { return; } switch (Z_TYPE_P(src)) { case IS_STRING: case IS_CONSTANT: Z_STR_P(src) = zend_clone_str(Z_STR_P(src)); break; case IS_ARRAY: if (Z_ARR_P(src) != &EG(symbol_table)) { if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_ARR_P(src))) != NULL) { Z_ARR_P(src) = ptr; } else { zend_array *old = Z_ARR_P(src); Z_ARR_P(src) = emalloc(sizeof(zend_array)); Z_ARR_P(src)->gc = old->gc; if (bind && Z_REFCOUNT_P(src) > 1) { accel_xlat_set(old, Z_ARR_P(src)); } zend_hash_clone_zval(Z_ARRVAL_P(src), old, 0); } } break; case IS_REFERENCE: if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_REF_P(src))) != NULL) { Z_REF_P(src) = ptr; } else { zend_reference *old = Z_REF_P(src); ZVAL_NEW_REF(src, &old->val); Z_REF_P(src)->gc = old->gc; if (bind && Z_REFCOUNT_P(src) > 1) { accel_xlat_set(old, Z_REF_P(src)); } zend_clone_zval(Z_REFVAL_P(src), bind); } break; case IS_CONSTANT_AST: if (bind && Z_REFCOUNT_P(src) > 1 && (ptr = accel_xlat_get(Z_AST_P(src))) != NULL) { Z_AST_P(src) = ptr; } else { zend_ast_ref *old = Z_AST_P(src); ZVAL_NEW_AST(src, old->ast); Z_AST_P(src)->gc = old->gc; if (bind && Z_REFCOUNT_P(src) > 1) { accel_xlat_set(old, Z_AST_P(src)); } Z_ASTVAL_P(src) = zend_ast_clone(Z_ASTVAL_P(src)); } break; } }
static void litespeed_php_import_environment_variables(zval *array_ptr) { char buf[128]; char **env, *p, *t = buf; size_t alloc_size = sizeof(buf); unsigned long nlen; /* ptrdiff_t is not portable */ if (Z_TYPE(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_ENV]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_ENV])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_ENV]); return; } else if (Z_TYPE(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY && Z_ARR_P(array_ptr) != Z_ARR(PG(http_globals)[TRACK_VARS_SERVER]) && zend_hash_num_elements(Z_ARRVAL(PG(http_globals)[TRACK_VARS_SERVER])) > 0 ) { zval_ptr_dtor_nogc(array_ptr); ZVAL_DUP(array_ptr, &PG(http_globals)[TRACK_VARS_SERVER]); return; } tsrm_env_lock(); for (env = environ; env != NULL && *env != NULL; env++) { p = strchr(*env, '='); if (!p) { /* malformed entry? */ continue; } nlen = p - *env; if (nlen >= alloc_size) { alloc_size = nlen + 64; t = (t == buf ? emalloc(alloc_size): erealloc(t, alloc_size)); } memcpy(t, *env, nlen); t[nlen] = '\0'; add_variable(t, nlen, p + 1, strlen( p + 1 ), array_ptr); } tsrm_env_unlock(); if (t != buf && t != NULL) { efree(t); } }
void skyray_http_request_resolve_cookies_if_needed(skyray_http_request_t *self) { if (!ZVAL_IS_NULL(&self->cookie_params)) { return; } zval *lines = skyray_http_message_get_header(&self->message, intern_str_cookie, 0); if (!lines) { return; } array_init(&self->cookie_params); zend_array *ht = Z_ARR_P(lines); zend_array *ht2; zval tmp, *data;; zend_hash_internal_pointer_reset(ht); while(zend_hash_has_more_elements(ht) == SUCCESS) { array_init(&tmp); data = zend_hash_get_current_data(ht); php_explode(intern_str_param_delimiter, Z_STR_P(data), &tmp, ZEND_LONG_MAX); ht2 = Z_ARR_P(&tmp); zend_hash_internal_pointer_reset(ht2); while (zend_hash_has_more_elements(ht2) == SUCCESS) { data = zend_hash_get_current_data(ht2); char *c = strchr(Z_STR_P(data)->val, '='); int len = c - Z_STR_P(data)->val; add_assoc_str_ex(&self->cookie_params, Z_STR_P(data)->val, len, zend_string_init(c + 1, Z_STR_P(data)->len - len - 1, 0)); zend_hash_move_forward(ht2); } zval_ptr_dtor(&tmp); zend_hash_move_forward(ht); } }
static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, void * arg ) { int filter_arg = (Z_ARR_P((zval *)arg) == Z_ARR(PG(http_globals)[TRACK_VARS_ENV])) ? PARSE_ENV : PARSE_SERVER; char * new_val = (char *) pValue; size_t new_val_len; if (sapi_module.input_filter(filter_arg, (char *)pKey, &new_val, valLen, &new_val_len)) { php_register_variable_safe((char *)pKey, new_val, new_val_len, (zval *)arg ); } return 1; }
static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) { zval *option_buffer; if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) { HashTable *dictionary; ZVAL_DEREF(option_buffer); if (Z_TYPE_P(option_buffer) != IS_ARRAY) { php_error_docref(NULL, E_WARNING, "dictionary must be of type array, got %s", zend_get_type_by_const(Z_TYPE_P(option_buffer))); return 0; } dictionary = Z_ARR_P(option_buffer); if (zend_hash_num_elements(dictionary) > 0) { char *dictptr; zval *cur; zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary)); zend_string **end, **ptr = strings - 1; ZEND_HASH_FOREACH_VAL(dictionary, cur) { int i; *++ptr = zval_get_string(cur); if (!*ptr || (*ptr)->len == 0) { if (*ptr) { efree(*ptr); } while (--ptr >= strings) { efree(ptr); } efree(strings); php_error_docref(NULL, E_WARNING, "dictionary entries must be non-empty strings"); return 0; } for (i = 0; i < (*ptr)->len; i++) { if ((*ptr)->val[i] == 0) { do { efree(ptr); } while (--ptr >= strings); efree(strings); php_error_docref(NULL, E_WARNING, "dictionary entries must not contain a NULL-byte"); return 0; } } *dictlen += (*ptr)->len + 1; } ZEND_HASH_FOREACH_END();
static void zend_persist_zval_const(zval *z) { zend_uchar flags; void *new_ptr; switch (Z_TYPE_P(z)) { case IS_STRING: case IS_CONSTANT: flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); zend_accel_memdup_interned_string(Z_STR_P(z)); Z_GC_FLAGS_P(z) |= flags; Z_TYPE_FLAGS_P(z) &= ~(IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); break; case IS_ARRAY: new_ptr = zend_shared_alloc_get_xlat_entry(Z_ARR_P(z)); if (new_ptr) { Z_ARR_P(z) = new_ptr; Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; } else { if (Z_IMMUTABLE_P(z)) { Z_ARR_P(z) = zend_accel_memdup(Z_ARR_P(z), sizeof(zend_array)); zend_hash_persist_immutable(Z_ARRVAL_P(z)); } else { GC_REMOVE_FROM_BUFFER(Z_ARR_P(z)); zend_accel_store(Z_ARR_P(z), sizeof(zend_array)); zend_hash_persist(Z_ARRVAL_P(z), zend_persist_zval); /* make immutable array */ Z_TYPE_FLAGS_P(z) = IS_TYPE_IMMUTABLE; GC_REFCOUNT(Z_COUNTED_P(z)) = 2; Z_ARRVAL_P(z)->u.flags &= ~HASH_FLAG_APPLY_PROTECTION; } } break; case IS_REFERENCE: new_ptr = zend_shared_alloc_get_xlat_entry(Z_REF_P(z)); if (new_ptr) { Z_REF_P(z) = new_ptr; } else { zend_accel_store(Z_REF_P(z), sizeof(zend_reference)); zend_persist_zval(Z_REFVAL_P(z)); } break; case IS_CONSTANT_AST: new_ptr = zend_shared_alloc_get_xlat_entry(Z_AST_P(z)); if (new_ptr) { Z_AST_P(z) = new_ptr; } else { zend_accel_store(Z_AST_P(z), sizeof(zend_ast_ref)); Z_ASTVAL_P(z) = zend_persist_ast(Z_ASTVAL_P(z)); } break; } }
static void php_exec_ex(INTERNAL_FUNCTION_PARAMETERS, int mode) /* {{{ */ { char *cmd; size_t cmd_len; zval *ret_code=NULL, *ret_array=NULL; int ret; ZEND_PARSE_PARAMETERS_START(1, (mode ? 2 : 3)) Z_PARAM_STRING(cmd, cmd_len) Z_PARAM_OPTIONAL if (!mode) { Z_PARAM_ZVAL_DEREF(ret_array) } Z_PARAM_ZVAL_DEREF(ret_code) ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE); if (!cmd_len) { php_error_docref(NULL, E_WARNING, "Cannot execute a blank command"); RETURN_FALSE; } if (strlen(cmd) != cmd_len) { php_error_docref(NULL, E_WARNING, "NULL byte detected. Possible attack"); RETURN_FALSE; } if (!ret_array) { ret = php_exec(mode, cmd, NULL, return_value); } else { if (Z_TYPE_P(ret_array) != IS_ARRAY) { zval_ptr_dtor(ret_array); array_init(ret_array); } else if (Z_REFCOUNT_P(ret_array) > 1) { zval_ptr_dtor(ret_array); ZVAL_ARR(ret_array, zend_array_dup(Z_ARR_P(ret_array))); } ret = php_exec(2, cmd, ret_array, return_value); } if (ret_code) { zval_ptr_dtor(ret_code); ZVAL_LONG(ret_code, ret); } }
static void zend_persist_zval_calc(zval *z) { zend_uchar flags; uint size; switch (Z_TYPE_P(z)) { case IS_STRING: case IS_CONSTANT: flags = Z_GC_FLAGS_P(z) & ~ (IS_STR_PERSISTENT | IS_STR_INTERNED | IS_STR_PERMANENT); ADD_INTERNED_STRING(Z_STR_P(z), 0); if (!Z_REFCOUNTED_P(z)) { Z_TYPE_FLAGS_P(z) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE); } Z_GC_FLAGS_P(z) |= flags; break; case IS_ARRAY: size = zend_shared_memdup_size(Z_ARR_P(z), sizeof(zend_array)); if (size) { ADD_SIZE(size); zend_hash_persist_calc(Z_ARRVAL_P(z), zend_persist_zval_calc); } break; case IS_REFERENCE: size = zend_shared_memdup_size(Z_REF_P(z), sizeof(zend_reference)); if (size) { ADD_SIZE(size); zend_persist_zval_calc(Z_REFVAL_P(z)); } break; case IS_CONSTANT_AST: size = zend_shared_memdup_size(Z_AST_P(z), sizeof(zend_ast_ref)); if (size) { ADD_SIZE(size); zend_persist_ast_calc(Z_ASTVAL_P(z)); } break; } }
static zend_bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) { zval *option_buffer; if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) { ZVAL_DEREF(option_buffer); switch (Z_TYPE_P(option_buffer)) { case IS_STRING: { zend_string *str = Z_STR_P(option_buffer); int i; zend_bool last_null = 1; for (i = 0; i < ZSTR_LEN(str); i++) { if (ZSTR_VAL(str)[i]) { last_null = 0; } else { if (last_null) { php_error_docref(NULL, E_WARNING, "dictionary string must not contain empty entries (two consecutive NULL-bytes or one at the very beginning)"); return 0; } last_null = 1; } } if (!last_null) { php_error_docref(NULL, E_WARNING, "dictionary string must be NULL-byte terminated (each dictionary entry has to be NULL-terminated)"); } *dict = emalloc(ZSTR_LEN(str)); memcpy(*dict, ZSTR_VAL(str), ZSTR_LEN(str)); *dictlen = ZSTR_LEN(str); } break; case IS_ARRAY: { HashTable *dictionary = Z_ARR_P(option_buffer); if (zend_hash_num_elements(dictionary) > 0) { char *dictptr; zval *cur; zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary)); zend_string **end, **ptr = strings - 1; ZEND_HASH_FOREACH_VAL(dictionary, cur) { int i; *++ptr = zval_get_string(cur); if (!*ptr || ZSTR_LEN(*ptr) == 0) { if (*ptr) { efree(*ptr); } while (--ptr >= strings) { efree(ptr); } efree(strings); php_error_docref(NULL, E_WARNING, "dictionary entries must be non-empty strings"); return 0; } for (i = 0; i < ZSTR_LEN(*ptr); i++) { if (ZSTR_VAL(*ptr)[i] == 0) { do { efree(ptr); } while (--ptr >= strings); efree(strings); php_error_docref(NULL, E_WARNING, "dictionary entries must not contain a NULL-byte"); return 0; } } *dictlen += ZSTR_LEN(*ptr) + 1; } ZEND_HASH_FOREACH_END(); dictptr = *dict = emalloc(*dictlen); ptr = strings; end = strings + zend_hash_num_elements(dictionary); do { memcpy(dictptr, ZSTR_VAL(*ptr), ZSTR_LEN(*ptr)); dictptr += ZSTR_LEN(*ptr); *dictptr++ = 0; zend_string_release(*ptr); } while (++ptr != end); efree(strings); } } break;
static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t type, HashTable *vars) /* {{{ */ { char *decode = NULL; switch (type &~ EXT_TYPE_UNUSED) { case IS_CV: { zend_string *var = ops->vars[EX_VAR_TO_NUM(op->var)]; asprintf(&decode, "$%.*s%c", var->len <= 19 ? (int) var->len : 18, var->val, var->len <= 19 ? 0 : '+'); } break; case IS_VAR: case IS_TMP_VAR: { zend_ulong id = 0, *pid = NULL; if (vars != NULL) { if ((pid = zend_hash_index_find_ptr(vars, (zend_ulong) ops->vars - op->var))) { id = *pid; } else { id = zend_hash_num_elements(vars); zend_hash_index_update_mem(vars, (zend_ulong) ops->vars - op->var, &id, sizeof(zend_ulong)); } } asprintf(&decode, "@" ZEND_ULONG_FMT, id); } break; case IS_CONST: { zval *literal = RT_CONSTANT(ops, *op); switch (Z_TYPE_P(literal)) { case IS_UNDEF: decode = zend_strndup("", 0); break; case IS_NULL: decode = zend_strndup(ZEND_STRL("null")); break; case IS_FALSE: decode = zend_strndup(ZEND_STRL("false")); break; case IS_TRUE: decode = zend_strndup(ZEND_STRL("true")); break; case IS_LONG: asprintf(&decode, "%lld", Z_LVAL_P(literal)); break; case IS_DOUBLE: asprintf(&decode, "%.*G", 14, Z_DVAL_P(literal)); break; case IS_STRING: { int i; zend_string *str = php_addcslashes(Z_STR_P(literal), 0, "\\\"", 2); for (i = 0; i < str->len; i++) { if (str->val[i] < 32) { str->val[i] = ' '; } } asprintf(&decode, "\"%.*s\"%c", str->len <= 18 ? (int) str->len : 17, str->val, str->len <= 18 ? 0 : '+'); zend_string_release(str); } break; case IS_RESOURCE: asprintf(&decode, "Rsrc #%d", Z_RES_HANDLE_P(literal)); break; case IS_ARRAY: asprintf(&decode, "array(%d)", zend_hash_num_elements(Z_ARR_P(literal))); break; case IS_OBJECT: { zend_string *str = Z_OBJCE_P(literal)->name; asprintf(&decode, "%.*s%c", str->len <= 18 ? (int) str->len : 18, str->val, str->len <= 18 ? 0 : '+'); } break; case IS_CONSTANT: decode = zend_strndup(ZEND_STRL("<constant>")); break; case IS_CONSTANT_AST: decode = zend_strndup(ZEND_STRL("<ast>")); break; default: asprintf(&decode, "unknown type: %d", Z_TYPE_P(literal)); break; } } break; case IS_UNUSED: asprintf(&decode, "<unused>"); break; } return decode; } /* }}} */
static void binary_deserialize(int8_t thrift_typeID, PHPInputTransport& transport, zval* return_value, HashTable* fieldspec) { ZVAL_NULL(return_value); switch (thrift_typeID) { case T_STOP: case T_VOID: RETURN_NULL(); return; case T_STRUCT: { zval* val_ptr = zend_hash_str_find(fieldspec, "class", sizeof("class")-1); if (val_ptr == nullptr) { throw_tprotocolexception("no class type in spec", INVALID_DATA); skip_element(T_STRUCT, transport); RETURN_NULL(); } char* structType = Z_STRVAL_P(val_ptr); // Create an object in PHP userland based on our spec createObject(structType, return_value); if (Z_TYPE_P(return_value) == IS_NULL) { // unable to create class entry skip_element(T_STRUCT, transport); RETURN_NULL(); } zval* spec = zend_read_static_property(Z_OBJCE_P(return_value), "_TSPEC", sizeof("_TSPEC")-1, false); if (Z_TYPE_P(spec) != IS_ARRAY) { char errbuf[128]; snprintf(errbuf, 128, "spec for %s is wrong type: %d\n", structType, Z_TYPE_P(spec)); throw_tprotocolexception(errbuf, INVALID_DATA); RETURN_NULL(); } binary_deserialize_spec(return_value, transport, Z_ARRVAL_P(spec)); return; } break; case T_BOOL: { uint8_t c; transport.readBytes(&c, 1); RETURN_BOOL(c != 0); } //case T_I08: // same numeric value as T_BYTE case T_BYTE: { uint8_t c; transport.readBytes(&c, 1); RETURN_LONG((int8_t)c); } case T_I16: { uint16_t c; transport.readBytes(&c, 2); RETURN_LONG((int16_t)ntohs(c)); } case T_I32: { uint32_t c; transport.readBytes(&c, 4); RETURN_LONG((int32_t)ntohl(c)); } case T_U64: case T_I64: { uint64_t c; transport.readBytes(&c, 8); RETURN_LONG((int64_t)ntohll(c)); } case T_DOUBLE: { union { uint64_t c; double d; } a; transport.readBytes(&(a.c), 8); a.c = ntohll(a.c); RETURN_DOUBLE(a.d); } //case T_UTF7: // aliases T_STRING case T_UTF8: case T_UTF16: case T_STRING: { uint32_t size = transport.readU32(); if (size) { char strbuf[size+1]; transport.readBytes(strbuf, size); strbuf[size] = '\0'; ZVAL_STRINGL(return_value, strbuf, size); } else { ZVAL_EMPTY_STRING(return_value); } return; } case T_MAP: { // array of key -> value uint8_t types[2]; transport.readBytes(types, 2); uint32_t size = transport.readU32(); array_init(return_value); zval *val_ptr; val_ptr = zend_hash_str_find(fieldspec, "key", sizeof("key")-1); HashTable* keyspec = Z_ARRVAL_P(val_ptr); val_ptr = zend_hash_str_find(fieldspec, "val", sizeof("val")-1); HashTable* valspec = Z_ARRVAL_P(val_ptr); for (uint32_t s = 0; s < size; ++s) { zval key, value; binary_deserialize(types[0], transport, &key, keyspec); binary_deserialize(types[1], transport, &value, valspec); if (Z_TYPE(key) == IS_LONG) { zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value); } else { if (Z_TYPE(key) != IS_STRING) convert_to_string(&key); zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value); } zval_dtor(&key); } return; // return_value already populated } case T_LIST: { // array with autogenerated numeric keys int8_t type = transport.readI8(); uint32_t size = transport.readU32(); zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1); HashTable* elemspec = Z_ARRVAL_P(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval value; binary_deserialize(type, transport, &value, elemspec); zend_hash_next_index_insert(Z_ARR_P(return_value), &value); } return; } case T_SET: { // array of key -> TRUE uint8_t type; uint32_t size; transport.readBytes(&type, 1); transport.readBytes(&size, 4); size = ntohl(size); zval *val_ptr = zend_hash_str_find(fieldspec, "elem", sizeof("elem")-1); HashTable* elemspec = Z_ARRVAL_P(val_ptr); array_init(return_value); for (uint32_t s = 0; s < size; ++s) { zval key, value; ZVAL_TRUE(&value); binary_deserialize(type, transport, &key, elemspec); if (Z_TYPE(key) == IS_LONG) { zend_hash_index_update(Z_ARR_P(return_value), Z_LVAL(key), &value); } else { if (Z_TYPE(key) != IS_STRING) convert_to_string(&key); zend_symtable_update(Z_ARR_P(return_value), Z_STR(key), &value); } zval_dtor(&key); } return; } }; char errbuf[128]; sprintf(errbuf, "Unknown thrift typeID %d", thrift_typeID); throw_tprotocolexception(errbuf, INVALID_DATA); }
void skyray_http_protocol_send_headers(skyray_http_protocol_t *self, skyray_http_message_t *message) { zval *zconnection = NULL; zconnection = skyray_http_message_get_header(message, intern_str_connection, 1); zend_array *ht = &message->headers; zend_array *headers; zend_string *name; zend_string *value; skyray_buffer_t header_s; skyray_buffer_init(&header_s, 2048); if (!skyray_http_message_has_header(message, intern_str_server)) { skyray_buffer_appendl(&header_s, ZEND_STRL("Server: Skyray Http Server\r\n")); } if (!skyray_http_message_has_header(message, intern_str_date)) { time_t tm; time(&tm); char *buf = ctime(&tm); skyray_buffer_appendl(&header_s, ZEND_STRL("Date: ")); skyray_buffer_appendl(&header_s, buf, strlen(buf) - 1); skyray_buffer_appendl(&header_s, ZEND_STRL("\r\n")); } zend_hash_internal_pointer_reset(ht); while(zend_hash_has_more_elements(ht) == SUCCESS) { zend_hash_get_current_key(ht, &name, NULL); headers = Z_ARR_P(zend_hash_get_current_data(ht)); zend_hash_internal_pointer_reset(headers); while(zend_hash_has_more_elements(headers) == SUCCESS) { value = Z_STR_P(zend_hash_get_current_data(headers)); skyray_buffer_appendl(&header_s, name->val, name->len); skyray_buffer_appendl(&header_s, ZEND_STRL(": ")); skyray_buffer_appendl(&header_s, value->val, value->len); skyray_buffer_appendl(&header_s, ZEND_STRL("\r\n")); zend_hash_move_forward(headers); } zend_hash_move_forward(ht); } self->close = 0; if (!zconnection) { if (http_should_keep_alive(&self->parser)) { skyray_buffer_appendl(&header_s, ZEND_STRL("Connection: keep-alive\r\n")); } else { skyray_buffer_appendl(&header_s, ZEND_STRL("Connection: close\r\n")); self->close = 1; } } else if (strcasecmp(Z_STR_P(zconnection)->val, "close") == 0) { self->close = 1; } self->chunked = 0; if (!skyray_http_message_has_header(message, intern_str_content_length)) { skyray_buffer_appendl(&header_s, ZEND_STRL("Transfer-Encoding: chunked\r\n")); self->chunked = 1; } skyray_buffer_appendl(&header_s, ZEND_STRL("\r\n")); skyray_stream_write(skyray_stream_from_obj(self->stream), header_s.buf); skyray_buffer_release(&header_s); }