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-2014, 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
) {
21 zend_update_property_double(Z_OBJCE_P(options
), options
, name_str
, name_len
, *(double *)value_ptr TSRMLS_CC
);
24 zend_update_property_long(Z_OBJCE_P(options
), options
, name_str
, name_len
, *(long *)value_ptr TSRMLS_CC
);
27 zend_update_property_stringl(Z_OBJCE_P(options
), options
, name_str
, name_len
, value_ptr
, value_len TSRMLS_CC
);
30 zend_update_property(Z_OBJCE_P(options
), options
, name_str
, name_len
, value_ptr TSRMLS_CC
);
34 zend_update_property_null(Z_OBJCE_P(options
), options
, name_str
, name_len TSRMLS_CC
);
37 convert_to_array(options
);
41 add_assoc_double_ex(options
, name_str
, name_len
+ 1, *(double *)value_ptr
);
44 add_assoc_long_ex(options
, name_str
, name_len
+ 1, *(long *)value_ptr
);
47 char *value
= estrndup(value_ptr
, value_len
);
48 add_assoc_stringl_ex(options
, name_str
, name_len
+ 1, value
, value_len
, 0);
51 Z_ADDREF_P(value_ptr
);
52 add_assoc_zval_ex(options
, name_str
, name_len
+ 1, value_ptr
);
57 add_assoc_null_ex(options
, name_str
, name_len
+ 1);
61 static zval
*get_option(zval
*options
, const char *name_str
, size_t name_len TSRMLS_DC
)
65 if (Z_TYPE_P(options
) == IS_OBJECT
) {
66 val
= zend_read_property(Z_OBJCE_P(options
), options
, name_str
, name_len
, 0 TSRMLS_CC
);
68 if (SUCCESS
== zend_symtable_find(Z_ARRVAL_P(options
), name_str
, name_len
+ 1, (void *) &valptr
)) {
79 static php_http_message_body_t
*get_body(zval
*options TSRMLS_DC
)
82 php_http_message_body_t
*body
= NULL
;
84 if ((zbody
= get_option(options
, ZEND_STRL("body") TSRMLS_CC
))) {
85 if ((Z_TYPE_P(zbody
) == IS_OBJECT
) && instanceof_function(Z_OBJCE_P(zbody
), php_http_message_body_class_entry TSRMLS_CC
)) {
86 php_http_message_body_object_t
*body_obj
= zend_object_store_get_object(zbody TSRMLS_CC
);
88 body
= body_obj
->body
;
90 zval_ptr_dtor(&zbody
);
95 static php_http_message_t
*get_request(zval
*options TSRMLS_DC
)
98 php_http_message_t
*request
= NULL
;
100 if ((zrequest
= get_option(options
, ZEND_STRL("request") TSRMLS_CC
))) {
101 if (Z_TYPE_P(zrequest
) == IS_OBJECT
&& instanceof_function(Z_OBJCE_P(zrequest
), php_http_message_class_entry TSRMLS_CC
)) {
102 php_http_message_object_t
*request_obj
= zend_object_store_get_object(zrequest TSRMLS_CC
);
104 request
= request_obj
->message
;
106 zval_ptr_dtor(&zrequest
);
112 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
)
114 php_http_cache_status_t ret
= PHP_HTTP_CACHE_NO
;
116 char *header
= NULL
, *etag
;
117 php_http_message_body_t
*body
;
121 if (!(body
= get_body(options TSRMLS_CC
))) {
125 if ((zetag
= get_option(options
, ZEND_STRL("etag") TSRMLS_CC
))) {
126 zval
*zetag_copy
= php_http_ztyp(IS_STRING
, zetag
);
127 zval_ptr_dtor(&zetag
);
131 if (zetag
&& Z_STRLEN_P(zetag
)) {
132 etag
= Z_STRVAL_P(zetag
);
133 } else if ((etag
= php_http_message_body_etag(body
))) {
134 set_option(options
, ZEND_STRL("etag"), IS_STRING
, etag
, strlen(etag
) TSRMLS_CC
);
139 zval_ptr_dtor(&zetag
);
142 if (etag
&& (header
= php_http_env_get_request_header(header_str
, header_len
, NULL
, request TSRMLS_CC
))) {
143 ret
= php_http_match(header
, etag
, PHP_HTTP_MATCH_WORD
) ? PHP_HTTP_CACHE_HIT
: PHP_HTTP_CACHE_MISS
;
154 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
)
156 php_http_cache_status_t ret
= PHP_HTTP_CACHE_NO
;
159 php_http_message_body_t
*body
;
162 if (!(body
= get_body(options TSRMLS_CC
))) {
166 if ((zlm
= get_option(options
, ZEND_STRL("lastModified") TSRMLS_CC
))) {
167 zval
*zlm_copy
= php_http_ztyp(IS_LONG
, zlm
);
172 if (zlm
&& Z_LVAL_P(zlm
) > 0) {
175 lm
= php_http_message_body_mtime(body
);
176 set_option(options
, ZEND_STRL("lastModified"), IS_LONG
, &lm
, 0 TSRMLS_CC
);
183 if ((header
= php_http_env_get_request_header(header_str
, header_len
, NULL
, request TSRMLS_CC
))) {
184 ums
= php_parse_date(header
, NULL
);
186 if (ums
> 0 && ums
>= lm
) {
187 ret
= PHP_HTTP_CACHE_HIT
;
189 ret
= PHP_HTTP_CACHE_MISS
;
197 static zend_bool
php_http_env_response_is_cacheable(php_http_env_response_t
*r
, php_http_message_t
*request
)
199 TSRMLS_FETCH_FROM_CTX(r
->ts
);
201 if (r
->ops
->get_status(r
) >= 400) {
205 if (php_http_env_got_request_header(ZEND_STRL("Authorization"), request TSRMLS_CC
)) {
209 if (-1 == php_http_select_str(php_http_env_get_request_method(request TSRMLS_CC
), 2, "HEAD", "GET")) {
216 static size_t output(void *context
, char *buf
, size_t len TSRMLS_DC
)
218 php_http_env_response_t
*r
= context
;
220 if (SUCCESS
!= r
->ops
->write(r
, buf
, len
)) {
224 /* we really only need to flush when throttling is enabled,
225 because we push the data as fast as possible anyway if not */
226 if (r
->throttle
.delay
>= PHP_HTTP_DIFFSEC
) {
228 php_http_sleep(r
->throttle
.delay
);
233 #define php_http_env_response_send_done(r) php_http_env_response_send_data((r), NULL, 0)
234 static STATUS
php_http_env_response_send_data(php_http_env_response_t
*r
, const char *buf
, size_t len
)
236 size_t chunks_sent
, chunk
= r
->throttle
.chunk
? r
->throttle
.chunk
: PHP_HTTP_SENDBUF_SIZE
;
237 TSRMLS_FETCH_FROM_CTX(r
->ts
);
239 if (r
->content
.encoder
) {
240 char *enc_str
= NULL
;
244 if (SUCCESS
!= php_http_encoding_stream_update(r
->content
.encoder
, buf
, len
, &enc_str
, &enc_len
)) {
248 if (SUCCESS
!= php_http_encoding_stream_finish(r
->content
.encoder
, &enc_str
, &enc_len
)) {
256 chunks_sent
= php_http_buffer_chunked_output(&r
->buffer
, enc_str
, enc_len
, buf
? chunk
: 0, output
, r TSRMLS_CC
);
259 chunks_sent
= php_http_buffer_chunked_output(&r
->buffer
, buf
, len
, buf
? chunk
: 0, output
, r TSRMLS_CC
);
262 return chunks_sent
!= (size_t) -1 ? SUCCESS
: FAILURE
;
265 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
)
270 r
= emalloc(sizeof(*r
));
272 memset(r
, 0, sizeof(*r
));
277 r
->ops
= php_http_env_response_get_sapi_ops();
280 r
->buffer
= php_http_buffer_init(NULL
);
283 r
->options
= options
;
285 TSRMLS_SET_CTX(r
->ts
);
287 if (r
->ops
->init
&& (SUCCESS
!= r
->ops
->init(r
, init_arg
))) {
289 php_http_env_response_free(&r
);
291 php_http_env_response_dtor(r
);
299 void php_http_env_response_dtor(php_http_env_response_t
*r
)
304 php_http_buffer_free(&r
->buffer
);
305 zval_ptr_dtor(&r
->options
);
306 STR_FREE(r
->content
.type
);
307 STR_FREE(r
->content
.encoding
);
308 if (r
->content
.encoder
) {
309 php_http_encoding_stream_free(&r
->content
.encoder
);
313 void php_http_env_response_free(php_http_env_response_t
**r
)
316 php_http_env_response_dtor(*r
);
322 static STATUS
php_http_env_response_send_head(php_http_env_response_t
*r
, php_http_message_t
*request
)
324 STATUS ret
= SUCCESS
;
325 zval
*zoption
, *options
= r
->options
;
326 TSRMLS_FETCH_FROM_CTX(r
->ts
);
332 if ((zoption
= get_option(options
, ZEND_STRL("responseCode") TSRMLS_CC
))) {
333 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
335 zval_ptr_dtor(&zoption
);
336 if (Z_LVAL_P(zoption_copy
) > 0) {
337 ret
= r
->ops
->set_status(r
, Z_LVAL_P(zoption_copy
));
339 zval_ptr_dtor(&zoption_copy
);
342 if (ret
!= SUCCESS
) {
346 if ((zoption
= get_option(options
, ZEND_STRL("httpVersion") TSRMLS_CC
))) {
347 php_http_version_t v
;
348 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
350 zval_ptr_dtor(&zoption
);
351 if (Z_STRLEN_P(zoption_copy
) && php_http_version_parse(&v
, Z_STRVAL_P(zoption_copy
) TSRMLS_CC
)) {
352 ret
= r
->ops
->set_protocol_version(r
, &v
);
353 php_http_version_dtor(&v
);
355 zval_ptr_dtor(&zoption_copy
);
358 if (ret
!= SUCCESS
) {
362 if ((zoption
= get_option(options
, ZEND_STRL("headers") TSRMLS_CC
))) {
363 if (Z_TYPE_P(zoption
) == IS_ARRAY
) {
364 php_http_header_to_callback(Z_ARRVAL_P(zoption
), 0, (php_http_pass_format_callback_t
) r
->ops
->set_header
, r TSRMLS_CC
);
366 zval_ptr_dtor(&zoption
);
369 if (ret
!= SUCCESS
) {
373 if ((zoption
= get_option(options
, ZEND_STRL("contentType") TSRMLS_CC
))) {
374 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
376 zval_ptr_dtor(&zoption
);
377 if (Z_STRLEN_P(zoption_copy
) && strchr(Z_STRVAL_P(zoption_copy
), '/')) {
378 if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Type: %.*s", Z_STRLEN_P(zoption_copy
), Z_STRVAL_P(zoption_copy
)))) {
379 r
->content
.type
= estrndup(Z_STRVAL_P(zoption_copy
), Z_STRLEN_P(zoption_copy
));
382 zval_ptr_dtor(&zoption_copy
);
385 if (ret
!= SUCCESS
) {
389 if (r
->range
.status
== PHP_HTTP_RANGE_OK
) {
390 if (zend_hash_num_elements(&r
->range
.values
) == 1) {
391 zval
**range
, **begin
, **end
;
393 if ( 1 == php_http_array_list(&r
->range
.values TSRMLS_CC
, 1, &range
)
394 && 2 == php_http_array_list(Z_ARRVAL_PP(range
) TSRMLS_CC
, 2, &begin
, &end
)
396 if (SUCCESS
== (ret
= r
->ops
->set_status(r
, 206))) {
397 ret
= r
->ops
->set_header(r
, "Content-Range: bytes %ld-%ld/%zu", Z_LVAL_PP(begin
), Z_LVAL_PP(end
), r
->content
.length
);
400 /* this should never happen */
401 zend_hash_destroy(&r
->range
.values
);
405 php_http_boundary(r
->range
.boundary
, sizeof(r
->range
.boundary
) TSRMLS_CC
);
406 if (SUCCESS
== (ret
= r
->ops
->set_status(r
, 206))) {
407 ret
= r
->ops
->set_header(r
, "Content-Type: multipart/byteranges; boundary=%s", r
->range
.boundary
);
411 if ((zoption
= get_option(options
, ZEND_STRL("cacheControl") TSRMLS_CC
))) {
412 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
414 zval_ptr_dtor(&zoption
);
415 if (Z_STRLEN_P(zoption_copy
)) {
416 ret
= r
->ops
->set_header(r
, "Cache-Control: %.*s", Z_STRLEN_P(zoption_copy
), Z_STRVAL_P(zoption_copy
));
418 zval_ptr_dtor(&zoption_copy
);
421 if (ret
!= SUCCESS
) {
425 if ((zoption
= get_option(options
, ZEND_STRL("contentDisposition") TSRMLS_CC
))) {
426 zval
*zoption_copy
= php_http_ztyp(IS_ARRAY
, zoption
);
427 php_http_buffer_t buf
;
429 php_http_buffer_init(&buf
);
430 if (php_http_params_to_string(&buf
, Z_ARRVAL_P(zoption_copy
), ZEND_STRL(","), ZEND_STRL(";"), ZEND_STRL("="), PHP_HTTP_PARAMS_DEFAULT TSRMLS_CC
)) {
432 ret
= r
->ops
->set_header(r
, "Content-Disposition: %.*s", buf
.used
, buf
.data
);
436 php_http_buffer_dtor(&buf
);
437 zval_ptr_dtor(&zoption_copy
);
438 zval_ptr_dtor(&zoption
);
441 if (ret
!= SUCCESS
) {
445 if ((zoption
= get_option(options
, ZEND_STRL("contentEncoding") TSRMLS_CC
))) {
446 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
448 HashTable
*result
= NULL
;
450 zval_ptr_dtor(&zoption
);
451 switch (Z_LVAL_P(zoption_copy
)) {
452 case PHP_HTTP_CONTENT_ENCODING_GZIP
:
453 INIT_PZVAL(&zsupported
);
454 array_init(&zsupported
);
455 add_next_index_stringl(&zsupported
, ZEND_STRL("none"), 1);
456 add_next_index_stringl(&zsupported
, ZEND_STRL("gzip"), 1);
457 add_next_index_stringl(&zsupported
, ZEND_STRL("deflate"), 1);
459 if ((result
= php_http_negotiate_encoding(Z_ARRVAL(zsupported
), request TSRMLS_CC
))) {
460 char *key_str
= NULL
;
463 zend_hash_internal_pointer_reset(result
);
464 if (HASH_KEY_IS_STRING
== zend_hash_get_current_key_ex(result
, &key_str
, &key_len
, NULL
, 0, NULL
)) {
465 if (!strcmp(key_str
, "gzip")) {
466 if (!(r
->content
.encoder
= php_http_encoding_stream_init(NULL
, php_http_encoding_stream_get_deflate_ops(), PHP_HTTP_DEFLATE_TYPE_GZIP TSRMLS_CC
))) {
468 } else if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Encoding: gzip"))) {
469 r
->content
.encoding
= estrndup(key_str
, key_len
- 1);
471 } else if (!strcmp(key_str
, "deflate")) {
472 if (!(r
->content
.encoder
= php_http_encoding_stream_init(NULL
, php_http_encoding_stream_get_deflate_ops(), PHP_HTTP_DEFLATE_TYPE_ZLIB TSRMLS_CC
))) {
474 } else if (SUCCESS
== (ret
= r
->ops
->set_header(r
, "Content-Encoding: deflate"))) {
475 r
->content
.encoding
= estrndup(key_str
, key_len
- 1);
478 ret
= r
->ops
->del_header(r
, ZEND_STRL("Content-Encoding"));
481 if (SUCCESS
== ret
) {
482 ret
= r
->ops
->add_header(r
, "Vary: Accept-Encoding");
486 zend_hash_destroy(result
);
487 FREE_HASHTABLE(result
);
490 zval_dtor(&zsupported
);
493 case PHP_HTTP_CONTENT_ENCODING_NONE
:
495 ret
= r
->ops
->del_header(r
, ZEND_STRL("Content-Encoding"));
498 zval_ptr_dtor(&zoption_copy
);
501 if (SUCCESS
!= ret
) {
505 if (php_http_env_response_is_cacheable(r
, request
)) {
506 switch (php_http_env_is_response_cached_by_etag(options
, ZEND_STRL("If-None-Match"), request TSRMLS_CC
)) {
507 case PHP_HTTP_CACHE_MISS
:
510 case PHP_HTTP_CACHE_NO
:
511 if (PHP_HTTP_CACHE_HIT
!= php_http_env_is_response_cached_by_last_modified(options
, ZEND_STRL("If-Modified-Since"), request TSRMLS_CC
)) {
516 case PHP_HTTP_CACHE_HIT
:
517 ret
= r
->ops
->set_status(r
, 304);
522 if ((zoption
= get_option(options
, ZEND_STRL("etag") TSRMLS_CC
))) {
523 zval
*zoption_copy
= php_http_ztyp(IS_STRING
, zoption
);
525 zval_ptr_dtor(&zoption
);
526 if (*Z_STRVAL_P(zoption_copy
) != '"' && strncmp(Z_STRVAL_P(zoption_copy
), "W/\"", 3)) {
527 ret
= r
->ops
->set_header(r
, "ETag: \"%s\"", Z_STRVAL_P(zoption_copy
));
529 ret
= r
->ops
->set_header(r
, "ETag: %s", Z_STRVAL_P(zoption_copy
));
531 zval_ptr_dtor(&zoption_copy
);
533 if ((zoption
= get_option(options
, ZEND_STRL("lastModified") TSRMLS_CC
))) {
534 zval
*zoption_copy
= php_http_ztyp(IS_LONG
, zoption
);
536 zval_ptr_dtor(&zoption
);
537 if (Z_LVAL_P(zoption_copy
)) {
538 char *date
= php_format_date(ZEND_STRL(PHP_HTTP_DATE_FORMAT
), Z_LVAL_P(zoption_copy
), 0 TSRMLS_CC
);
540 ret
= r
->ops
->set_header(r
, "Last-Modified: %s", date
);
544 zval_ptr_dtor(&zoption_copy
);
552 static STATUS
php_http_env_response_send_body(php_http_env_response_t
*r
)
554 STATUS ret
= SUCCESS
;
556 php_http_message_body_t
*body
;
557 TSRMLS_FETCH_FROM_CTX(r
->ts
);
563 if ((body
= get_body(r
->options TSRMLS_CC
))) {
564 if ((zoption
= get_option(r
->options
, ZEND_STRL("throttleDelay") TSRMLS_CC
))) {
565 if (Z_TYPE_P(zoption
) == IS_DOUBLE
) {
566 r
->throttle
.delay
= Z_DVAL_P(zoption
);
568 zval_ptr_dtor(&zoption
);
570 if ((zoption
= get_option(r
->options
, ZEND_STRL("throttleChunk") TSRMLS_CC
))) {
571 if (Z_TYPE_P(zoption
) == IS_LONG
) {
572 r
->throttle
.chunk
= Z_LVAL_P(zoption
);
574 zval_ptr_dtor(&zoption
);
577 if (r
->range
.status
== PHP_HTTP_RANGE_OK
) {
578 if (zend_hash_num_elements(&r
->range
.values
) == 1) {
580 zval
**range
, **begin
, **end
;
582 if ( 1 == php_http_array_list(&r
->range
.values TSRMLS_CC
, 1, &range
)
583 && 2 == php_http_array_list(Z_ARRVAL_PP(range
) TSRMLS_CC
, 2, &begin
, &end
)
586 ret
= 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);
587 if (ret
== SUCCESS
) {
588 ret
= php_http_env_response_send_done(r
);
590 zend_hash_destroy(&r
->range
.values
);
592 /* this should never happen */
593 zend_hash_destroy(&r
->range
.values
);
594 r
->ops
->set_status(r
, 500);
599 /* send multipart/byte-ranges message */
603 FOREACH_HASH_VAL(pos
, &r
->range
.values
, chunk
) {
606 if (2 == php_http_array_list(Z_ARRVAL_PP(chunk
) TSRMLS_CC
, 2, &begin
, &end
)) {
607 php_http_buffer_appendf(r
->buffer
,
610 "Content-Type: %s" PHP_HTTP_CRLF
611 "Content-Range: bytes %ld-%ld/%zu" PHP_HTTP_CRLF PHP_HTTP_CRLF
,
614 r
->content
.type
? r
->content
.type
: "application/octet-stream",
619 ret
= 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);
623 if (ret
== SUCCESS
) {
624 php_http_buffer_appendf(r
->buffer
, PHP_HTTP_CRLF
"--%s--", r
->range
.boundary
);
625 ret
= php_http_env_response_send_done(r
);
627 zend_hash_destroy(&r
->range
.values
);
631 ret
= php_http_message_body_to_callback(body
, (php_http_pass_callback_t
) php_http_env_response_send_data
, r
, 0, 0);
632 if (ret
== SUCCESS
) {
633 ret
= php_http_env_response_send_done(r
);
640 STATUS
php_http_env_response_send(php_http_env_response_t
*r
)
642 php_http_message_t
*request
;
643 php_http_message_body_t
*body
;
644 TSRMLS_FETCH_FROM_CTX(r
->ts
);
646 request
= get_request(r
->options TSRMLS_CC
);
648 /* check for ranges */
649 if ((body
= get_body(r
->options TSRMLS_CC
))) {
650 r
->content
.length
= php_http_message_body_size(body
);
652 if (SUCCESS
!= r
->ops
->set_header(r
, "Accept-Ranges: bytes")) {
655 zend_hash_init(&r
->range
.values
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
656 r
->range
.status
= php_http_env_get_request_ranges(&r
->range
.values
, r
->content
.length
, request TSRMLS_CC
);
658 switch (r
->range
.status
) {
659 case PHP_HTTP_RANGE_NO
:
660 zend_hash_destroy(&r
->range
.values
);
663 case PHP_HTTP_RANGE_ERR
:
664 if (php_http_env_got_request_header(ZEND_STRL("If-Range"), request TSRMLS_CC
)) {
665 r
->range
.status
= PHP_HTTP_RANGE_NO
;
666 zend_hash_destroy(&r
->range
.values
);
669 zend_hash_destroy(&r
->range
.values
);
670 if (SUCCESS
!= r
->ops
->set_status(r
, 416)) {
673 if (SUCCESS
!= r
->ops
->set_header(r
, "Content-Range: bytes */%zu", r
->content
.length
)) {
679 case PHP_HTTP_RANGE_OK
:
680 if (PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_etag(r
->options
, ZEND_STRL("If-Range"), request TSRMLS_CC
)
681 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("If-Range"), request TSRMLS_CC
)
683 r
->range
.status
= PHP_HTTP_RANGE_NO
;
684 zend_hash_destroy(&r
->range
.values
);
687 if (PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_etag(r
->options
, ZEND_STRL("If-Match"), request TSRMLS_CC
)
688 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("If-Unmodified-Since"), request TSRMLS_CC
)
689 || PHP_HTTP_CACHE_MISS
== php_http_env_is_response_cached_by_last_modified(r
->options
, ZEND_STRL("Unless-Modified-Since"), request TSRMLS_CC
)
692 zend_hash_destroy(&r
->range
.values
);
693 if (SUCCESS
!= r
->ops
->set_status(r
, 412)) {
704 if (SUCCESS
!= php_http_env_response_send_head(r
, request
)) {
705 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to send response headers");
709 if (SUCCESS
!= php_http_env_response_send_body(r
)) {
710 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to send response body");
714 if (SUCCESS
!= r
->ops
->finish(r
)) {
715 php_error_docref(NULL TSRMLS_CC
, E_WARNING
, "Failed to finish response");
722 static long php_http_env_response_sapi_get_status(php_http_env_response_t
*r
)
724 TSRMLS_FETCH_FROM_CTX(r
->ts
);
726 return php_http_env_get_response_code(TSRMLS_C
);
728 static STATUS
php_http_env_response_sapi_set_status(php_http_env_response_t
*r
, long http_code
)
730 TSRMLS_FETCH_FROM_CTX(r
->ts
);
732 return php_http_env_set_response_code(http_code TSRMLS_CC
);
734 static STATUS
php_http_env_response_sapi_set_protocol_version(php_http_env_response_t
*r
, php_http_version_t
*v
)
736 TSRMLS_FETCH_FROM_CTX(r
->ts
);
738 return php_http_env_set_response_protocol_version(v TSRMLS_CC
);
740 static STATUS
php_http_env_response_sapi_set_header(php_http_env_response_t
*r
, const char *fmt
, ...)
744 TSRMLS_FETCH_FROM_CTX(r
->ts
);
747 ret
= php_http_env_set_response_header_va(0, 1, fmt
, args TSRMLS_CC
);
752 static STATUS
php_http_env_response_sapi_add_header(php_http_env_response_t
*r
, const char *fmt
, ...)
756 TSRMLS_FETCH_FROM_CTX(r
->ts
);
759 ret
= php_http_env_set_response_header_va(0, 0, fmt
, args TSRMLS_CC
);
764 static STATUS
php_http_env_response_sapi_del_header(php_http_env_response_t
*r
, const char *header_str
, size_t header_len
)
766 TSRMLS_FETCH_FROM_CTX(r
->ts
);
768 return php_http_env_set_response_header_value(0, header_str
, header_len
, NULL
, 1 TSRMLS_CC
);
770 static STATUS
php_http_env_response_sapi_write(php_http_env_response_t
*r
, const char *data_str
, size_t data_len
)
772 TSRMLS_FETCH_FROM_CTX(r
->ts
);
774 if (0 < PHPWRITE(data_str
, data_len
)) {
779 static STATUS
php_http_env_response_sapi_flush(php_http_env_response_t
*r
)
781 TSRMLS_FETCH_FROM_CTX(r
->ts
);
783 #if PHP_VERSION_ID >= 50400
784 if (php_output_get_level(TSRMLS_C
)) {
785 php_output_flush_all(TSRMLS_C
);
787 if (!(php_output_get_status(TSRMLS_C
) & PHP_OUTPUT_IMPLICITFLUSH
)) {
788 sapi_flush(TSRMLS_C
);
791 php_end_ob_buffer(1, 1 TSRMLS_CC
);
792 sapi_flush(TSRMLS_C
);
797 static STATUS
php_http_env_response_sapi_finish(php_http_env_response_t
*r
)
802 static php_http_env_response_ops_t php_http_env_response_sapi_ops
= {
805 php_http_env_response_sapi_get_status
,
806 php_http_env_response_sapi_set_status
,
807 php_http_env_response_sapi_set_protocol_version
,
808 php_http_env_response_sapi_set_header
,
809 php_http_env_response_sapi_add_header
,
810 php_http_env_response_sapi_del_header
,
811 php_http_env_response_sapi_write
,
812 php_http_env_response_sapi_flush
,
813 php_http_env_response_sapi_finish
816 php_http_env_response_ops_t
*php_http_env_response_get_sapi_ops(void)
818 return &php_http_env_response_sapi_ops
;
821 typedef struct php_http_env_response_stream_ctx
{
823 php_http_version_t version
;
830 } php_http_env_response_stream_ctx_t
;
832 static STATUS
php_http_env_response_stream_init(php_http_env_response_t
*r
, void *init_arg
)
834 php_http_env_response_stream_ctx_t
*ctx
;
835 TSRMLS_FETCH_FROM_CTX(r
->ts
);
837 ctx
= ecalloc(1, sizeof(*ctx
));
839 ctx
->stream
= init_arg
;
840 if (SUCCESS
!= zend_list_addref(ctx
->stream
->rsrc_id
)) {
844 zend_hash_init(&ctx
->header
, 0, NULL
, ZVAL_PTR_DTOR
, 0);
845 php_http_version_init(&ctx
->version
, 1, 1 TSRMLS_CC
);
846 ctx
->status_code
= 200;
852 static void php_http_env_response_stream_dtor(php_http_env_response_t
*r
)
854 php_http_env_response_stream_ctx_t
*ctx
= r
->ctx
;
855 TSRMLS_FETCH_FROM_CTX(r
->ts
);
857 zend_hash_destroy(&ctx
->header
);
858 zend_list_delete(ctx
->stream
->rsrc_id
);
862 static void php_http_env_response_stream_header(php_http_env_response_stream_ctx_t
*ctx
, HashTable
*header TSRMLS_DC
)
867 FOREACH_HASH_VAL(pos
, &ctx
->header
, val
) {
868 if (Z_TYPE_PP(val
) == IS_ARRAY
) {
869 php_http_env_response_stream_header(ctx
, Z_ARRVAL_PP(val
) TSRMLS_CC
);
871 php_stream_write(ctx
->stream
, Z_STRVAL_PP(val
), Z_STRLEN_PP(val
));
872 php_stream_write_string(ctx
->stream
, PHP_HTTP_CRLF
);
876 static STATUS
php_http_env_response_stream_start(php_http_env_response_stream_ctx_t
*ctx TSRMLS_DC
)
878 if (ctx
->started
|| ctx
->finished
) {
882 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
));
883 php_http_env_response_stream_header(ctx
, &ctx
->header TSRMLS_CC
);
884 php_stream_write_string(ctx
->stream
, PHP_HTTP_CRLF
);
888 static long php_http_env_response_stream_get_status(php_http_env_response_t
*r
)
890 php_http_env_response_stream_ctx_t
*ctx
= r
->ctx
;
892 return ctx
->status_code
;
894 static STATUS
php_http_env_response_stream_set_status(php_http_env_response_t
*r
, long http_code
)
896 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
898 if (stream_ctx
->started
|| stream_ctx
->finished
) {
902 stream_ctx
->status_code
= http_code
;
906 static STATUS
php_http_env_response_stream_set_protocol_version(php_http_env_response_t
*r
, php_http_version_t
*v
)
908 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
910 if (stream_ctx
->started
|| stream_ctx
->finished
) {
914 memcpy(&stream_ctx
->version
, v
, sizeof(stream_ctx
->version
));
918 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
)
920 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
921 char *header_end
, *header_str
= NULL
;
922 size_t header_len
= 0;
923 zval
*zheader
, **zheader_ptr
;
925 if (stream_ctx
->started
|| stream_ctx
->finished
) {
929 header_len
= vspprintf(&header_str
, 0, fmt
, argv
);
931 if (!(header_end
= strchr(header_str
, ':'))) {
938 if (!replace
&& (SUCCESS
== zend_hash_find(&stream_ctx
->header
, header_str
, header_end
- header_str
+ 1, (void *) &zheader_ptr
))) {
939 convert_to_array(*zheader_ptr
);
941 return add_next_index_stringl(*zheader_ptr
, header_str
, header_len
, 0);
943 MAKE_STD_ZVAL(zheader
);
944 ZVAL_STRINGL(zheader
, header_str
, header_len
, 0);
946 if (SUCCESS
!= zend_hash_update(&stream_ctx
->header
, header_str
, header_end
- header_str
+ 1, (void *) &zheader
, sizeof(zval
*), NULL
)) {
947 zval_ptr_dtor(&zheader
);
955 static STATUS
php_http_env_response_stream_set_header(php_http_env_response_t
*r
, const char *fmt
, ...)
961 ret
= php_http_env_response_stream_set_header_ex(r
, 1, fmt
, argv
);
966 static STATUS
php_http_env_response_stream_add_header(php_http_env_response_t
*r
, const char *fmt
, ...)
972 ret
= php_http_env_response_stream_set_header_ex(r
, 0, fmt
, argv
);
977 static STATUS
php_http_env_response_stream_del_header(php_http_env_response_t
*r
, const char *header_str
, size_t header_len
)
979 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
981 if (stream_ctx
->started
|| stream_ctx
->finished
) {
985 zend_hash_del(&stream_ctx
->header
, header_str
, header_len
+ 1);
988 static STATUS
php_http_env_response_stream_write(php_http_env_response_t
*r
, const char *data_str
, size_t data_len
)
990 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
991 TSRMLS_FETCH_FROM_CTX(r
->ts
);
993 if (stream_ctx
->finished
) {
996 if (!stream_ctx
->started
) {
997 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
1002 if (data_len
!= php_stream_write(stream_ctx
->stream
, data_str
, data_len
)) {
1008 static STATUS
php_http_env_response_stream_flush(php_http_env_response_t
*r
)
1010 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
1011 TSRMLS_FETCH_FROM_CTX(r
->ts
);
1013 if (stream_ctx
->finished
) {
1016 if (!stream_ctx
->started
) {
1017 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
1022 return php_stream_flush(stream_ctx
->stream
);
1024 static STATUS
php_http_env_response_stream_finish(php_http_env_response_t
*r
)
1026 php_http_env_response_stream_ctx_t
*stream_ctx
= r
->ctx
;
1027 TSRMLS_FETCH_FROM_CTX(r
->ts
);
1029 if (stream_ctx
->finished
) {
1032 if (!stream_ctx
->started
) {
1033 if (SUCCESS
!= php_http_env_response_stream_start(stream_ctx TSRMLS_CC
)) {
1038 stream_ctx
->finished
= 1;
1043 static php_http_env_response_ops_t php_http_env_response_stream_ops
= {
1044 php_http_env_response_stream_init
,
1045 php_http_env_response_stream_dtor
,
1046 php_http_env_response_stream_get_status
,
1047 php_http_env_response_stream_set_status
,
1048 php_http_env_response_stream_set_protocol_version
,
1049 php_http_env_response_stream_set_header
,
1050 php_http_env_response_stream_add_header
,
1051 php_http_env_response_stream_del_header
,
1052 php_http_env_response_stream_write
,
1053 php_http_env_response_stream_flush
,
1054 php_http_env_response_stream_finish
1057 php_http_env_response_ops_t
*php_http_env_response_get_stream_ops(void)
1059 return &php_http_env_response_stream_ops
;
1062 #define PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj) \
1064 if (!obj->message) { \
1065 obj->message = php_http_message_init_env(NULL, PHP_HTTP_RESPONSE TSRMLS_CC); \
1069 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___construct
, 0, 0, 0)
1070 ZEND_END_ARG_INFO();
1071 static PHP_METHOD(HttpEnvResponse
, __construct
)
1073 php_http_message_object_t
*obj
;
1075 php_http_expect(SUCCESS
== zend_parse_parameters_none(), invalid_arg
, return);
1077 obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1079 php_http_expect(obj
->message
= php_http_message_init_env(obj
->message
, PHP_HTTP_RESPONSE TSRMLS_CC
), unexpected_val
, return);
1082 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse___invoke
, 0, 0, 1)
1083 ZEND_ARG_INFO(0, ob_string
)
1084 ZEND_ARG_INFO(0, ob_flags
)
1085 ZEND_END_ARG_INFO();
1086 static PHP_METHOD(HttpEnvResponse
, __invoke
)
1092 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s|l", &ob_str
, &ob_len
, &ob_flags
)) {
1093 php_http_message_object_t
*obj
= zend_object_store_get_object(getThis() TSRMLS_CC
);
1095 PHP_HTTP_ENV_RESPONSE_OBJECT_INIT(obj
);
1097 php_http_message_object_init_body_object(obj
);
1098 php_http_message_body_append(obj
->message
->body
, ob_str
, ob_len
);
1099 #if PHP_VERSION_ID >= 50400
1102 RETURN_EMPTY_STRING();
1107 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setEnvRequest
, 0, 0, 1)
1108 ZEND_ARG_OBJ_INFO(0, env_request
, http
\\Message
, 1)
1109 ZEND_END_ARG_INFO();
1110 static PHP_METHOD(HttpEnvResponse
, setEnvRequest
)
1112 zval
*env_req
= NULL
;
1114 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|O", &env_req
, php_http_message_class_entry
), invalid_arg
, return);
1116 set_option(getThis(), ZEND_STRL("request"), IS_OBJECT
, env_req
, 0 TSRMLS_CC
);
1117 RETVAL_ZVAL(getThis(), 1, 0);
1120 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentType
, 0, 0, 1)
1121 ZEND_ARG_INFO(0, content_type
)
1122 ZEND_END_ARG_INFO();
1123 static PHP_METHOD(HttpEnvResponse
, setContentType
)
1125 char *ct_str
= NULL
;
1128 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &ct_str
, &ct_len
), invalid_arg
, return);
1130 set_option(getThis(), ZEND_STRL("contentType"), IS_STRING
, ct_str
, ct_len TSRMLS_CC
);
1131 RETVAL_ZVAL(getThis(), 1, 0);
1134 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentDisposition
, 0, 0, 1)
1135 ZEND_ARG_ARRAY_INFO(0, disposition_params
, 1)
1136 ZEND_END_ARG_INFO();
1137 static PHP_METHOD(HttpEnvResponse
, setContentDisposition
)
1141 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "a", &zdisposition
), invalid_arg
, return);
1143 zend_update_property(Z_OBJCE_P(getThis()), getThis(), ZEND_STRL("contentDisposition"), zdisposition TSRMLS_CC
);
1144 RETVAL_ZVAL(getThis(), 1, 0);
1147 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setContentEncoding
, 0, 0, 1)
1148 ZEND_ARG_INFO(0, content_encoding
)
1149 ZEND_END_ARG_INFO();
1150 static PHP_METHOD(HttpEnvResponse
, setContentEncoding
)
1154 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &ce
), invalid_arg
, return);
1156 set_option(getThis(), ZEND_STRL("contentEncoding"), IS_LONG
, &ce
, 0 TSRMLS_CC
);
1157 RETVAL_ZVAL(getThis(), 1, 0);
1160 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setCacheControl
, 0, 0, 1)
1161 ZEND_ARG_INFO(0, cache_control
)
1162 ZEND_END_ARG_INFO();
1163 static PHP_METHOD(HttpEnvResponse
, setCacheControl
)
1165 char *cc_str
= NULL
;
1168 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &cc_str
, &cc_len
), invalid_arg
, return);
1170 set_option(getThis(), ZEND_STRL("cacheControl"), IS_STRING
, cc_str
, cc_len TSRMLS_CC
);
1171 RETVAL_ZVAL(getThis(), 1, 0);
1174 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setLastModified
, 0, 0, 1)
1175 ZEND_ARG_INFO(0, last_modified
)
1176 ZEND_END_ARG_INFO();
1177 static PHP_METHOD(HttpEnvResponse
, setLastModified
)
1181 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l", &last_modified
), invalid_arg
, return);
1183 set_option(getThis(), ZEND_STRL("lastModified"), IS_LONG
, &last_modified
, 0 TSRMLS_CC
);
1184 RETVAL_ZVAL(getThis(), 1, 0);
1187 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_isCachedByLastModified
, 0, 0, 0)
1188 ZEND_ARG_INFO(0, header_name
)
1189 ZEND_END_ARG_INFO();
1190 static PHP_METHOD(HttpEnvResponse
, isCachedByLastModified
)
1192 char *header_name_str
= NULL
;
1193 int header_name_len
= 0;
1195 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &header_name_str
, &header_name_len
)) {
1196 if (!header_name_str
|| !header_name_len
) {
1197 header_name_str
= "If-Modified-Since";
1198 header_name_len
= lenof("If-Modified-Since");
1201 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
));
1205 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setEtag
, 0, 0, 1)
1206 ZEND_ARG_INFO(0, etag
)
1207 ZEND_END_ARG_INFO();
1208 static PHP_METHOD(HttpEnvResponse
, setEtag
)
1210 char *etag_str
= NULL
;
1213 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "s!", &etag_str
, &etag_len
), invalid_arg
, return);
1215 set_option(getThis(), ZEND_STRL("etag"), IS_STRING
, etag_str
, etag_len TSRMLS_CC
);
1216 RETVAL_ZVAL(getThis(), 1, 0);
1219 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_isCachedByEtag
, 0, 0, 0)
1220 ZEND_ARG_INFO(0, header_name
)
1221 ZEND_END_ARG_INFO();
1222 static PHP_METHOD(HttpEnvResponse
, isCachedByEtag
)
1224 char *header_name_str
= NULL
;
1225 int header_name_len
= 0;
1227 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|s!", &header_name_str
, &header_name_len
)) {
1228 if (!header_name_str
|| !header_name_len
) {
1229 header_name_str
= "If-None-Match";
1230 header_name_len
= lenof("If-None-Match");
1232 RETURN_LONG(php_http_env_is_response_cached_by_etag(getThis(), header_name_str
, header_name_len
, get_request(getThis() TSRMLS_CC
) TSRMLS_CC
));
1236 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_setThrottleRate
, 0, 0, 1)
1237 ZEND_ARG_INFO(0, chunk_size
)
1238 ZEND_ARG_INFO(0, delay
)
1239 ZEND_END_ARG_INFO();
1240 static PHP_METHOD(HttpEnvResponse
, setThrottleRate
)
1245 php_http_expect(SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "l|d", &chunk_size
, &delay
), invalid_arg
, return);
1247 set_option(getThis(), ZEND_STRL("throttleDelay"), IS_DOUBLE
, &delay
, 0 TSRMLS_CC
);
1248 set_option(getThis(), ZEND_STRL("throttleChunk"), IS_LONG
, &chunk_size
, 0 TSRMLS_CC
);
1249 RETVAL_ZVAL(getThis(), 1, 0);
1252 ZEND_BEGIN_ARG_INFO_EX(ai_HttpEnvResponse_send
, 0, 0, 0)
1253 ZEND_ARG_INFO(0, stream
)
1254 ZEND_END_ARG_INFO();
1255 static PHP_METHOD(HttpEnvResponse
, send
)
1257 zval
*zstream
= NULL
;
1258 php_stream
*s
= NULL
;
1260 if (SUCCESS
== zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC
, "|r", &zstream
)) {
1261 /* first flush the output layer to avoid conflicting headers and output;
1262 * also, ob_start($thisEnvResponse) might have been called */
1263 #if PHP_VERSION_ID >= 50400
1264 php_output_end_all(TSRMLS_C
);
1266 php_end_ob_buffers(1 TSRMLS_CC
);
1269 php_http_env_response_t
*r
;
1271 php_stream_from_zval(s
, &zstream
);
1272 r
= php_http_env_response_init(NULL
, getThis(), php_http_env_response_get_stream_ops(), s TSRMLS_CC
);
1277 RETVAL_BOOL(SUCCESS
== php_http_env_response_send(r
));
1278 php_http_env_response_free(&r
);
1280 php_http_env_response_t r
;
1282 if (!php_http_env_response_init(&r
, getThis(), NULL
, NULL TSRMLS_CC
)) {
1286 RETVAL_BOOL(SUCCESS
== php_http_env_response_send(&r
));
1287 php_http_env_response_dtor(&r
);
1292 static zend_function_entry php_http_env_response_methods
[] = {
1293 PHP_ME(HttpEnvResponse
, __construct
, ai_HttpEnvResponse___construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
1294 PHP_ME(HttpEnvResponse
, __invoke
, ai_HttpEnvResponse___invoke
, ZEND_ACC_PUBLIC
)
1295 PHP_ME(HttpEnvResponse
, setEnvRequest
, ai_HttpEnvResponse_setEnvRequest
, ZEND_ACC_PUBLIC
)
1296 PHP_ME(HttpEnvResponse
, setContentType
, ai_HttpEnvResponse_setContentType
, ZEND_ACC_PUBLIC
)
1297 PHP_ME(HttpEnvResponse
, setContentDisposition
, ai_HttpEnvResponse_setContentDisposition
, ZEND_ACC_PUBLIC
)
1298 PHP_ME(HttpEnvResponse
, setContentEncoding
, ai_HttpEnvResponse_setContentEncoding
, ZEND_ACC_PUBLIC
)
1299 PHP_ME(HttpEnvResponse
, setCacheControl
, ai_HttpEnvResponse_setCacheControl
, ZEND_ACC_PUBLIC
)
1300 PHP_ME(HttpEnvResponse
, setLastModified
, ai_HttpEnvResponse_setLastModified
, ZEND_ACC_PUBLIC
)
1301 PHP_ME(HttpEnvResponse
, isCachedByLastModified
, ai_HttpEnvResponse_isCachedByLastModified
, ZEND_ACC_PUBLIC
)
1302 PHP_ME(HttpEnvResponse
, setEtag
, ai_HttpEnvResponse_setEtag
, ZEND_ACC_PUBLIC
)
1303 PHP_ME(HttpEnvResponse
, isCachedByEtag
, ai_HttpEnvResponse_isCachedByEtag
, ZEND_ACC_PUBLIC
)
1304 PHP_ME(HttpEnvResponse
, setThrottleRate
, ai_HttpEnvResponse_setThrottleRate
, ZEND_ACC_PUBLIC
)
1305 PHP_ME(HttpEnvResponse
, send
, ai_HttpEnvResponse_send
, ZEND_ACC_PUBLIC
)
1306 EMPTY_FUNCTION_ENTRY
1309 zend_class_entry
*php_http_env_response_class_entry
;
1311 PHP_MINIT_FUNCTION(http_env_response
)
1313 zend_class_entry ce
= {0};
1315 INIT_NS_CLASS_ENTRY(ce
, "http\\Env", "Response", php_http_env_response_methods
);
1316 php_http_env_response_class_entry
= zend_register_internal_class_ex(&ce
, php_http_message_class_entry
, NULL TSRMLS_CC
);
1318 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CONTENT_ENCODING_NONE"), PHP_HTTP_CONTENT_ENCODING_NONE TSRMLS_CC
);
1319 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CONTENT_ENCODING_GZIP"), PHP_HTTP_CONTENT_ENCODING_GZIP TSRMLS_CC
);
1321 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_NO"), PHP_HTTP_CACHE_NO TSRMLS_CC
);
1322 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_HIT"), PHP_HTTP_CACHE_HIT TSRMLS_CC
);
1323 zend_declare_class_constant_long(php_http_env_response_class_entry
, ZEND_STRL("CACHE_MISS"), PHP_HTTP_CACHE_MISS TSRMLS_CC
);
1325 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("request"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1326 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentType"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1327 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentDisposition"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1328 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("contentEncoding"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1329 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("cacheControl"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1330 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("etag"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1331 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("lastModified"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1332 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("throttleDelay"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1333 zend_declare_property_null(php_http_env_response_class_entry
, ZEND_STRL("throttleChunk"), ZEND_ACC_PROTECTED TSRMLS_CC
);
1344 * vim600: noet sw=4 ts=4 fdm=marker
1345 * vim<600: noet sw=4 ts=4