- force syncronized flush on encoding stream
authorMichael Wallner <mike@php.net>
Wed, 19 Apr 2006 15:42:28 +0000 (15:42 +0000)
committerMichael Wallner <mike@php.net>
Wed, 19 Apr 2006 15:42:28 +0000 (15:42 +0000)
- allow erealloc failure in phpstr_resize_ex()

# appending a *deflate* (zlib/gzip) filter to a stream
# for reading won't make one happy, though

http_encoding_api.c
http_filter_api.c
php_http_encoding_api.h
phpstr/phpstr.c
phpstr/phpstr.h

index f732d43ad2ccbecadbdd4f11324069804735e997..bf6fd5c163ae08a267f930d21668ed0b2fb2950b 100644 (file)
@@ -343,9 +343,9 @@ retry_inflate:
                Z.avail_in = data_len;
                
                do {
-                       phpstr_resize(&buffer, data_len << 2);
-
-                       do {
+                       if (phpstr_resize_ex(&buffer, data_len << 2, 0, 1) == (size_t) -1) {
+                               status = Z_MEM_ERROR;
+                       } else do {
                                Z.avail_out = (buffer.free -= Z.total_out - buffer.used);
                                Z.next_out = (Bytef *) buffer.data + (buffer.used = Z.total_out);
                                status = inflate(&Z, Z_NO_FLUSH);
@@ -457,7 +457,7 @@ PHP_HTTP_API STATUS _http_encoding_deflate_stream_update(http_encoding_stream *s
        s->stream.avail_out = *encoded_len;
        s->stream.next_out = (Bytef *) *encoded;
        
-       switch (status = deflate(&s->stream, Z_NO_FLUSH))
+       switch (status = deflate(&s->stream, HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags)))
        {
                case Z_OK:
                case Z_STREAM_END:
@@ -503,7 +503,7 @@ retry_raw_inflate:
                s->stream.next_out = (Bytef *) *decoded;
                s->stream.avail_out = *decoded_len;
                
-               switch (status = inflate(&s->stream, Z_NO_FLUSH))
+               switch (status = inflate(&s->stream, HTTP_ENCODING_STREAM_FLUSH_FLAG(s->flags)))
                {
                        case Z_OK:
                        case Z_STREAM_END:
@@ -549,7 +549,7 @@ PHP_HTTP_API STATUS _http_encoding_deflate_stream_flush(http_encoding_stream *s,
        s->stream.avail_out = *encoded_len;
        s->stream.next_out = (Bytef *) *encoded;
        
-       switch (status = deflate(&s->stream, Z_SYNC_FLUSH))
+       switch (status = deflate(&s->stream, Z_FULL_FLUSH))
        {
                case Z_OK:
                case Z_STREAM_END:
index 02467decdb2844570151a79883d83d10ad9a89ca..8d138b9c748e214807cd15dd13abeeb5716cd641 100644 (file)
@@ -313,8 +313,10 @@ static HTTP_FILTER_FUNCTION(deflate)
                        if (ptr->buflen) {
                                http_encoding_deflate_stream_update(buffer, ptr->buf, ptr->buflen, &encoded, &encoded_len);
                                if (encoded) {
-                                       out_avail = 1;
-                                       NEW_BUCKET(encoded, encoded_len);
+                                       if (encoded_len) {
+                                               out_avail = 1;
+                                               NEW_BUCKET(encoded, encoded_len);
+                                       }
                                        efree(encoded);
                                }
                        }
@@ -331,8 +333,10 @@ static HTTP_FILTER_FUNCTION(deflate)
                
                http_encoding_deflate_stream_flush(buffer, &encoded, &encoded_len);
                if (encoded) {
-                       out_avail = 1;
-                       NEW_BUCKET(encoded, encoded_len);
+                       if (encoded_len) {
+                               out_avail = 1;
+                               NEW_BUCKET(encoded, encoded_len);
+                       }
                        efree(encoded);
                }
        }
@@ -343,8 +347,10 @@ static HTTP_FILTER_FUNCTION(deflate)
                
                http_encoding_deflate_stream_finish(buffer, &encoded, &encoded_len);
                if (encoded) {
-                       out_avail = 1;
-                       NEW_BUCKET(encoded, encoded_len);
+                       if (encoded_len) {
+                               out_avail = 1;
+                               NEW_BUCKET(encoded, encoded_len);
+                       }
                        efree(encoded);
                }
        }
@@ -378,8 +384,10 @@ static HTTP_FILTER_FUNCTION(inflate)
                        if (ptr->buflen) {
                                http_encoding_inflate_stream_update(buffer, ptr->buf, ptr->buflen, &decoded, &decoded_len);
                                if (decoded) {
-                                       out_avail = 1;
-                                       NEW_BUCKET(decoded, decoded_len);
+                                       if (decoded_len) {
+                                               out_avail = 1;
+                                               NEW_BUCKET(decoded, decoded_len);
+                                       }
                                        efree(decoded);
                                }
                        }
@@ -396,8 +404,10 @@ static HTTP_FILTER_FUNCTION(inflate)
                
                http_encoding_inflate_stream_flush(buffer, &decoded, &decoded_len);
                if (decoded) {
-                       out_avail = 1;
-                       NEW_BUCKET(decoded, decoded_len);
+                       if (decoded_len) {
+                               out_avail = 1;
+                               NEW_BUCKET(decoded, decoded_len);
+                       }
                        efree(decoded);
                }
        }
@@ -408,8 +418,10 @@ static HTTP_FILTER_FUNCTION(inflate)
                
                http_encoding_inflate_stream_finish(buffer, &decoded, &decoded_len);
                if (decoded) {
-                       out_avail = 1;
-                       NEW_BUCKET(decoded, decoded_len);
+                       if (decoded_len) {
+                               out_avail = 1;
+                               NEW_BUCKET(decoded, decoded_len);
+                       }
                        efree(decoded);
                }
        }
@@ -465,7 +477,7 @@ static php_stream_filter *http_filter_create(const char *name, zval *params, int
        } else
        
        if (!strcasecmp(name, "http.inflate")) {
-               int flags = p ? HTTP_ENCODING_STREAM_PERSISTENT : 0;
+               int flags = HTTP_ENCODING_STREAM_FLUSH_SYNC | (p ? HTTP_ENCODING_STREAM_PERSISTENT : 0);
                HTTP_FILTER_BUFFER(inflate) *b = NULL;
                
                if ((b = http_encoding_inflate_stream_init(NULL, flags))) {
@@ -476,7 +488,7 @@ static php_stream_filter *http_filter_create(const char *name, zval *params, int
        } else
        
        if (!strcasecmp(name, "http.deflate")) {
-               int flags = p ? HTTP_ENCODING_STREAM_PERSISTENT : 0;
+               int flags = HTTP_ENCODING_STREAM_FLUSH_SYNC | (p ? HTTP_ENCODING_STREAM_PERSISTENT : 0);
                HTTP_FILTER_BUFFER(deflate) *b = NULL;
                
                if (params) {
@@ -492,7 +504,7 @@ static php_stream_filter *http_filter_create(const char *name, zval *params, int
                                        zval *orig = *tmp;
                                        
                                        convert_to_long_ex(tmp);
-                                       flags |= (Z_LVAL_PP(tmp) & 0x0fffffff);
+                                       flags |= (Z_LVAL_PP(tmp) & 0x00ffffff);
                                        if (orig != *tmp) zval_ptr_dtor(tmp);
                                }
                        }
index 88540334050f19cd82b8e2d8768b513d9da7a935..88b4295d2606e03689ca68f714e3391cb8599af0 100644 (file)
@@ -62,6 +62,15 @@ typedef enum _http_encoding_type_t {
 #define HTTP_INFLATE_TYPE_GZIP                 0x00000000
 #define HTTP_INFLATE_TYPE_RAW                  0x00000001
 
+#define HTTP_ENCODING_STREAM_FLUSH_NONE        0x00000000
+#define HTTP_ENCODING_STREAM_FLUSH_SYNC 0x00100000
+#define HTTP_ENCODING_STREAM_FLUSH_FULL 0x00200000
+
+#define HTTP_ENCODING_STREAM_FLUSH_FLAG(f) ( \
+       (f) & HTTP_ENCODING_STREAM_FLUSH_FULL ? Z_FULL_FLUSH : \
+       (f) & HTTP_ENCODING_STREAM_FLUSH_SYNC ? Z_SYNC_FLUSH : \
+       Z_NO_FLUSH)
+
 #define HTTP_ENCODING_STREAM_PERSISTENT        0x01000000
 
 typedef struct _http_encoding_stream_t {
index a312b1e773134dbe2ad558aeaaffaa78ff1ec38b..4eaec1c0a9a300365ec1252a79f9944d3aef6e93 100644 (file)
@@ -34,7 +34,7 @@ PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t
        return buf;
 }
 
-PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size)
+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size, int allow_error)
 {
 #if 0
        fprintf(stderr, "RESIZE: size=%lu, used=%lu, free=%lu\n", buf->size, buf->used, buf->free);
@@ -46,7 +46,13 @@ PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size
                        size *= 2;
                }
                if (buf->data) {
-                       char *ptr = perealloc(buf->data, buf->used + buf->free + size, buf->pmem);
+                       char *ptr;
+                       
+                       if (allow_error) {
+                               ptr = perealloc_recoverable(buf->data, buf->used + buf->free + size, buf->pmem);
+                       } else {
+                               ptr = perealloc(buf->data, buf->used + buf->free + size, buf->pmem);
+                       }
                        
                        if (ptr) {
                                buf->data = ptr;
@@ -279,7 +285,7 @@ PHPSTR_API phpstr *phpstr_merge(unsigned argc, ...)
 
 PHPSTR_API phpstr *phpstr_fix(phpstr *buf)
 {
-       if (NOMEM == phpstr_resize_ex(buf, 1, 1)) {
+       if (NOMEM == phpstr_resize_ex(buf, 1, 1, 0)) {
                return NULL;
        }
        buf->data[buf->used] = '\0';
index ac58c1d320f95c974080a693a24dfbce75a2561d..40e2e32f92587be8c9bef0aa260e737986be532f 100644 (file)
@@ -105,8 +105,8 @@ PHPSTR_API phpstr *phpstr_init_ex(phpstr *buf, size_t chunk_size, int flags);
 PHPSTR_API phpstr *phpstr_from_string_ex(phpstr *buf, const char *string, size_t length);
 
 /* usually only called from within the internal functions */
-#define phpstr_resize(b, s) phpstr_resize_ex((b), (s), 0)
-PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size);
+#define phpstr_resize(b, s) phpstr_resize_ex((b), (s), 0, 0)
+PHPSTR_API size_t phpstr_resize_ex(phpstr *buf, size_t len, size_t override_size, int allow_error);
 
 /* shrink memory chunk to actually used size (+1) */
 PHPSTR_API size_t phpstr_shrink(phpstr *buf);