2 +--------------------------------------------------------------------+
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted provided that the conditions mentioned |
7 | in the accompanying LICENSE file are met. |
8 +--------------------------------------------------------------------+
9 | Copyright (c) 2004-2011, Michael Wallner <mike@php.net> |
10 +--------------------------------------------------------------------+
13 #include "php_http_api.h"
15 static void set_option(zval
*options
, const char *name_str
, size_t name_len
, int type
, void *value_ptr
, size_t value_len TSRMLS_DC
)
17 if (Z_TYPE_P(options
) == IS_OBJECT
) {
18 /* stupid non-const api */
19 char *name
= estrndup(name_str
, name_len
);
23 zend_update_property_double(Z_OBJCE_P(options
), options
, name
, name_len
, *(double *)value_ptr TSRMLS_CC
);
26 zend_update_property_long(Z_OBJCE_P(options
), options
, name
, name_len
, *(long *)value_ptr TSRMLS_CC
);
29 zend_update_property_stringl(Z_OBJCE_P(options
), options
, name
, name_len
, value_ptr
, value_len TSRMLS_CC
);
32 zend_update_property(Z_OBJCE_P(options
), options
, name
, name_len
, value_ptr TSRMLS_CC
);
36 zend_update_property_null(Z_OBJCE_P(options
), options
, name
, name_len TSRMLS_CC
);
40 convert_to_array(options
);
44 add_assoc_double_ex(options
, name_str
, name_len
+ 1, *(double *)value_ptr
);
47 add_assoc_long_ex(options
, name_str
, name_len
+ 1, *(long *)value_ptr
);
50 char *value
= estrndup(value_ptr
, value_len
);
51 add_assoc_stringl_ex(options
, name_str
, name_len
+ 1, value
, value_len
, 0);
54 Z_ADDREF_P(value_ptr
);
55 add_assoc_zval_ex(options
, name_str
, name_len
+ 1, value_ptr
);
60 add_assoc_null_ex(options
, name_str
, name_len
+ 1);
64 static zval
*get_option(zval
*options
, const char *name_str
, size_t name_len TSRMLS_DC
)
68 if (Z_TYPE_P(options
) == IS_OBJECT
) {
69 char *name
= estrndup(name_str
, name_len
);
70 val
= zend_read_property(Z_OBJCE_P(options
), options
, name
, name_len
, 0 TSRMLS_CC
);
73 if (SUCCESS
== zend_symtable_find(Z_ARRVAL_P(options
), name_str
, name_len
+ 1, (void *) &valptr
)) {
84 static php_http_message_body_t
*get_body(zval
*options TSRMLS_DC
)
87 php_http_message_body_t
*body
= NULL
;
89 if ((zbody
= get_option(options
, ZEND_STRL("body") TSRMLS_CC
))) {
90 if ((Z_TYPE_P(zbody
) == IS_OBJECT
) && instanceof_function(Z_OBJCE_P(zbody
), php_http_message_body_get_class_entry() TSRMLS_CC
)) {
91 php_http_message_body_object_t
*body_obj
= zend_object_store_get_object(zbody TSRMLS_CC
);
93 body
= body_obj
->body
;
95 zval_ptr_dtor(&zbody
);
100 static php_http_message_t
*get_request(zval
*options TSRMLS_DC
)
103 php_http_message_t
*request
= NULL
;
105 if ((zrequest
= get_option(options
, ZEND_STRL("request") TSRMLS_CC
))) {
106 if (Z_TYPE_P(zrequest
) == IS_OBJECT
&& instanceof_function(Z_OBJCE_P(zrequest
), php_http_message_get_class_entry() TSRMLS_CC
)) {
107 php_http_message_object_t
*request_obj
= zend_object_store_get_object(zrequest TSRMLS_CC
);
109 request
= request_obj
->message
;
111 zval_ptr_dtor(&zrequest
);
117 PHP_HTTP_API php_http_cache_status_t
php_http_env_is_response_cached_by_etag(zval
*options
, const char *header_str
, size_t header_len
, php_http_message_t
*request TSRMLS_DC
)
119 php_http_cache_status_t ret
= PHP_HTTP_CACHE_NO
;
121 char *header
= NULL
, *etag
;
122 php_http_message_body_t
*body
;
126 if (!(body
= get_body(options TSRMLS_CC
))) {
130 if ((zetag
= get_option(options
, ZEND_STRL("etag") TSRMLS_CC
))) {
131 zval
*zetag_copy
= php_http_ztyp(IS_STRING
, zetag
);
132 zval_ptr_dtor(&zetag
);
136 if (zetag
&& Z_STRLEN_P(zetag
)) {
137 etag
= Z_STRVAL_P(zetag
);
138 } else if ((etag
= php_http_message_body_etag(body
))) {
139 set_option(options
, ZEND_STRL("etag"), IS_STRING
, etag
, strlen(etag
) TSRMLS_CC
);
144 zval_ptr_dtor(&zetag
);
147 if (etag
&& (header
= php_http_env_get_request_header(header_str
, header_len
, NULL
, request TSRMLS_CC
))) {
148 ret
= php_http_match(header
, etag
, PHP_HTTP_MATCH_WORD
) ? PHP_HTTP_CACHE_HIT
: PHP_HTTP_CACHE_MISS
;
159 PHP_HTTP_API php_http_cache_status_t
php_http_env_is_response_cached_by_last_modified(zval
*options
, const char *header_str
, size_t header_len
, php_http_message_t
*request TSRMLS_DC
)
161 php_http_cache_status_t ret
= PHP_HTTP_CACHE_NO
;
164 php_http_message_body_t
*body
;
167 if (!(body
= get_body(options TSRMLS_CC
))) {
171 if ((zlm
= get_option(options
, ZEND_STRL("lastModified") TSRMLS_CC
))) {
172 zval
*zlm_copy
= php_http_ztyp(IS_LONG
, zlm
);
177 if (zlm
&& Z_LVAL_P(zlm
) > 0) {
180 lm
= php_http_message_body_mtime(body
);
181 set_option(options
, ZEND_STRL("lastModified"), IS_LONG
, &lm
, 0 TSRMLS_CC
);
188 if ((header
= php_http_env_get_request_header(header_str
, header_len
, NULL
, request TSRMLS_CC
))) {
189 ums
= php_parse_date(header
, NULL
);
191 if (ums
> 0 && ums
>= lm
) {
192 ret
= PHP_HTTP_CACHE_HIT
;
194 ret
= PHP_HTTP_CACHE_MISS
;
202 static zend_bool
php_http_env_response_is_cacheable(php_http_env_response_t
*r
, php_http_message_t
*request
)
204 TSRMLS_FETCH_FROM_CTX(r
->ts
);
206 if (r
->ops
->get_status(r
) >= 400) {
210 if (php_http_env_got_request_header(ZEND_STRL("Authorizsation"), request TSRMLS_CC
)) {
214 if (-1 == php_http_select_str(php_http_env_get_request_method(request TSRMLS_CC
), 2, "HEAD", "GET")) {
221 static size_t output(void *context
, char *buf
, size_t len TSRMLS_DC
)
223 php_http_env_response_t
*r
= context
;
225 r
->ops
->write(r
, buf
, len
);
227 /* we really only need to flush when throttling is enabled,
228 because we push the data as fast as possible anyway if not */
229 if (r
->throttle
.delay
>= PHP_HTTP_DIFFSEC
) {
231 php_http_sleep(r
->throttle
.delay
);
236 #define php_http_env_response_send_done(r) php_http_env_response_send_data((r), NULL, 0)
237 static STATUS
php_http_env_response_send_data(php_http_env_response_t
*r
, const char *buf
, size_t len
)
239 size_t chunk
= r
->throttle
.chunk
? r
->throttle
.chunk
: PHP_HTTP_SENDBUF_SIZE
;
240 TSRMLS_FETCH_FROM_CTX(r
->ts
);
242 if (r
->content
.encoder
) {
243 char *enc_str
= NULL
;
247 if (SUCCESS
!= php_http_encoding_stream_update(r
->content
.encoder
, buf
, len
, &enc_str
, &enc_len
)) {
251 if (SUCCESS
!= php_http_encoding_stream_finish(r
->content
.encoder
, &enc_str
, &enc_len
)) {
257 php_http_buffer_chunked_output(&r
->buffer
, enc_str
, enc_len
, buf
? chunk
: 0, output
, r TSRMLS_CC
);
261 php_http_buffer_chunked_output(&r
->buffer
, buf
, len
, buf
? chunk
: 0, output
, r TSRMLS_CC
);
267 PHP_HTTP_API php_http_env_response_t
*php_http_env_response_init(php_http_env_response_t
*r
, zval
*options
, php_http_env_response_ops_t
*ops
, void *init_arg TSRMLS_DC
)
272 r
= emalloc(sizeof(*r
));
274 memset(r
, 0, sizeof(*r
));
279 r
->ops
= php_http_env_response_get_sapi_ops();
282 r
->buffer
= php_http_buffer_init(NULL
);
285 r
->options
= options
;
287 TSRMLS_SET_CTX(r
->ts
);
289 if (r
->ops
->init
&& (SUCCESS
!= r
->ops
->init(r
, init_arg
))) {
291 php_http_env_response_free(&r
);
293 php_http_env_response_dtor(r
);
301 PHP_HTTP_API
void php_http_env_response_dtor(php_http_env_response_t
*r
)
306 php_http_buffer_free(&r
->buffer
);
307 zval_ptr_dtor(&r
->options
);
308 STR_FREE(r
->content
.type
);
309 STR_FREE(r
->content
.encoding
);
310 if (r
->content
.encoder
) {
311 php_http_encoding_stream_free(&r
->content
.encoder
);
315 PHP_HTTP_API
void php_http_env_response_free(php_http_env_response_t
**r
)
318 php_http_env_response_dtor(*r
);
324 static STATUS
php_http_env_response_send_head(php_http_env_response_t
*r
, php_http_message_t
*request
)
326 STATUS ret
= SUCCESS
;
327 zval
*zoption
, *options
= r
->options
;
328 TSRMLS_FETCH_FROM_CTX(r
->ts
);
334 if ((zoption
= get_option(options
, ZEND_STRL("responseCode") TSRMLS_CC
))) {
335 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
337 zval_ptr_dtor(&zoption
);
338 if (Z_LVAL_P(zoption_copy
) > 0) {
339 ret
= r
->ops
->set_status(r
, Z_LVAL_P(zoption_copy
));
341 zval_ptr_dtor(&zoption_copy
);
344 if (ret
!= SUCCESS
) {
348 if ((zoption
= get_option(options
, ZEND_STRL("httpVersion") TSRMLS_CC
))) {
349 php_http_version_t v
;
350 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
352 zval_ptr_dtor(&zoption
);
353 if (Z_STRLEN_P(zoption_copy
) && php_http_version_parse(&v
, Z_STRVAL_P(zoption_copy
) TSRMLS_CC
)) {
354 ret
= r
->ops
->set_protocol_version(r
, &v
);
355 php_http_version_dtor(&v
);
357 zval_ptr_dtor(&zoption_copy
);
360 if (ret
!= SUCCESS
) {
364 if ((zoption
= get_option(options
, ZEND_STRL("headers") TSRMLS_CC
))) {
365 if (Z_TYPE_P(zoption
) == IS_ARRAY
) {
366 php_http_headers_to_callback(Z_ARRVAL_P(zoption
), 0, (php_http_pass_format_callback_t
) r
->ops
->set_header
, r TSRMLS_CC
);
368 zval_ptr_dtor(&zoption
);
371 if (ret
!= SUCCESS
) {
375 if ((zoption
= get_option(options
, ZEND_STRL("contentType") TSRMLS_CC
))) {
376 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
378 zval_ptr_dtor(&zoption
);
379 if (Z_STRLEN_P(zoption_copy
)) {
380 PHP_HTTP_CHECK_CONTENT_TYPE(Z_STRVAL_P(zoption_copy
), ret
= FAILURE
) else {
381 if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Type: %.*s", Z_STRLEN_P(zoption_copy
), Z_STRVAL_P(zoption_copy
)))) {
382 r
->content
.type
= estrndup(Z_STRVAL_P(zoption_copy
), Z_STRLEN_P(zoption_copy
));
386 zval_ptr_dtor(&zoption_copy
);
389 if (ret
!= SUCCESS
) {
393 if (r
->range
.status
== PHP_HTTP_RANGE_OK
) {
394 if (zend_hash_num_elements(&r
->range
.values
) == 1) {
395 zval
**range
, **begin
, **end
;
397 if ( 1 == php_http_array_list(&r
->range
.values TSRMLS_CC
, 1, &range
)
398 && 2 == php_http_array_list(Z_ARRVAL_PP(range
) TSRMLS_CC
, 2, &begin
, &end
)
400 if (SUCCESS
== (ret
= r
->ops
->set_status(r
, 206))) {
401 ret
= r
->ops
->set_header(r
, "Content-Range: bytes %ld-%ld/%zu", Z_LVAL_PP(begin
), Z_LVAL_PP(end
), r
->content
.length
);
404 /* this should never happen */
405 zend_hash_destroy(&r
->range
.values
);
409 php_http_boundary(r
->range
.boundary
, sizeof(r
->range
.boundary
) TSRMLS_CC
);
410 if (SUCCESS
== (ret
= r
->ops
->set_status(r
, 206))) {
411 ret
= r
->ops
->set_header(r
, "Content-Type: multipart/byteranges; boundary=%s", r
->range
.boundary
);
415 if ((zoption
= get_option(options
, ZEND_STRL("cacheControl") TSRMLS_CC
))) {
416 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
418 zval_ptr_dtor(&zoption
);
419 if (Z_STRLEN_P(zoption_copy
)) {
420 ret
= r
->ops
->set_header(r
, "Cache-Control: %.*s", Z_STRLEN_P(zoption_copy
), Z_STRVAL_P(zoption_copy
));
422 zval_ptr_dtor(&zoption_copy
);
425 if (ret
!= SUCCESS
) {
429 if ((zoption
= get_option(options
, ZEND_STRL("contentDisposition") TSRMLS_CC
))) {
430 zval
*zoption_copy
= php_http_ztyp(IS_ARRAY
, zoption
);
431 php_http_buffer_t buf
;
433 php_http_buffer_init(&buf
);
434 if (php_http_params_to_string(&buf
, Z_ARRVAL_P(zoption_copy
), ZEND_STRL(","), ZEND_STRL(";"), ZEND_STRL("="), PHP_HTTP_PARAMS_DEFAULT TSRMLS_CC
)) {
436 ret
= r
->ops
->set_header(r
, "Content-Disposition: %.*s", buf
.used
, buf
.data
);
440 php_http_buffer_dtor(&buf
);
441 zval_ptr_dtor(&zoption_copy
);
442 zval_ptr_dtor(&zoption
);
445 if (ret
!= SUCCESS
) {
449 if ((zoption
= get_option(options
, ZEND_STRL("contentEncoding") TSRMLS_CC
))) {
450 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
452 HashTable
*result
= NULL
;
454 zval_ptr_dtor(&zoption
);
455 switch (Z_LVAL_P(zoption_copy
)) {
456 case PHP_HTTP_CONTENT_ENCODING_GZIP
:
457 INIT_PZVAL(&zsupported
);
458 array_init(&zsupported
);
459 add_next_index_stringl(&zsupported
, ZEND_STRL("none"), 1);
460 add_next_index_stringl(&zsupported
, ZEND_STRL("gzip"), 1);
461 add_next_index_stringl(&zsupported
, ZEND_STRL("deflate"), 1);
463 if ((result
= php_http_negotiate_encoding(Z_ARRVAL(zsupported
), request TSRMLS_CC
))) {
464 char *key_str
= NULL
;
467 zend_hash_internal_pointer_reset(result
);
468 if (HASH_KEY_IS_STRING
== zend_hash_get_current_key_ex(result
, &key_str
, &key_len
, NULL
, 0, NULL
)) {
469 if (!strcmp(key_str
, "gzip")) {
470 if (!(r
->content
.encoder
= php_http_encoding_stream_init(NULL
, php_http_encoding_stream_get_deflate_ops(), PHP_HTTP_DEFLATE_TYPE_GZIP TSRMLS_CC
))) {
472 } else if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Encoding: gzip"))) {
473 r
->content
.encoding
= estrndup(key_str
, key_len
- 1);
475 } else if (!strcmp(key_str
, "deflate")) {
476 if (!(r
->content
.encoder
= php_http_encoding_stream_init(NULL
, php_http_encoding_stream_get_deflate_ops(), PHP_HTTP_DEFLATE_TYPE_ZLIB TSRMLS_CC
))) {
478 } else if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Encoding: deflate"))) {
479 r
->content
.encoding
= estrndup(key_str
, key_len
- 1);
482 ret
= r
->ops
->del_header(r
, ZEND_STRL("Content-Encoding"));
485 if (SUCCESS
== ret
) {
486 ret
= r
->ops
->add_header(r
, "Vary: Accept-Encoding");
490 zend_hash_destroy(result
);
491 FREE_HASHTABLE(result
);
494 zval_dtor(&zsupported
);
497 case PHP_HTTP_CONTENT_ENCODING_NONE
:
499 ret
= r
->ops
->del_header(r
, ZEND_STRL("Content-Encoding"));
502 zval_ptr_dtor(&zoption_copy
);
505 if (SUCCESS
!= ret
) {
509 if (php_http_env_response_is_cacheable(r
, request
)) {
510 switch (php_http_env_is_response_cached_by_etag(options
, ZEND_STRL("If-None-Match"), request TSRMLS_CC
)) {
511 case PHP_HTTP_CACHE_MISS
:
514 case PHP_HTTP_CACHE_NO
:
515 if (PHP_HTTP_CACHE_HIT
!= php_http_env_is_response_cached_by_last_modified(options
, ZEND_STRL("If-Modified-Since"), request TSRMLS_CC
)) {
520 case PHP_HTTP_CACHE_HIT
:
521 ret
= r
->ops
->set_status(r
, 304);
526 if ((zoption
= get_option(options
, ZEND_STRL("etag") TSRMLS_CC
))) {
527 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
529 zval_ptr_dtor(&zoption
);
530 if (*Z_STRVAL_P(zoption_copy
) != '"' && strncmp(Z_STRVAL_P(zoption_copy
), "W/\"", 3)) {
531 ret
= r
->ops
->set_header(r
, "ETag: \"%s\"", Z_STRVAL_P(zoption_copy
));
533 ret
= r
->ops
->set_header(r
, "ETag: %s", Z_STRVAL_P(zoption_copy
));
535 zval_ptr_dtor(&zoption_copy
);
537 if ((zoption
= get_option(options
, ZEND_STRL("lastModified") TSRMLS_CC
))) {
538 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
540 zval_ptr_dtor(&zoption
);
541 if (Z_LVAL_P(zoption_copy
)) {
542 char *date
= php_format_date(ZEND_STRL(PHP_HTTP_DATE_FORMAT
), Z_LVAL_P(zoption_copy
), 0 TSRMLS_CC
);
544 ret
= r
->ops
->set_header(r
, "Last-Modified: %s", date
);
548 zval_ptr_dtor(&zoption_copy
);
556 static STATUS
php_http_env_response_send_body(php_http_env_response_t
*r
)
558 STATUS ret
= SUCCESS
;
560 php_http_message_body_t
*body
;
561 TSRMLS_FETCH_FROM_CTX(r
->ts
);
567 if ((body
= get_body(r
->options TSRMLS_CC
))) {
568 if ((zoption
= get_option(r
->options
, ZEND_STRL("throttleDelay") TSRMLS_CC
))) {
569 if (Z_TYPE_P(zoption
) == IS_DOUBLE
) {
570 r
->throttle
.delay
= Z_DVAL_P(zoption
);
572 zval_ptr_dtor(&zoption
);
574 if ((zoption
= get_option(r
->options
, ZEND_STRL("throttleChunk") TSRMLS_CC
))) {
575 if (Z_TYPE_P(zoption
) == IS_LONG
) {
576 r
->throttle
.chunk
= Z_LVAL_P(zoption
);
578 zval_ptr_dtor(&zoption
);
581 if (r
->range
.status
== PHP_HTTP_RANGE_OK
) {
582 if (zend_hash_num_elements(&r
->range
.values
) == 1) {
584 zval
**range
, **begin
, **end
;
586 if ( 1 == php_http_array_list(&r
->range
.values TSRMLS_CC
, 1, &range
)
587 && 2 == php_http_array_list(Z_ARRVAL_PP(range
) TSRMLS_CC
, 2, &begin
, &end
)
590 php_http_message_body_to_callback(body
, (php_http_pass_callback_t
) php_http_env_response_send_data
, r
, Z_LVAL_PP(begin
), Z_LVAL_PP(end
) - Z_LVAL_PP(begin
) + 1);
591 php_http_env_response_send_done(r
);
592 zend_hash_destroy(&r
->range
.values
);
595 /* this should never happen */
596 zend_hash_destroy(&r
->range
.values
);
597 r
->ops
->set_status(r
, 500);
602 /* send multipart/byte-ranges message */
606 FOREACH_HASH_VAL(pos
, &r
->range
.values
, chunk
) {
609 if (2 == php_http_array_list(Z_ARRVAL_PP(chunk
) TSRMLS_CC
, 2, &begin
, &end
)) {
610 php_http_buffer_appendf(r
->buffer
,
613 "Content-Type: %s" PHP_HTTP_CRLF
614 "Content-Range: bytes %ld-%ld/%zu" PHP_HTTP_CRLF PHP_HTTP_CRLF
,
617 r
->content
.type
? r
->content
.type
: "application/octet-stream",
622 php_http_message_body_to_callback(body
, (php_http_pass_callback_t
) php_http_env_response_send_data
, r
, Z_LVAL_PP(begin
), Z_LVAL_PP(end
) - Z_LVAL_PP(begin
) + 1);
625 php_http_buffer_appendf(r
->buffer
, PHP_HTTP_CRLF
"--%s--", r
->range
.boundary
);
626 php_http_env_response_send_done(r
);
627 zend_hash_destroy(&r
->range
.values
);
631 php_http_message_body_to_callback(body
, (php_http_pass_callback_t
) php_http_env_response_send_data
, r
, 0, 0);
632 php_http_env_response_send_done(r
);
638 PHP_HTTP_API STATUS
php_http_env_response_send(php_http_env_response_t
*r
)
640 php_http_message_t
*request
;
641 php_http_message_body_t
*body
;
642 TSRMLS_FETCH_FROM_CTX(r
->ts
);
644 request
= get_request(r
->options TSRMLS_CC
);
646 /* check for ranges */
647 if ((body
= get_body(r
->options TSRMLS_CC
))) {
648 r
->content
.length
= php_http_message_body_size(body
);
650 if (SUCCESS
!= r
->ops
->set_header(r
, "Accept-Ranges: bytes")) {
653 zend_hash_init(&r
->range
.values
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
654 r
->range
.status
= php_http_env_get_request_ranges(&r
->range
.values
, r
->content
.length
, request TSRMLS_CC
);
656 switch (r
->range
.status
) {
657 case PHP_HTTP_RANGE_NO
:
658 zend_hash_destroy(&r
->range
.values
);
661 case PHP_HTTP_RANGE_ERR
:
662 if (php_http_env_got_request_header(ZEND_STRL("If-Range"), request TSRMLS_CC
)) {
663 r
->range
.status
= PHP_HTTP_RANGE_NO
;
664 zend_hash_destroy(&r
->range
.values
);
667 zend_hash_destroy(&r
->range
.values
);
668 if (SUCCESS
!= r
->ops
->set_status(r
, 416)) {
671 if (SUCCESS
!= r
->ops
->set_header(r
, "Content-Range: bytes */%zu", r
->content
.length
)) {
677 case PHP_HTTP_RANGE_OK
:
678 if (PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_etag(r
->options
, ZEND_STRL("If-Range"), request TSRMLS_CC
)
679 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("If-Range"), request TSRMLS_CC
)
681 r
->range
.status
= PHP_HTTP_RANGE_NO
;
682 zend_hash_destroy(&r
->range
.values
);
685 if (PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_etag(r
->options
, ZEND_STRL("If-Match"), request TSRMLS_CC
)
686 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("If-Unmodified-Since"), request TSRMLS_CC
)
687 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("Unless-Modified-Since"), request TSRMLS_CC
)
690 zend_hash_destroy(&r
->range
.values
);
691 if (SUCCESS
!= r
->ops
->set_status(r
, 412)) {
702 if (SUCCESS
!= php_http_env_response_send_head(r
, request
)) {
706 if (SUCCESS
!= php_http_env_response_send_body(r
)) {
710 if (SUCCESS
!= r
->ops
->finish(r
)) {
717 static long php_http_env_response_sapi_get_status(php_http_env_response_t
*r
)
719 TSRMLS_FETCH_FROM_CTX(r
->ts
);
721 return php_http_env_get_response_code(TSRMLS_C
);
723 static STATUS
php_http_env_response_sapi_set_status(php_http_env_response_t
*r
, long http_code
)
725 TSRMLS_FETCH_FROM_CTX(r
->ts
);
727 return php_http_env_set_response_code(http_code TSRMLS_CC
);
729 static STATUS
php_http_env_response_sapi_set_protocol_version(php_http_env_response_t
*r
, php_http_version_t
*v
)
731 TSRMLS_FETCH_FROM_CTX(r
->ts
);
733 return php_http_env_set_response_protocol_version(v TSRMLS_CC
);
735 static STATUS
php_http_env_response_sapi_set_header(php_http_env_response_t
*r
, const char *fmt
, ...)
739 TSRMLS_FETCH_FROM_CTX(r
->ts
);
742 ret
= php_http_env_set_response_header_va(0, 1, fmt
, args TSRMLS_CC
);
747 static STATUS
php_http_env_response_sapi_add_header(php_http_env_response_t
*r
, const char *fmt
, ...)
751 TSRMLS_FETCH_FROM_CTX(r
->ts
);
754 ret
= php_http_env_set_response_header_va(0, 0, fmt
, args TSRMLS_CC
);
759 static STATUS
php_http_env_response_sapi_del_header(php_http_env_response_t
*r
, const char *header_str
, size_t header_len
)
761 TSRMLS_FETCH_FROM_CTX(r
->ts
);
763 return php_http_env_set_response_header_value(0, header_str
, header_len
, NULL
, 1 TSRMLS_CC
);
765 static STATUS
php_http_env_response_sapi_write(php_http_env_response_t
*r
, const char *data_str
, size_t data_len
)
767 TSRMLS_FETCH_FROM_CTX(r
->ts
);
769 if (0 < PHPWRITE(data_str
, data_len
)) {
774 static STATUS
php_http_env_response_sapi_flush(php_http_env_response_t
*r
)
776 TSRMLS_FETCH_FROM_CTX(r
->ts
);
778 #if PHP_VERSION_ID >= 50400
779 if (php_output_get_level(TSRMLS_C
)) {
780 php_output_flush_all(TSRMLS_C
);
782 if (!(php_output_get_status(TSRMLS_C
) & PHP_OUTPUT_IMPLICITFLUSH
)) {
783 sapi_flush(TSRMLS_C
);
786 php_end_ob_buffer(1, 1 TSRMLS_CC
);
787 sapi_flush(TSRMLS_C
);
792 static STATUS
php_http_env_response_sapi_finish(php_http_env_response_t
*r
)
797 static php_http_env_response_ops_t php_http_env_response_sapi_ops
= {
800 php_http_env_response_sapi_get_status
,
801 php_http_env_response_sapi_set_status
,
802 php_http_env_response_sapi_set_protocol_version
,
803 php_http_env_response_sapi_set_header
,
804 php_http_env_response_sapi_add_header
,
805 php_http_env_response_sapi_del_header
,
806 php_http_env_response_sapi_write
,
807 php_http_env_response_sapi_flush
,
808 php_http_env_response_sapi_finish
811 PHP_HTTP_API php_http_env_response_ops_t
*php_http_env_response_get_sapi_ops(void)
813 return &php_http_env_response_sapi_ops
;
816 typedef struct php_http_env_response_stream_ctx
{
818 php_http_version_t version
;
825 } php_http_env_response_stream_ctx_t
;
827 static STATUS
php_http_env_response_stream_init(php_http_env_response_t
*r
, void *init_arg
)
829 php_http_env_response_stream_ctx_t
*ctx
;
830 TSRMLS_FETCH_FROM_CTX(r
->ts
);
832 ctx
= ecalloc(1, sizeof(*ctx
));
834 ctx
->stream
= init_arg
;
835 if (SUCCESS
!= zend_list_addref(ctx
->stream
->rsrc_id
)) {
839 zend_hash_init(&ctx
->header
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
840 php_http_version_init(&ctx
->version
, 1, 1 TSRMLS_CC
);
841 ctx
->status_code
= 200;
847 static void php_http_env_response_stream_dtor(php_http_env_response_t
*r
)
849 php_http_env_response_stream_ctx_t
*ctx
= r
->ctx
;
850 TSRMLS_FETCH_FROM_CTX(r
->ts
);
852 zend_hash_destroy(&ctx
->header
);
853 zend_list_delete(ctx
->stream
->rsrc_id
);
857 static void php_http_env_response_stream_header(php_http_env_response_stream_ctx_t
*ctx
, HashTable
*header TSRMLS_DC
)
862 FOREACH_HASH_VAL(pos
, &ctx
->header
, val
) {
863 if (Z_TYPE_PP(val
) == IS_ARRAY
) {
864 php_http_env_response_stream_header(ctx
, Z_ARRVAL_PP(val
) TSRMLS_CC
);
866 php_stream_write(ctx
->stream
, Z_STRVAL_PP(val
), Z_STRLEN_PP(val
));
867 php_stream_write_string(ctx
->stream
, PHP_HTTP_CRLF
);
871 static STATUS
php_http_env_response_stream_start(php_http_env_response_stream_ctx_t
*ctx TSRMLS_DC
)
873 if (ctx
->started
|| ctx
->finished
) {
877 php_stream_printf(ctx
->stream TSRMLS_CC
, "HTTP/%u.%u %ld %s" PHP_HTTP_CRLF
, ctx
->version
.major
, ctx
->version
.minor
, ctx
->status_code
, php_http_env_get_response_status_for_code(ctx
->status_code
));
878 php_http_env_response_stream_header(ctx
, &ctx
->header TSRMLS_CC
);
879 php_stream_write_string(ctx
->stream
, PHP_HTTP_CRLF
);
883 static long php_http_env_response_stream_get_status(php_http_env_response_t
*r
)
885 php_http_env_response_stream_ctx_t
*ctx
= r
->ctx
;
887 return ctx
->status_code
;
889 static STATUS
php_http_env_response_stream_set_status(php_http_env_response_t
*r
, long http_code
)
891 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
893 if (stream_ctx
->started
|| stream_ctx
->finished
) {
897 stream_ctx
->status_code
= http_code
;
901 static STATUS
php_http_env_response_stream_set_protocol_version(php_http_env_response_t
*r
, php_http_version_t
*v
)
903 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
905 if (stream_ctx
->started
|| stream_ctx
->finished
) {
909 memcpy(&stream_ctx
->version
, v
, sizeof(stream_ctx
->version
));
913 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
)
915 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
916 char *header_end
, *header_str
= NULL
;
917 size_t header_len
= 0;
918 zval
*zheader
, **zheader_ptr
;
920 if (stream_ctx
->started
|| stream_ctx
->finished
) {
924 header_len
= vspprintf(&header_str
, 0, fmt
, argv
);
926 if (!(header_end
= strchr(header_str
, ':'))) {
933 if (!replace
&& (SUCCESS
== zend_hash_find(&stream_ctx
->header
, header_str
, header_end
- header_str
+ 1, (void *) &zheader_ptr
))) {
934 convert_to_array(*zheader_ptr
);
936 return add_next_index_stringl(*zheader_ptr
, header_str
, header_len
, 0);
938 MAKE_STD_ZVAL(zheader
);
939 ZVAL_STRINGL(zheader
, header_str
, header_len
, 0);
941 if (SUCCESS
!= zend_hash_update(&stream_ctx
->header
, header_str
, header_end
- header_str
+ 1, (void *) &zheader
, sizeof(zval
*), NULL
)) {
942 zval_ptr_dtor(&zheader
);
950 static STATUS
php_http_env_response_stream_set_header(php_http_env_response_t
*r
, const char *fmt
, ...)
956 ret
= php_http_env_response_stream_set_header_ex(r
, 1, fmt
, argv
);
961 static STATUS
php_http_env_response_stream_add_header(php_http_env_response_t
*r
, const char *fmt
, ...)
967 ret
= php_http_env_response_stream_set_header_ex(r
, 0, fmt
, argv
);
972 static STATUS
php_http_env_response_stream_del_header(php_http_env_response_t
*r
, const char *header_str
, size_t header_len
)
974 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
976 if (stream_ctx
->started
|| stream_ctx
->finished
) {
980 zend_hash_del(&stream_ctx
->header
, header_str
, header_len
+ 1);
983 static STATUS
php_http_env_response_stream_write(php_http_env_response_t
*r
, const char *data_str
, size_t data_len
)
985 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
986 TSRMLS_FETCH_FROM_CTX(r
->ts
);
988 if (stream_ctx
->finished
) {
991 if (!stream_ctx
->started
) {
992 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
997 php_stream_write(stream_ctx
->stream
, data_str
, data_len
);
1001 static STATUS
php_http_env_response_stream_flush(php_http_env_response_t
*r
)
1003 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
1004 TSRMLS_FETCH_FROM_CTX(r
->ts
);
1006 if (stream_ctx
->finished
) {
1009 if (!stream_ctx
->started
) {
1010 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
1015 return php_stream_flush(stream_ctx
->stream
);
1017 static STATUS
php_http_env_response_stream_finish(php_http_env_response_t
*r
)
1019 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
1020 TSRMLS_FETCH_FROM_CTX(r
->ts
);
1022 if (stream_ctx
->finished
) {
1025 if (!stream_ctx
->started
) {
1026 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
1031 stream_ctx
->finished
= 1;
1036 static php_http_env_response_ops_t php_http_env_response_stream_ops
= {
1037 php_http_env_response_stream_init
,
1038 php_http_env_response_stream_dtor
,
1039 php_http_env_response_stream_get_status
,
1040 php_http_env_response_stream_set_status
,
1041 php_http_env_response_stream_set_protocol_version
,
1042 php_http_env_response_stream_set_header
,
1043 php_http_env_response_stream_add_header
,
1044 php_http_env_response_stream_del_header
,
1045 php_http_env_response_stream_write
,
1046 php_http_env_response_stream_flush
,
1047 php_http_env_response_stream_finish
1050 PHP_HTTP_API php_http_env_response_ops_t
*php_http_env_response_get_stream_ops(void)
1052 return &php_http_env_response_stream_ops
;
1055 #undef PHP_HTTP_BEGIN_ARGS
1056 #undef PHP_HTTP_EMPTY_ARGS
1057 #define PHP_HTTP_BEGIN_ARGS(method, req_args) PHP_HTTP_BEGIN_ARGS_EX(HttpEnvResponse, method, 0, req_args)
1058 #define PHP_HTTP_EMPTY_ARGS(method) PHP_HTTP_EMPTY_ARGS_EX(HttpEnvResponse, method, 0)
1059 #define PHP_HTTP_ENV_RESPONSE_ME(method, visibility) PHP_ME(HttpEnvResponse, method, PHP_HTTP_ARGS(HttpEnvResponse, method), visibility)
1061 PHP_HTTP_EMPTY_ARGS(__construct
);
1063 PHP_HTTP_BEGIN_ARGS(__invoke
, 1)
1064 PHP_HTTP_ARG_VAL(ob_string
, 0)
1065 PHP_HTTP_ARG_VAL(ob_flags
, 0)
1068 PHP_HTTP_BEGIN_ARGS(setEnvRequest
, 1)
1069 PHP_HTTP_ARG_OBJ(http
\\Message
, env_request
, 1)
1072 PHP_HTTP_BEGIN_ARGS(setContentType
, 1)
1073 PHP_HTTP_ARG_VAL(content_type
, 0)
1076 PHP_HTTP_BEGIN_ARGS(setContentEncoding
, 1)
1077 PHP_HTTP_ARG_VAL(content_encoding
, 0)
1080 PHP_HTTP_BEGIN_ARGS(setContentDisposition
, 1)
1081 PHP_HTTP_ARG_ARR(disposition_params
, 1, 0)
1084 PHP_HTTP_BEGIN_ARGS(setCacheControl
, 1)
1085 PHP_HTTP_ARG_VAL(cache_control
, 0)
1088 PHP_HTTP_BEGIN_ARGS(setLastModified
, 1)
1089 PHP_HTTP_ARG_VAL(last_modified
, 0)
1092 PHP_HTTP_BEGIN_ARGS(isCachedByLastModified
, 0)
1093 PHP_HTTP_ARG_VAL(header_name
, 0)
1096 PHP_HTTP_BEGIN_ARGS(setEtag
, 1)
1097 PHP_HTTP_ARG_VAL(etag
, 0)
1100 PHP_HTTP_BEGIN_ARGS(isCachedByEtag
, 0)
1101 PHP_HTTP_ARG_VAL(header_name
, 0)
1104 PHP_HTTP_BEGIN_ARGS(setThrottleRate
, 1)
1105 PHP_HTTP_ARG_VAL(chunk_size
, 0)
1106 PHP_HTTP_ARG_VAL(delay
, 0)
1109 PHP_HTTP_EMPTY_ARGS(send
);
1111 static zend_class_entry
*php_http_env_response_class_entry
;
1113 zend_class_entry
*php_http_env_response_get_class_entry(void)
1115 return php_http_env_response_class_entry
;
1118 static zend_function_entry php_http_env_response_method_entry
[] = {
1119 PHP_HTTP_ENV_RESPONSE_ME(__construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1120 PHP_HTTP_ENV_RESPONSE_ME(__invoke
, ZEND_ACC_PUBLIC
)
1121 PHP_HTTP_ENV_RESPONSE_ME(setEnvRequest
, ZEND_ACC_PUBLIC
)
1122 PHP_HTTP_ENV_RESPONSE_ME(setContentType
, ZEND_ACC_PUBLIC
)
1123 PHP_HTTP_ENV_RESPONSE_ME(setContentDisposition
, ZEND_ACC_PUBLIC
)
1124 PHP_HTTP_ENV_RESPONSE_ME(setContentEncoding
, ZEND_ACC_PUBLIC
)
1125 PHP_HTTP_ENV_RESPONSE_ME(setCacheControl
, ZEND_ACC_PUBLIC
)
1126 PHP_HTTP_ENV_RESPONSE_ME(setLastModified
, ZEND_ACC_PUBLIC
)
1127 PHP_HTTP_ENV_RESPONSE_ME(isCachedByLastModified
, ZEND_ACC_PUBLIC
)
1128 PHP_HTTP_ENV_RESPONSE_ME(setEtag
, ZEND_ACC_PUBLIC
)
1129 PHP_HTTP_ENV_RESPONSE_ME(isCachedByEtag
, ZEND_ACC_PUBLIC
)
1130 PHP_HTTP_ENV_RESPONSE_ME(setThrottleRate
, ZEND_ACC_PUBLIC
)
1132 PHP_HTTP_ENV_RESPONSE_ME(send
, ZEND_ACC_PUBLIC
)
1134 EMPTY_FUNCTION_ENTRY
1137 #define PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj) \
1139 if (!obj->message) { \
1140 obj->message = php_http_message_init_env(NULL, PHP_HTTP_RESPONSE TSRMLS_CC); \
1144 PHP_METHOD(HttpEnvResponse
, __construct
)
1146 with_error_handling(EH_THROW
, php_http_exception_get_class_entry()) {
1147 php_http_message_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1149 if (SUCCESS
== zend_parse_parameters_none()) {
1150 with_error_handling(EH_THROW
, php_http_exception_get_class_entry()) {
1151 obj
->message
= php_http_message_init_env(obj
->message
, PHP_HTTP_RESPONSE TSRMLS_CC
);
1152 } end_error_handling();
1154 PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj
);
1155 } end_error_handling();
1159 PHP_METHOD(HttpEnvResponse
, __invoke
)
1165 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|l", &ob_str
, &ob_len
, &ob_flags
)) {
1166 php_http_message_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1168 PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj
);
1170 if (obj
->body
.handle
|| SUCCESS
== php_http_new(&obj
->body
, php_http_message_body_get_class_entry(), (php_http_new_t
) php_http_message_body_object_new_ex
, NULL
, (void *) php_http_message_body_init(&obj
->message
->body
, NULL TSRMLS_CC
), NULL TSRMLS_CC
)) {
1171 php_http_message_body_append(obj
->message
->body
, ob_str
, ob_len
);
1178 PHP_METHOD(HttpEnvResponse
, setEnvRequest
)
1180 zval
*env_req
= NULL
;
1182 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|O", &env_req
, php_http_message_get_class_entry())) {
1183 set_option(getThis(), ZEND_STRL("request"), IS_OBJECT
, env_req
, 0 TSRMLS_CC
);
1187 PHP_METHOD(HttpEnvResponse
, setContentType
)
1189 char *ct_str
= NULL
;
1192 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &ct_str
, &ct_len
)) {
1193 set_option(getThis(), ZEND_STRL("contentType"), IS_STRING
, ct_str
, ct_len TSRMLS_CC
);
1197 PHP_METHOD(HttpEnvResponse
, setContentDisposition
)
1201 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a", &zdisposition
)) {
1202 zend_update_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("contentDisposition"), zdisposition TSRMLS_CC
);
1206 PHP_METHOD(HttpEnvResponse
, setContentEncoding
)
1210 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &ce
)) {
1211 set_option(getThis(), ZEND_STRL("contentEncoding"), IS_LONG
, &ce
, 0 TSRMLS_CC
);
1215 PHP_METHOD(HttpEnvResponse
, setCacheControl
)
1217 char *cc_str
= NULL
;
1220 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &cc_str
, &cc_len
)) {
1221 set_option(getThis(), ZEND_STRL("cacheControl"), IS_STRING
, cc_str
, cc_len TSRMLS_CC
);
1225 PHP_METHOD(HttpEnvResponse
, setLastModified
)
1229 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &last_modified
)) {
1230 set_option(getThis(), ZEND_STRL("lastModified"), IS_LONG
, &last_modified
, 0 TSRMLS_CC
);
1234 PHP_METHOD(HttpEnvResponse
, isCachedByLastModified
)
1236 char *header_name_str
= NULL
;
1237 int header_name_len
= 0;
1239 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &header_name_str
, &header_name_len
)) {
1240 if (!header_name_str
|| !header_name_len
) {
1241 header_name_str
= "If-Modified-Since";
1242 header_name_len
= lenof("If-Modified-Since");
1245 RETURN_LONG(php_http_env_is_response_cached_by_last_modified(getThis(), header_name_str
, header_name_len
, get_request(getThis() TSRMLS_CC
) TSRMLS_CC
));
1250 PHP_METHOD(HttpEnvResponse
, setEtag
)
1252 char *etag_str
= NULL
;
1255 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &etag_str
, &etag_len
)) {
1256 set_option(getThis(), ZEND_STRL("etag"), IS_STRING
, etag_str
, etag_len TSRMLS_CC
);
1260 PHP_METHOD(HttpEnvResponse
, isCachedByEtag
)
1262 char *header_name_str
= NULL
;
1263 int header_name_len
= 0;
1265 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &header_name_str
, &header_name_len
)) {
1266 if (!header_name_str
|| !header_name_len
) {
1267 header_name_str
= "If-None-Match";
1268 header_name_len
= lenof("If-None-Match");
1270 RETURN_LONG(php_http_env_is_response_cached_by_etag(getThis(), header_name_str
, header_name_len
, get_request(getThis() TSRMLS_CC
) TSRMLS_CC
));
1275 PHP_METHOD(HttpEnvResponse
, setThrottleRate
)
1280 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|d", &chunk_size
, &delay
)) {
1281 set_option(getThis(), ZEND_STRL("throttleDelay"), IS_DOUBLE
, &delay
, 0 TSRMLS_CC
);
1282 set_option(getThis(), ZEND_STRL("throttleChunk"), IS_LONG
, &chunk_size
, 0 TSRMLS_CC
);
1288 PHP_METHOD(HttpEnvResponse
, send
)
1290 zval
*zstream
= NULL
;
1291 php_stream
*s
= NULL
;
1295 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r", &zstream
)) {
1297 php_stream_from_zval_no_verify(s
, &zstream
);
1300 php_http_env_response_t
*r
;
1302 if ((r
= php_http_env_response_init(NULL
, getThis(), php_http_env_response_get_stream_ops(), s TSRMLS_CC
))) {
1303 RETVAL_SUCCESS(php_http_env_response_send(r
));
1304 php_http_env_response_free(&r
);
1308 php_http_env_response_t r
;
1310 if (php_http_env_response_init(&r
, getThis(), NULL
, NULL TSRMLS_CC
)) {
1311 RETVAL_SUCCESS(php_http_env_response_send(&r
));
1312 php_http_env_response_dtor(&r
);
1318 PHP_MINIT_FUNCTION(http_env_response
)
1320 PHP_HTTP_REGISTER_CLASS(http
\\Env
, Response
, http_env_response
, php_http_message_get_class_entry(), 0);
1322 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CONTENT_ENCODING_NONE"), PHP_HTTP_CONTENT_ENCODING_NONE TSRMLS_CC
);
1323 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CONTENT_ENCODING_GZIP"), PHP_HTTP_CONTENT_ENCODING_GZIP TSRMLS_CC
);
1325 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_NO"), PHP_HTTP_CACHE_NO TSRMLS_CC
);
1326 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_HIT"), PHP_HTTP_CACHE_HIT TSRMLS_CC
);
1327 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_MISS"), PHP_HTTP_CACHE_MISS TSRMLS_CC
);
1329 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("request"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1330 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentType"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1331 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentDisposition"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1332 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentEncoding"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1333 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("cacheControl"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1334 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("etag"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1335 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("lastModified"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1336 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("throttleDelay"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1337 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("throttleChunk"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1348 * vim600: noet sw=4 ts=4 fdm=marker
1349 * vim<600: noet sw=4 ts=4