fprintf(stderr, "Flushing after writing %u bytes\n", (uint) data_len);
#endif
-#define HTTP_MSEC(s) (s * 1000)
-#define HTTP_USEC(s) (HTTP_MSEC(s) * 1000)
-#define HTTP_NSEC(s) (HTTP_USEC(s) * 1000)
-#define HTTP_NANOSEC (1000 * 1000 * 1000)
-#define HTTP_DIFFSEC (0.001)
-
if (HTTP_G->send.throttle_delay >= HTTP_DIFFSEC) {
-#if defined(PHP_WIN32)
- Sleep((DWORD) HTTP_MSEC(HTTP_G->send.throttle_delay));
-#elif defined(HAVE_USLEEP)
- usleep(HTTP_USEC(HTTP_G->send.throttle_delay));
-#elif defined(HAVE_NANOSLEEP)
- struct timespec req, rem;
-
- req.tv_sec = (time_t) HTTP_G->send.throttle_delay;
- req.tv_nsec = HTTP_NSEC(HTTP_G->send.throttle_delay) % HTTP_NANOSEC;
-
- while (nanosleep(&req, &rem) && (errno == EINTR) && (HTTP_NSEC(rem.tv_sec) + rem.tv_nsec) > HTTP_NSEC(HTTP_DIFFSEC))) {
- req.tv_sec = rem.tv_sec;
- req.tv_nsec = rem.tv_nsec;
- }
-#endif
+ http_sleep(HTTP_G->send.throttle_delay);
}
}
/* }}} */
{
int encoding;
- if ((encoding = http_encoding_response_start(content_length))) {
+ if ((encoding = http_encoding_response_start(content_length, 0))) {
#ifdef HTTP_HAVE_ZLIB
*buffer = http_encoding_deflate_stream_init(NULL,
(encoding == HTTP_ENCODING_GZIP) ?
#define http_send_response_data_plain(b, d, dl) _http_send_response_data_plain((b), (d), (dl) TSRMLS_CC)
static inline void _http_send_response_data_plain(void **buffer, const char *data, size_t data_len TSRMLS_DC)
{
- if (HTTP_G->send.deflate.encoding) {
+ if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) {
#ifdef HTTP_HAVE_ZLIB
char *encoded;
size_t encoded_len;
#define http_send_response_finish(b) _http_send_response_finish((b) TSRMLS_CC)
static inline void _http_send_response_finish(void **buffer TSRMLS_DC)
{
- if (HTTP_G->send.deflate.encoding) {
+ if (HTTP_G->send.deflate.response && HTTP_G->send.deflate.encoding) {
#ifdef HTTP_HAVE_ZLIB
char *encoded = NULL;
size_t encoded_len = 0;
}
/* }}} */
+/* {{{ http_find_header */
+typedef struct {
+ const char *h;
+ size_t l;
+} http_response_header_t;
+
+static int http_find_header(void *data, void *arg)
+{
+ http_response_header_t *h = arg;
+ sapi_header_struct *s = data;
+
+ return (!strncasecmp(s->header, h->h, h->l)) && s->header[h->l] == ':';
+}
+/* }}} */
+
+/* {{{ void http_hide_header(char *) */
+PHP_HTTP_API void _http_hide_header_ex(const char *name, size_t name_len TSRMLS_DC)
+{
+ http_response_header_t h = {name, name_len};
+ zend_llist_del_element(&SG(sapi_headers).headers, (void *) &h, http_find_header);
+}
+/* }}} */
+
+/* {{{ void http_send_header_zval(char*, zval **, zend_bool) */
+PHP_HTTP_API void _http_send_header_zval_ex(const char *name, size_t name_len, zval **val, zend_bool replace TSRMLS_DC)
+{
+ if (!val || !*val || Z_TYPE_PP(val) == IS_NULL || (Z_TYPE_PP(val) == IS_STRING && !Z_STRLEN_PP(val))) {
+ http_hide_header_ex(name, name_len);
+ } else if (Z_TYPE_PP(val) == IS_ARRAY || Z_TYPE_PP(val) == IS_OBJECT) {
+ zend_bool first = replace;
+ zval **data;
+ HashPosition pos;
+
+ FOREACH_HASH_VAL(pos, HASH_OF(*val), data) {
+ zval *orig = *data;
+
+ convert_to_string_ex(data);
+ http_send_header_ex(name, name_len, Z_STRVAL_PP(data), Z_STRLEN_PP(data), first, NULL);
+ if (orig != *data) {
+ zval_ptr_dtor(data);
+ }
+ first = 0;
+ }
+ } else {
+ zval *orig = *val;
+
+ convert_to_string_ex(val);
+ http_send_header_ex(name, name_len, Z_STRVAL_PP(val), Z_STRLEN_PP(val), replace, NULL);
+ if (orig != *val) {
+ zval_ptr_dtor(val);
+ }
+ }
+}
+/* }}} */
/* {{{ STATUS http_send_header(char *, char *, zend_bool) */
PHP_HTTP_API STATUS _http_send_header_ex(const char *name, size_t name_len, const char *value, size_t value_len, zend_bool replace, char **sent_header TSRMLS_DC)
{
STATUS ret;
- size_t header_len = sizeof(": ") + name_len + value_len + 1;
- char *header = emalloc(header_len + 1);
-
- header[header_len] = '\0';
- header_len = snprintf(header, header_len, "%s: %s", name, value);
- ret = http_send_header_string_ex(header, header_len, replace);
- if (sent_header) {
- *sent_header = header;
+
+ if (value && value_len) {
+ size_t header_len = sizeof(": ") + name_len + value_len + 1;
+ char *header = emalloc(header_len + 1);
+
+ header[header_len] = '\0';
+ header_len = snprintf(header, header_len, "%s: %s", name, value);
+ ret = http_send_header_string_ex(header, header_len, replace);
+ if (sent_header) {
+ *sent_header = header;
+ } else {
+ efree(header);
+ }
} else {
- efree(header);
+ http_hide_header_ex(name, name_len);
+ ret = SUCCESS;
}
return ret;
}
if ((!file) || php_stream_stat(file, &ssb)) {
char *defct = sapi_get_default_content_type(TSRMLS_C);
+ http_hide_header("Content-Disposition");
http_send_content_type(defct, strlen(defct));
- http_send_header_string("Content-Disposition:");
http_error(HE_WARNING, HTTP_E_RESPONSE, "File not found; stat failed");
STR_FREE(defct);