+ if (stream_ctx->started || stream_ctx->finished) {
+ return FAILURE;
+ }
+
+ stream_ctx->status_code = http_code;
+
+ return SUCCESS;
+}
+static STATUS php_http_env_response_stream_set_protocol_version(php_http_env_response_t *r, php_http_version_t *v)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+
+ if (stream_ctx->started || stream_ctx->finished) {
+ return FAILURE;
+ }
+
+ memcpy(&stream_ctx->version, v, sizeof(stream_ctx->version));
+
+ return SUCCESS;
+}
+static STATUS php_http_env_response_stream_set_header_ex(php_http_env_response_t *r, zend_bool replace, const char *fmt, va_list argv)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+ char *header_end, *header_str = NULL;
+ size_t header_len = 0;
+ zval *zheader, **zheader_ptr;
+
+ if (stream_ctx->started || stream_ctx->finished) {
+ return FAILURE;
+ }
+
+ header_len = vspprintf(&header_str, 0, fmt, argv);
+
+ if (!(header_end = strchr(header_str, ':'))) {
+ efree(header_str);
+ return FAILURE;
+ }
+
+ *header_end = '\0';
+
+ if (!replace && (SUCCESS == zend_hash_find(&stream_ctx->header, header_str, header_end - header_str + 1, (void *) &zheader_ptr))) {
+ convert_to_array(*zheader_ptr);
+ *header_end = ':';
+ return add_next_index_stringl(*zheader_ptr, header_str, header_len, 0);
+ } else {
+ MAKE_STD_ZVAL(zheader);
+ ZVAL_STRINGL(zheader, header_str, header_len, 0);
+
+ if (SUCCESS != zend_hash_update(&stream_ctx->header, header_str, header_end - header_str + 1, (void *) &zheader, sizeof(zval *), NULL)) {
+ zval_ptr_dtor(&zheader);
+ return FAILURE;
+ }
+
+ *header_end = ':';
+ return SUCCESS;
+ }
+}
+static STATUS php_http_env_response_stream_set_header(php_http_env_response_t *r, const char *fmt, ...)
+{
+ STATUS ret;
+ va_list argv;
+
+ va_start(argv, fmt);
+ ret = php_http_env_response_stream_set_header_ex(r, 1, fmt, argv);
+ va_end(argv);
+
+ return ret;
+}
+static STATUS php_http_env_response_stream_add_header(php_http_env_response_t *r, const char *fmt, ...)
+{
+ STATUS ret;
+ va_list argv;
+
+ va_start(argv, fmt);
+ ret = php_http_env_response_stream_set_header_ex(r, 0, fmt, argv);
+ va_end(argv);
+
+ return ret;
+}
+static STATUS php_http_env_response_stream_del_header(php_http_env_response_t *r, const char *header_str, size_t header_len)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+
+ if (stream_ctx->started || stream_ctx->finished) {
+ return FAILURE;
+ }
+
+ zend_hash_del(&stream_ctx->header, header_str, header_len + 1);
+ return SUCCESS;
+}
+static STATUS php_http_env_response_stream_write(php_http_env_response_t *r, const char *data_str, size_t data_len)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+ TSRMLS_FETCH_FROM_CTX(r->ts);
+
+ if (stream_ctx->finished) {
+ return FAILURE;
+ }
+ if (!stream_ctx->started) {
+ if (SUCCESS != php_http_env_response_stream_start(stream_ctx TSRMLS_CC)) {
+ return FAILURE;
+ }
+ }
+
+ php_stream_write(stream_ctx->stream, data_str, data_len);
+
+ return SUCCESS;
+}
+static STATUS php_http_env_response_stream_flush(php_http_env_response_t *r)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+ TSRMLS_FETCH_FROM_CTX(r->ts);
+
+ if (stream_ctx->finished) {
+ return FAILURE;
+ }
+ if (!stream_ctx->started) {
+ if (SUCCESS != php_http_env_response_stream_start(stream_ctx TSRMLS_CC)) {
+ return FAILURE;
+ }
+ }
+
+ return php_stream_flush(stream_ctx->stream);
+}
+static STATUS php_http_env_response_stream_finish(php_http_env_response_t *r)
+{
+ php_http_env_response_stream_ctx_t *stream_ctx = r->ctx;
+ TSRMLS_FETCH_FROM_CTX(r->ts);
+
+ if (stream_ctx->finished) {
+ return FAILURE;
+ }
+ if (!stream_ctx->started) {
+ if (SUCCESS != php_http_env_response_stream_start(stream_ctx TSRMLS_CC)) {
+ return FAILURE;
+ }
+ }
+
+ stream_ctx->finished = 1;
+
+ return SUCCESS;
+}
+
+static php_http_env_response_ops_t php_http_env_response_stream_ops = {
+ php_http_env_response_stream_init,
+ php_http_env_response_stream_dtor,
+ php_http_env_response_stream_get_status,
+ php_http_env_response_stream_set_status,
+ php_http_env_response_stream_set_protocol_version,
+ php_http_env_response_stream_set_header,
+ php_http_env_response_stream_add_header,
+ php_http_env_response_stream_del_header,
+ php_http_env_response_stream_write,
+ php_http_env_response_stream_flush,
+ php_http_env_response_stream_finish
+};
+
+php_http_env_response_ops_t *php_http_env_response_get_stream_ops(void)
+{
+ return &php_http_env_response_stream_ops;
+}
+
+#define PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj) \
+ do { \
+ if (!obj->message) { \
+ obj->message = php_http_message_init_env(NULL, PHP_HTTP_RESPONSE TSRMLS_CC); \
+ } \
+ } while (0)
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___construct, 0, 0, 0)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpEnvResponse, __construct)
+{
+ php_http_message_object_t *obj;
+
+ php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return);
+
+ obj = zend_object_store_get_object(getThis() TSRMLS_CC);
+
+ php_http_expect(obj->message = php_http_message_init_env(obj->message, PHP_HTTP_RESPONSE TSRMLS_CC), unexpected_val, return);
+}
+
+ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___invoke, 0, 0, 1)
+ ZEND_ARG_INFO(0, ob_string)
+ ZEND_ARG_INFO(0, ob_flags)
+ZEND_END_ARG_INFO();
+static PHP_METHOD(HttpEnvResponse, __invoke)