- add compression functions to userspace
authorMichael Wallner <mike@php.net>
Mon, 10 Oct 2005 16:40:15 +0000 (16:40 +0000)
committerMichael Wallner <mike@php.net>
Mon, 10 Oct 2005 16:40:15 +0000 (16:40 +0000)
http_functions.c
http_util_object.c
package2.xml
php_http.h
php_http_api.h
php_http_util_object.h
tests/request_gzip.phpt

index 364e81fe13c948eb9b6331afd1272a2f8212cb48..d205ea26567f10a5106f68b054fe21bb0df26d57 100644 (file)
@@ -1408,6 +1408,188 @@ PHP_FUNCTION(http_build_query)
 #endif /* !ZEND_ENGINE_2 */
 /* }}} */
 
+/* {{{ */
+#ifdef HTTP_HAVE_ZLIB
+
+/* {{{ proto string http_gzencode(string data[, int level = -1])
+ *
+ * Compress data with the HTTP compatible GZIP encoding.
+ * 
+ * Expects the first parameter to be a string which contains the data that
+ * should be encoded.  Additionally accepts an optional in paramter specifying
+ * the compression level, where -1 is default, 0 is no compression and 9 is
+ * best compression ratio.
+ * 
+ * Returns the encoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_gzencode)
+{
+       char *data;
+       int data_len;
+       long level = -1;
+
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) {
+               HTTP_CHECK_GZIP_LEVEL(level, return);
+               {
+                       char *encoded;
+                       size_t encoded_len;
+                       
+                       if (SUCCESS == http_encoding_gzencode(level, data, data_len, &encoded, &encoded_len)) {
+                               RETURN_STRINGL(encoded, (int) encoded_len, 0);
+                       }
+               }
+       }
+}
+/* }}} */
+
+/* {{{ proto string http_gzdecode(string data)
+ *
+ * Uncompress data compressed with the HTTP compatible GZIP encoding.
+ * 
+ * Expects a string as parameter containing the compressed data.
+ * 
+ * Returns the decoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_gzdecode)
+{
+       char *data;
+       int data_len;
+       
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
+               char *decoded;
+               size_t decoded_len;
+               
+               if (SUCCESS == http_encoding_gzdecode(data, data_len, &decoded, &decoded_len)) {
+                       RETURN_STRINGL(decoded, (int) decoded_len, 0);
+               }
+       }
+}
+/* }}} */
+
+/* {{{  proto string http_deflate(string data[, int level = -1])
+ *
+ * Compress data with the HTTP compatible DEFLATE encoding.
+ * 
+ * Expects the first parameter to be a string containing the data that should
+ * be encoded.  Additionally accepts an optional int parameter specifying the
+ * compression level, where -1 is default, 0 is no compression and 9 is best
+ * compression ratio.
+ * 
+ * Returns the encoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_deflate)
+{
+       char *data;
+       int data_len;
+       long level = -1;
+       
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) {
+               HTTP_CHECK_GZIP_LEVEL(level, return);
+               {
+                       char *encoded;
+                       size_t encoded_len;
+                       
+                       if (SUCCESS == http_encoding_deflate(level, data, data_len, &encoded, &encoded_len)) {
+                               RETURN_STRINGL(encoded, (int) encoded_len, 0);
+                       }
+               }
+       }
+}
+/* }}} */
+
+/* {{{ proto string http_inflate(string data)
+ *
+ * Uncompress data compressed with the HTTP compatible DEFLATE encoding.
+ * 
+ * Expects a string as parameter containing the compressed data.
+ * 
+ * Returns the decoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_inflate)
+{
+       char *data;
+       int data_len;
+       
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
+               char *decoded;
+               size_t decoded_len;
+               
+               if (SUCCESS == http_encoding_inflate(data, data_len, &decoded, &decoded_len)) {
+                       RETURN_STRINGL(decoded, (int) decoded_len, 0);
+               }
+       }
+}
+/* }}} */
+
+/* {{{ proto string http_compress(string data[, int level = -1])
+ *
+ * Compress data with the HTTP compatible COMPRESS encoding.
+ * 
+ * Expects the first parameter to be a string containing the data which should
+ * be encoded.  Additionally accepts an optional int parameter specifying the
+ * compression level, where -1 is default, 0 is no compression and 9 is best
+ * compression ratio.
+ * 
+ * Returns the encoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_compress)
+{
+       char *data;
+       int data_len;
+       long level;
+       
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &data, &data_len, &level)) {
+               HTTP_CHECK_GZIP_LEVEL(level, return);
+               {
+                       char *encoded;
+                       size_t encoded_len;
+                       
+                       if (SUCCESS == http_encoding_compress(level, data, data_len, &encoded, &encoded_len)) {
+                               RETURN_STRINGL(encoded, (int) encoded_len, 0);
+                       }
+               }
+       }
+}
+/* }}} */
+
+/* {{{ proto string http_uncompress(string data)
+ *
+ * Uncompress data compressed with the HTTP compatible COMPRESS encoding.
+ * 
+ * Expects a string as parameter containing the compressed data.
+ * 
+ * Returns the decoded string on success, or NULL on failure.
+ */
+PHP_FUNCTION(http_uncompress)
+{
+       char *data;
+       int data_len;
+       
+       RETVAL_NULL();
+       
+       if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &data, &data_len)) {
+               char *decoded;
+               size_t decoded_len;
+               
+               if (SUCCESS == http_encoding_uncompress(data, data_len, &decoded, &decoded_len)) {
+                       RETURN_STRINGL(decoded, decoded_len, 0);
+               }
+       }
+}
+/* }}} */
+#endif /* HTTP_HAVE_ZLIB */
+/* }}} */
+
 PHP_FUNCTION(http_test)
 {
 }
index ac87820f678b2f19d8d2ae2786d632e96d513dc6..8fab46bb8e07b4f3ab69e165b612f6c47131054c 100644 (file)
@@ -69,10 +69,6 @@ HTTP_BEGIN_ARGS(matchRequestHeader, 2)
        HTTP_ARG_VAL(case_sensitive, 0)
 HTTP_END_ARGS;
 
-HTTP_BEGIN_ARGS(chunkedDecode, 1)
-       HTTP_ARG_VAL(encoded_string, 0)
-HTTP_END_ARGS;
-
 HTTP_BEGIN_ARGS(parseMessage, 1)
        HTTP_ARG_VAL(message_string, 0)
 HTTP_END_ARGS;
@@ -81,6 +77,37 @@ HTTP_BEGIN_ARGS(parseHeaders, 1)
        HTTP_ARG_VAL(headers_string, 0)
 HTTP_END_ARGS;
 
+HTTP_BEGIN_ARGS(chunkedDecode, 1)
+       HTTP_ARG_VAL(encoded_string, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(gzEncode, 1)
+       HTTP_ARG_VAL(plain, 0)
+       HTTP_ARG_VAL(level, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(gzDecode, 1)
+       HTTP_ARG_VAL(encoded, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(deflate, 1)
+       HTTP_ARG_VAL(plain, 0)
+       HTTP_ARG_VAL(level, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(inflate, 1)
+       HTTP_ARG_VAL(encoded, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(compress, 1)
+       HTTP_ARG_VAL(plain, 0)
+       HTTP_ARG_VAL(level, 0)
+HTTP_END_ARGS;
+
+HTTP_BEGIN_ARGS(uncompress, 1)
+       HTTP_ARG_VAL(encoded, 0)
+HTTP_END_ARGS;
+
 zend_class_entry *http_util_object_ce;
 zend_function_entry http_util_object_fe[] = {
        HTTP_UTIL_ALIAS(date, http_date)
@@ -90,9 +117,15 @@ zend_function_entry http_util_object_fe[] = {
        HTTP_UTIL_ALIAS(matchModified, http_match_modified)
        HTTP_UTIL_ALIAS(matchEtag, http_match_etag)
        HTTP_UTIL_ALIAS(matchRequestHeader, http_match_request_header)
-       HTTP_UTIL_ALIAS(chunkedDecode, http_chunked_decode)
        HTTP_UTIL_ALIAS(parseMessage, http_parse_message)
        HTTP_UTIL_ALIAS(parseHeaders, http_parse_headers)
+       HTTP_UTIL_ALIAS(chunkedDecode, http_chunked_decode)
+       HTTP_UTIL_ALIAS(gzEncode, http_gzencode)
+       HTTP_UTIL_ALIAS(gzDecode, http_gzdecode)
+       HTTP_UTIL_ALIAS(deflate, http_deflate)
+       HTTP_UTIL_ALIAS(inflate, http_inflate)
+       HTTP_UTIL_ALIAS(compress, http_compress)
+       HTTP_UTIL_ALIAS(uncompress, http_uncompress)
        
        EMPTY_FUNCTION_ENTRY
 };
index efeadf3bbc99a2d250a8f84444596d9cd076c09a..8de160f3da9618836f23c786b0012c3a522f3cbe 100644 (file)
@@ -41,6 +41,7 @@
  <notes><![CDATA[
 + Updated documentation (a lot)
 + Added optional third parameter to HttpRequest::__construct() accepting an array with options
++ Added compression functions gzencode/gzdecode, deflate/inflate, compress/uncompress
 
 - Renamed http_absolute_uri() to http_build_uri() (complements with http_build_query())
 - Changed the signature of the negotiator to fill the second parameter with the results array
@@ -85,6 +86,7 @@
    <file role="src" name="php_http_api.h"/>
    <file role="src" name="php_http_cache_api.h"/>
    <file role="src" name="php_http_date_api.h"/>
+   <file role="src" name="php_http_encoding_api.h">
    <file role="src" name="php_http_headers_api.h"/>
    <file role="src" name="php_http_info_api.h"/>
    <file role="src" name="php_http_message_api.h"/>
    <file role="src" name="http_api.c"/>
    <file role="src" name="http_cache_api.c"/>
    <file role="src" name="http_date_api.c"/>
+   <file role="src" name="http_encoding_api.c">
    <file role="src" name="http_headers_api.c"/>
    <file role="src" name="http_info_api.c"/>
    <file role="src" name="http_message_api.c"/>
index 8600f12fde25b60a0e1d94877d070277ece632a2..223a4f63dbab25bd6f59450f95ac465c3ff3186c 100644 (file)
@@ -132,6 +132,14 @@ PHP_FUNCTION(http_request_method_name);
 PHP_FUNCTION(http_build_query);
 #endif /* ZEND_ENGINE_2 */
 PHP_FUNCTION(ob_etaghandler);
+#ifdef HTTP_HAVE_ZLIB
+PHP_FUNCTION(http_gzencode);
+PHP_FUNCTION(http_gzdecode);
+PHP_FUNCTION(http_deflate);
+PHP_FUNCTION(http_inflate);
+PHP_FUNCTION(http_compress);
+PHP_FUNCTION(http_uncompress);
+#endif
 
 PHP_MINIT_FUNCTION(http);
 PHP_MSHUTDOWN_FUNCTION(http);
index a6f19ebb53e58ab9c255bac4025c7c43e5ead217..c84331a2379361dfad6150c6c625aa97107cb8a3 100644 (file)
@@ -57,7 +57,11 @@ extern void _http_error_ex(long type TSRMLS_DC, long code, const char *format, .
                        http_error(HE_NOTICE, HTTP_E_MESSAGE_TYPE, "HttpMessage is not of type HTTP_MSG_REQUEST"); \
                        action; \
                }
-
+#define HTTP_CHECK_GZIP_LEVEL(level, action) \
+       if (level < -1 || level > 9) { \
+               http_error_ex(HE_WARNING, HTTP_E_INVALID_PARAM, "Invalid compression level (-1 to 9): %d", level); \
+               action; \
+       }
 
 #define http_log(f, i, m) _http_log_ex((f), (i), (m) TSRMLS_CC)
 extern void http_log_ex(char *file, const char *ident, const char *message TSRMLS_DC);
index d50850e71a17c3869821c70e4543b449c09d5580..ba711b8cb52583a6bbf1c9d3a8ef85ee8c066e87 100644 (file)
@@ -31,9 +31,15 @@ PHP_METHOD(HttpUtil, negotiateLanguage);
 PHP_METHOD(HttpUtil, negotiateCharset);
 PHP_METHOD(HttpUtil, matchModified);
 PHP_METHOD(HttpUtil, matchEtag);
-PHP_METHOD(HttpUtil, chunkedDecode);
 PHP_METHOD(HttpUtil, parseHeaders);
 PHP_METHOD(HttpUtil, parseMessage);
+PHP_METHOD(HttpUtil, chunkedDecode);
+PHP_METHOD(HttpUtil, gzEncode);
+PHP_METHOD(HttpUtil, gzDecode);
+PHP_METHOD(HttpUtil, deflate);
+PHP_METHOD(HttpUtil, inflate);
+PHP_METHOD(HttpUtil, compress);
+PHP_METHOD(HttpUtil, uncompress);
 
 #endif
 #endif
index 7a9f02725922bc79891da22eed47b3918fe42a1a..ea2cb5f8e7a28f6c742d18fc145d5d9108be6773 100644 (file)
@@ -42,4 +42,6 @@ object(stdClass)#%d (%d) {
 "
   ["parentMessage"]=>
   NULL
-}Done
+}
+Done
+