2 +----------------------------------------------------------------------+
4 +----------------------------------------------------------------------+
5 | This source file is subject to version 3.0 of the PHP license, that |
6 | is bundled with this package in the file LICENSE, and is available |
7 | through the world-wide-web at http://www.php.net/license/3_0.txt. |
8 | If you did not receive a copy of the PHP license and are unable to |
9 | obtain it through the world-wide-web, please send a note to |
10 | license@php.net so we can mail you a copy immediately. |
11 +----------------------------------------------------------------------+
12 | Copyright (c) 2004-2005 Michael Wallner <mike@php.net> |
13 +----------------------------------------------------------------------+
27 #include "php_http_api.h"
28 #include "php_http_std_defs.h"
29 #include "php_http_response_object.h"
30 #include "php_http_send_api.h"
31 #include "php_http_cache_api.h"
35 ZEND_EXTERN_MODULE_GLOBALS(http
);
37 #define HTTP_BEGIN_ARGS(method, req_args) HTTP_BEGIN_ARGS_EX(HttpResponse, method, 0, req_args)
38 #define HTTP_EMPTY_ARGS(method, ret_ref) HTTP_EMPTY_ARGS_EX(HttpResponse, method, ret_ref)
39 #define HTTP_RESPONSE_ME(method, visibility) PHP_ME(HttpResponse, method, HTTP_ARGS(HttpResponse, method), visibility)
41 HTTP_EMPTY_ARGS(__destruct
, 0);
42 HTTP_BEGIN_ARGS(__construct
, 0)
43 HTTP_ARG_VAL(cache
, 0)
47 HTTP_EMPTY_ARGS(getETag
, 0);
48 HTTP_BEGIN_ARGS(setETag
, 1)
52 HTTP_EMPTY_ARGS(getCache
, 0);
53 HTTP_BEGIN_ARGS(setCache
, 1)
54 HTTP_ARG_VAL(cache
, 0)
57 HTTP_EMPTY_ARGS(getGzip
, 0);
58 HTTP_BEGIN_ARGS(setGzip
, 1)
62 HTTP_EMPTY_ARGS(getCacheControl
, 0);
63 HTTP_BEGIN_ARGS(setCacheControl
, 1)
64 HTTP_ARG_VAL(cache_control
, 0)
68 HTTP_EMPTY_ARGS(getContentType
, 0);
69 HTTP_BEGIN_ARGS(setContentType
, 1)
70 HTTP_ARG_VAL(content_type
, 0)
73 HTTP_EMPTY_ARGS(getContentDisposition
, 0);
74 HTTP_BEGIN_ARGS(setContentDisposition
, 1)
75 HTTP_ARG_VAL(filename
, 0)
76 HTTP_ARG_VAL(send_inline
, 0)
79 HTTP_EMPTY_ARGS(getThrottleDelay
, 0);
80 HTTP_BEGIN_ARGS(setThrottleDelay
, 1)
81 HTTP_ARG_VAL(seconds
, 0)
84 HTTP_EMPTY_ARGS(getSendBuffersize
, 0);
85 HTTP_BEGIN_ARGS(setSendBuffersize
, 1)
86 HTTP_ARG_VAL(bytes
, 0)
89 HTTP_EMPTY_ARGS(getData
, 0);
90 HTTP_BEGIN_ARGS(setData
, 1)
94 HTTP_EMPTY_ARGS(getStream
, 0);
95 HTTP_BEGIN_ARGS(setStream
, 1)
96 HTTP_ARG_VAL(stream
, 0)
99 HTTP_EMPTY_ARGS(getFile
, 0);
100 HTTP_BEGIN_ARGS(setFile
, 1)
101 HTTP_ARG_VAL(filepath
, 0)
104 HTTP_BEGIN_ARGS(send
, 0)
105 HTTP_ARG_VAL(clean_ob
, 0)
108 HTTP_BEGIN_ARGS(catchOutput
, 0)
109 HTTP_ARG_VAL(clean_ob
, 0)
112 #define http_response_object_declare_default_properties() _http_response_object_declare_default_properties(TSRMLS_C)
113 static inline void _http_response_object_declare_default_properties(TSRMLS_D
);
115 zend_class_entry
*http_response_object_ce
;
116 zend_function_entry http_response_object_fe
[] = {
117 HTTP_RESPONSE_ME(__construct
, ZEND_ACC_PUBLIC
|ZEND_ACC_CTOR
)
118 HTTP_RESPONSE_ME(__destruct
, ZEND_ACC_PUBLIC
|ZEND_ACC_DTOR
)
120 HTTP_RESPONSE_ME(setETag
, ZEND_ACC_PUBLIC
)
121 HTTP_RESPONSE_ME(getETag
, ZEND_ACC_PUBLIC
)
123 HTTP_RESPONSE_ME(setContentDisposition
, ZEND_ACC_PUBLIC
)
124 HTTP_RESPONSE_ME(getContentDisposition
, ZEND_ACC_PUBLIC
)
126 HTTP_RESPONSE_ME(setContentType
, ZEND_ACC_PUBLIC
)
127 HTTP_RESPONSE_ME(getContentType
, ZEND_ACC_PUBLIC
)
129 HTTP_RESPONSE_ME(setCache
, ZEND_ACC_PUBLIC
)
130 HTTP_RESPONSE_ME(getCache
, ZEND_ACC_PUBLIC
)
132 HTTP_RESPONSE_ME(setCacheControl
, ZEND_ACC_PUBLIC
)
133 HTTP_RESPONSE_ME(getCacheControl
, ZEND_ACC_PUBLIC
)
135 HTTP_RESPONSE_ME(setGzip
, ZEND_ACC_PUBLIC
)
136 HTTP_RESPONSE_ME(getGzip
, ZEND_ACC_PUBLIC
)
138 HTTP_RESPONSE_ME(setThrottleDelay
, ZEND_ACC_PUBLIC
)
139 HTTP_RESPONSE_ME(getThrottleDelay
, ZEND_ACC_PUBLIC
)
141 HTTP_RESPONSE_ME(setSendBuffersize
, ZEND_ACC_PUBLIC
)
142 HTTP_RESPONSE_ME(getSendBuffersize
, ZEND_ACC_PUBLIC
)
144 HTTP_RESPONSE_ME(setData
, ZEND_ACC_PUBLIC
)
145 HTTP_RESPONSE_ME(getData
, ZEND_ACC_PUBLIC
)
147 HTTP_RESPONSE_ME(setFile
, ZEND_ACC_PUBLIC
)
148 HTTP_RESPONSE_ME(getFile
, ZEND_ACC_PUBLIC
)
150 HTTP_RESPONSE_ME(setStream
, ZEND_ACC_PUBLIC
)
151 HTTP_RESPONSE_ME(getStream
, ZEND_ACC_PUBLIC
)
153 HTTP_RESPONSE_ME(send
, ZEND_ACC_PUBLIC
)
154 HTTP_RESPONSE_ME(catchOutput
, ZEND_ACC_PUBLIC
)
158 static zend_object_handlers http_response_object_handlers
;
160 void _http_response_object_init(INIT_FUNC_ARGS
)
162 HTTP_REGISTER_CLASS_EX(HttpResponse
, http_response_object
, NULL
, 0);
165 zend_object_value
_http_response_object_new(zend_class_entry
*ce TSRMLS_DC
)
167 zend_object_value ov
;
168 http_response_object
*o
;
170 o
= ecalloc(1, sizeof(http_response_object
));
173 ALLOC_HASHTABLE(OBJ_PROP(o
));
174 zend_hash_init(OBJ_PROP(o
), 0, NULL
, ZVAL_PTR_DTOR
, 0);
175 zend_hash_copy(OBJ_PROP(o
), &ce
->default_properties
, (copy_ctor_func_t
) zval_add_ref
, NULL
, sizeof(zval
*));
177 ov
.handle
= zend_objects_store_put(o
, (zend_objects_store_dtor_t
) zend_objects_destroy_object
, http_response_object_free
, NULL TSRMLS_CC
);
178 ov
.handlers
= &http_response_object_handlers
;
183 static inline void _http_response_object_declare_default_properties(TSRMLS_D
)
185 zend_class_entry
*ce
= http_response_object_ce
;
187 DCL_PROP(PROTECTED
, string
, contentType
, "application/x-octetstream");
188 DCL_PROP(PROTECTED
, string
, eTag
, "");
189 DCL_PROP(PROTECTED
, string
, dispoFile
, "");
190 DCL_PROP(PROTECTED
, string
, cacheControl
, "public");
191 DCL_PROP(PROTECTED
, string
, data
, "");
192 DCL_PROP(PROTECTED
, string
, file
, "");
193 DCL_PROP(PROTECTED
, long, stream
, 0);
194 DCL_PROP(PROTECTED
, long, lastModified
, 0);
195 DCL_PROP(PROTECTED
, long, dispoInline
, 0);
196 DCL_PROP(PROTECTED
, long, cache
, 0);
197 DCL_PROP(PROTECTED
, long, gzip
, 0);
198 DCL_PROP(PROTECTED
, long, sendBuffersize
, HTTP_SENDBUF_SIZE
);
199 DCL_PROP(PROTECTED
, double, throttleDelay
, 0.0);
201 DCL_PROP(PRIVATE
, long, raw_cache_header
, 0);
202 DCL_PROP(PRIVATE
, long, send_mode
, -1);
203 DCL_PROP(PRIVATE
, long, sent
, 0);
204 DCL_PROP(PRIVATE
, long, catch_ob
, 0);
207 void _http_response_object_free(zend_object
*object TSRMLS_DC
)
209 http_response_object
*o
= (http_response_object
*) object
;
212 zend_hash_destroy(OBJ_PROP(o
));
213 FREE_HASHTABLE(OBJ_PROP(o
));
218 void _http_response_object_sendhandler(zval
*this_ptr
, http_response_object
*obj
, zend_bool clean_ob
, zval
*return_value TSRMLS_DC
)
220 zval
*do_cache
, *do_gzip
;
223 getObject(http_response_object
, o
);
227 do_cache
= GET_PROP(obj
, cache
);
228 do_gzip
= GET_PROP(obj
, gzip
);
231 /* interrupt on-the-fly etag generation */
232 HTTP_G(etag
).started
= 0;
233 /* discard previous output buffers */
234 php_end_ob_buffers(0 TSRMLS_CC
);
238 if (Z_LVAL_P(do_gzip
)) {
239 php_start_ob_buffer_named("ob_gzhandler", 0, 1 TSRMLS_CC
);
243 if (Z_LVAL_P(do_cache
)) {
246 zval
*cctrl
, *etag
, *lmod
, *ccraw
;
248 etag
= GET_PROP(obj
, eTag
);
249 lmod
= GET_PROP(obj
, lastModified
);
250 cctrl
= GET_PROP(obj
, cacheControl
);
251 ccraw
= GET_PROP(obj
, raw_cache_header
);
253 if (Z_LVAL_P(ccraw
)) {
254 cc_hdr
= Z_STRVAL_P(cctrl
);
255 cc_len
= Z_STRLEN_P(cctrl
);
257 char cc_header
[42] = {0};
258 sprintf(cc_header
, "%s, must-revalidate, max-age=0", Z_STRVAL_P(cctrl
));
260 cc_len
= Z_STRLEN_P(cctrl
) + lenof(", must-revalidate, max-age=0");
263 http_cache_etag(Z_STRVAL_P(etag
), Z_STRLEN_P(etag
), cc_hdr
, cc_len
);
264 http_cache_last_modified(Z_LVAL_P(lmod
), Z_LVAL_P(lmod
) ? Z_LVAL_P(lmod
) : time(NULL
), cc_hdr
, cc_len
);
269 zval
*ctype
= GET_PROP(obj
, contentType
);
270 if (Z_STRLEN_P(ctype
)) {
271 http_send_content_type(Z_STRVAL_P(ctype
), Z_STRLEN_P(ctype
));
273 http_send_content_type("application/x-octetstream", lenof("application/x-octetstream"));
277 /* content disposition */
279 zval
*dispo_file
= GET_PROP(obj
, dispoFile
);
280 if (Z_STRLEN_P(dispo_file
)) {
281 zval
*dispo_inline
= GET_PROP(obj
, dispoInline
);
282 http_send_content_disposition(Z_STRVAL_P(dispo_file
), Z_STRLEN_P(dispo_file
), (zend_bool
) Z_LVAL_P(dispo_inline
));
288 zval
*send_buffersize
, *throttle_delay
;
289 send_buffersize
= GET_PROP(obj
, sendBuffersize
);
290 throttle_delay
= GET_PROP(obj
, throttleDelay
);
291 HTTP_G(send
).buffer_size
= Z_LVAL_P(send_buffersize
);
292 HTTP_G(send
).throttle_delay
= Z_DVAL_P(throttle_delay
);
297 zval
*send_mode
= GET_PROP(obj
, send_mode
);
298 switch (Z_LVAL_P(send_mode
))
302 zval
*zdata
= GET_PROP(obj
, data
);
303 RETURN_SUCCESS(http_send_data(Z_STRVAL_P(zdata
), Z_STRLEN_P(zdata
)));
308 php_stream
*the_real_stream
;
309 zval
*the_stream
= GET_PROP(obj
, stream
);
310 php_stream_from_zval(the_real_stream
, &the_stream
);
311 RETURN_SUCCESS(http_send_stream(the_real_stream
));
316 zval
*zfile
= GET_PROP(obj
, file
);
317 RETURN_SUCCESS(http_send_file(Z_STRVAL_P(zfile
)));
323 #endif /* ZEND_ENGINE_2 */
330 * vim600: noet sw=4 ts=4 fdm=marker
331 * vim<600: noet sw=4 ts=4