From: Michael Wallner Date: Mon, 21 Nov 2005 16:48:27 +0000 (+0000) Subject: - drop mhash support X-Git-Tag: RELEASE_0_19_0~9 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=0acbfc76b5a3e4122a6d06d64bd834a810806656 - drop mhash support --- diff --git a/config.m4 b/config.m4 index 9b6176f..1e8eff1 100644 --- a/config.m4 +++ b/config.m4 @@ -7,9 +7,6 @@ PHP_ARG_ENABLE([http], [whether to enable extended HTTP support], PHP_ARG_WITH([http-curl-requests], [whether to enable cURL HTTP requests], [ --with-http-curl-requests[=CURLDIR] With cURL HTTP request support]) -PHP_ARG_WITH([http-mhash-etags], [whether to enable mhash ETag generator], -[ --with-http-mhash-etags[=MHASHDIR] - With mhash ETag generator support]) PHP_ARG_WITH([http-magic-mime], [whether to enable response content type guessing], [ --with-http-magic-mime[=MAGICDIR] With magic mime response content type guessing]) @@ -133,31 +130,6 @@ dnl ---- ) fi -dnl ---- -dnl MHASH -dnl ---- - if test "$PHP_HTTP_MHASH_ETAGS" != "no"; then - - AC_MSG_CHECKING([for mhash.h]) - MHASH_DIR= - for i in "$PHP_HTTP_MHASH_ETAGS" /usr/local /usr /opt; do - if test -f "$i/include/mhash.h"; then - MHASH_DIR=$i - break - fi - done - if test -z "$MHASH_DIR"; then - AC_MSG_RESULT([not found]) - AC_MSG_ERROR([could not find mhash.h]) - else - AC_MSG_RESULT([found in $MHASH_DIR]) - fi - - PHP_ADD_INCLUDE($MHASH_DIR/include) - PHP_ADD_LIBRARY_WITH_PATH(mhash, $MHASH_DIR/$PHP_LIBDIR, HTTP_SHARED_LIBADD) - AC_DEFINE([HTTP_HAVE_MHASH], [1], [Have mhash support]) - fi - dnl ---- dnl MAGIC dnl ---- @@ -183,6 +155,12 @@ dnl ---- AC_DEFINE([HTTP_HAVE_MAGIC], [1], [Have magic mime support]) fi +dnl ---- +dnl HASH +dnl ---- + + dnl TODO + dnl ---- dnl DONE dnl ---- @@ -206,7 +184,7 @@ dnl ---- dnl outside src dir, adds install-http target PHP_ADD_MAKEFILE_FRAGMENT dnl within src dir, installs http headers - ifdef([PHP_INSTALL_HEADERS], [PHP_INSTALL_HEADERS(ext/http, $PHP_HTTP_HEADER_FILES)], [ ]) + ifdef([PHP_INSTALL_HEADERS], [PHP_INSTALL_HEADERS(ext/http, $PHP_HTTP_HEADERS)], [ ]) AC_DEFINE([HAVE_HTTP], [1], [Have extended HTTP support]) fi diff --git a/config.w32 b/config.w32 index af89ae7..a53455e 100644 --- a/config.w32 +++ b/config.w32 @@ -31,21 +31,19 @@ if (PHP_HTTP != "no") { } if (PHP_HASH != "no") { - if (glob(configure_module_dirname +"\\..\\hash\\php_hash_sha.h").length) { - ADD_FLAG("CFLAGS_HTTP", "/I"+ configure_module_dirname +"\\..\\hash"); - AC_DEFINE("HTTP_HAVE_HASH_EXT_INCLUDES", 1, ""); + var f; + STDOUT.Write("Checking for ext/hash ... "); + if (glob((f = configure_module_dirname +"\\..\\hash") +"\\php_hash.h").length || + glob((f = configure_module_dirname +"\\..\\..\\..\\pecl\\hash") +"\\php_hash.h").length) { + ADD_FLAG("CFLAGS_HTTP", "/I"+ f); + AC_DEFINE("HTTP_HAVE_EXT_HASH", 1, ""); + ADD_EXTENSION_DEP("http", "hash", true); + STDOUT.WriteLine(condense_path(f)); + } else { + STDOUT.WriteLine(""); } } - MHASH_LIB = PHP_DEBUG != "no" ? "libmhash-staticd.lib":"libmhash-static.lib"; - if (CHECK_HEADER_ADD_INCLUDE('mhash.h', 'CFLAGS_HTTP') && - (CHECK_LIB(MHASH_LIB, 'http', PHP_HTTP) || - CHECK_LIB('libmhash.lib', 'http', PHP_HTTP))) { - AC_DEFINE('HTTP_HAVE_MHASH', 1 , "Have mhash library"); - } else { - WARNING("mhash etag generator not enabled; libraries and headers not found"); - } - CURL_LIB = PHP_DEBUG != "no" ? "libcurld.lib":"libcurl.lib"; if (CHECK_HEADER_ADD_INCLUDE("curl/curl.h", "CFLAGS_HTTP") && CHECK_HEADER_ADD_INCLUDE("openssl/crypto.h", "CFLAGS_HTTP") && diff --git a/docs/functions.html b/docs/functions.html index e1329bb..b815071 100644 --- a/docs/functions.html +++ b/docs/functions.html @@ -113,6 +113,19 @@ if none match.

<?php
$charsets 
= array(
        
'iso-8859-1'// default
        
'iso-8859-2',
        
'iso-8859-15',
        
'utf-8'
);

$pref http_negotiate_charset($charsets$result);

if (
strcmp($pref'iso-8859-1')) {
        
iconv_set_encoding('internal_encoding''iso-8859-1');
        
iconv_set_encoding('output_encoding'$pref);
        
ob_start('ob_iconv_handler');
}

print_r($result);
?>

+

string http_negotiate_ctype(array supported[, array &result])

+

This function negotiates the clients preferred content type based on its
+Accept HTTP header. The qualifier is recognized and content types
+without qualifier are rated highest.

+

Expects an array as parameter cotaining the supported content types as values.
+If the optional second parameter is supplied, it will be filled with an
+array containing the negotiation results.

+

Returns the negotiated content type or the default content type
+(i.e. first array entry) if none match.

+

Example:


+<?php
$ctypes 
= array('application/xhtml+xml''text/html');
http_send_content_type(http_negotiate_content_type($ctypes));
?>
+

+

bool http_send_status(int status)

Send HTTP status code.

Expects an HTTP status code as parameter.

@@ -384,8 +397,6 @@ all supported features that depend on external libraries.

and SSL requests can be issued
  • HTTP_SUPPORT_ENCODINGS: whether ext/http was linked against zlib,
    and compressed HTTP responses can be decoded
    -
  • HTTP_SUPPORT_MHASHETAGS: whether ext/http was linked against libmhash,
    - and ETags can be generated with the available mhash algorithms
  • HTTP_SUPPORT_MAGICMIME: whether ext/http was linked against libmagic,
    and the HttpResponse::guessContentType() method is usable

    @@ -480,6 +491,15 @@ This provides limited functionality compared to HttpRequest and HttpResponse.

    Accepts a bool parameter which specifies whether the returned string
    should also contain any parent messages.

    Returns the full message as string.

    +

    int HttpMessage::count()

    +

    Implements Countable.

    +

    Returns the number of parent messages + 1.

    +

    string HttpMessage::serialize()

    +

    Implements Serializable.

    +

    Returns the serialized representation of the HttpMessage.

    +

    void HttpMessage::unserialize(string serialized)

    +

    Implements Serializable.

    +

    Re-constructs the HttpMessage based upon the serialized string.


    http_request_object.c

    HttpRequest

    @@ -697,6 +717,11 @@ cycle.

    references the last received response. Use HttpMessage::getParentMessage()
    to access the data of previously sent requests whithin this request
    cycle.

    +

    Note that the internal request message is immutable, that means that the
    +request message received through HttpRequest::getRequestMessage() will
    +always look the same for the same request, regardless of any changes you
    +may have made to the returned object.

    +

    Throws HttpMalformedHeadersException, HttpEncodingException.

    HttpMessage HttpRequest::getHistory()

    Get all sent requests and received responses as an HttpMessage object.

    If you don't want to record history at all, set the instance variable
    @@ -705,12 +730,18 @@ HttpRequest::$recoedHistory to FALSE.

    history.

    The object references the last received response, use HttpMessage::getParentMessage()
    to access the data of previously sent requests and received responses.

    -

    Throws HttpMalformedHeaderException.

    +

    Note that the internal history is immutable, that means that any changes
    +you make the the message list won't affect a history message list newly
    +created by another call to HttpRequest::getHistory().

    +

    Throws HttpMalformedHeaderException, HttpEncodingException.

    void HttpRequest::clearHistory()

    Clear the history.

    HttpMessage HttpRequest::send()

    Send the HTTP request.

    Returns the received response as HttpMessage object.

    +

    NOTE: While an exception may be thrown, the transfer could have succeeded
    +at least partially, so you might want to check the return values of various
    +HttpRequest::getResponse*() methods.

    Throws HttpRuntimeException, HttpRequestException,
    HttpMalformedHeaderException, HttpEncodingException.

    GET example:


    @@ -778,6 +809,9 @@ HttpRequestPoolException, HttpMalformedHeaderException.

    Implements Iterator::next().

    void HttpRequestPool::rewind()

    Implements Iterator::rewind().

    +

    int HttpRequestPool::count()

    +

    Implements Countable.

    +

    Returns the number of attached HttpRequest objects.

    array HttpRequestPool::getAttachedRequests()

    Get attached HttpRequest objects.

    Returns an array containing all currently attached HttpRequest objects.

    @@ -953,6 +987,8 @@ http.cache_log is set.

  • http_negotiate_charset
  • +
  • http_negotiate_content_type +
  • http_send_status
  • http_send_last_modified @@ -1053,6 +1089,9 @@ http.cache_log is set.

  • HttpMessage::getParentMessage()
  • HttpMessage::send()
  • HttpMessage::toString()
  • +
  • HttpMessage::count()
  • +
  • HttpMessage::serialize()
  • +
  • HttpMessage::unserialize()
  • @@ -1120,6 +1159,7 @@ http.cache_log is set.

  • HttpRequestPool::key()
  • HttpRequestPool::next()
  • HttpRequestPool::rewind()
  • +
  • HttpRequestPool::count()
  • HttpRequestPool::getAttachedRequests()
  • HttpRequestPool::getFinishedRequests()
  • @@ -1161,7 +1201,7 @@ http.cache_log is set.

    -

    Generated at: Fri, 04 Nov 2005 12:29:06 +0100

    +

    Generated at: Mon, 21 Nov 2005 16:56:18 +0100

    diff --git a/docs/http.ini b/docs/http.ini index 372c1f3..11e8189 100644 --- a/docs/http.ini +++ b/docs/http.ini @@ -8,11 +8,10 @@ ; disable if you want php not to exit in case of redirects and cache hits ;http.force_exit = 0 -; the hashing algorithm with wich ETags are generated -; you can use mhash constants if ext/mhash is enabled, or their -; literal representation if ext/http was linked against libmhash -;http.etag_mode = HTTP_ETAG_MHASH_TIGER ; same as 7 -http.etag_mode = HTTP_ETAG_MD5 +; the hashing algorithm with wich ETags are generated (MD5, SHA1, CRC32B) +; if ext/hash is available, this can be set to any hash algorithm ext/hash supports +; MD5 is the default and fallback algorithm +http.etag_mode = "MD5" ; allowed request methods ; by default PHP ignores unkown request methods diff --git a/http.c b/http.c index ffbae18..1c4a6a4 100644 --- a/http.c +++ b/http.c @@ -58,9 +58,6 @@ # endif # include #endif -#ifdef HTTP_HAVE_MHASH -# include -#endif #ifdef HTTP_HAVE_ZLIB # include #endif @@ -218,56 +215,6 @@ PHP_INI_MH(http_update_allowed_methods) return OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); } -#undef CASE_HTTP_ETAG_HASH -#define CASE_HTTP_ETAG_HASH(HASH) \ - case HTTP_ETAG_##HASH: \ - ZEND_WRITE("HTTP_ETAG_"#HASH, lenof("HTTP_ETAG_"#HASH)); \ - break; -PHP_INI_DISP(http_etag_mode_displayer) -{ - long value; - - if (type == ZEND_INI_DISPLAY_ORIG && ini_entry->modified) { - value = (ini_entry->orig_value) ? atoi(ini_entry->orig_value) : HTTP_ETAG_MD5; - } else if (ini_entry->value) { - value = (ini_entry->value[0]) ? atoi(ini_entry->value) : HTTP_ETAG_MD5; - } else { - value = HTTP_ETAG_MD5; - } - - switch (value) - { -#ifdef HTTP_HAVE_HASH_EXT - CASE_HTTP_ETAG_HASH(RIPEMD160); - CASE_HTTP_ETAG_HASH(RIPEMD128); - CASE_HTTP_ETAG_HASH(SHA512); - CASE_HTTP_ETAG_HASH(SHA384); - CASE_HTTP_ETAG_HASH(SHA256); -#endif - CASE_HTTP_ETAG_HASH(CRC32); - CASE_HTTP_ETAG_HASH(SHA1); -#ifndef HTTP_HAVE_MHASH - default: -#endif - CASE_HTTP_ETAG_HASH(MD5); - -#ifdef HTTP_HAVE_MHASH - default: - { - const char *hash_name = mhash_get_hash_name_static(value); - - if (!hash_name) { - ZEND_WRITE("HTTP_ETAG_MD5", lenof("HTTP_ETAG_MD5")); - } else { - ZEND_WRITE("HTTP_ETAG_MHASH_", lenof("HTTP_ETAG_MHASH_")); - ZEND_WRITE(hash_name, strlen(hash_name)); - } - } - break; -#endif - } -} - #ifndef ZEND_ENGINE_2 # define OnUpdateLong OnUpdateInt #endif @@ -278,7 +225,7 @@ PHP_INI_BEGIN() HTTP_PHP_INI_ENTRY("http.redirect_log", "", PHP_INI_ALL, OnUpdateString, log.redirect) HTTP_PHP_INI_ENTRY("http.allowed_methods_log", "", PHP_INI_ALL, OnUpdateString, log.allowed_methods) HTTP_PHP_INI_ENTRY("http.composite_log", "", PHP_INI_ALL, OnUpdateString, log.composite) - HTTP_PHP_INI_ENTRY_EX("http.etag_mode", "-2", PHP_INI_ALL, OnUpdateLong, http_etag_mode_displayer, etag.mode) + HTTP_PHP_INI_ENTRY("http.etag_mode", "MD5", PHP_INI_ALL, OnUpdateString, etag.mode) #ifdef ZEND_ENGINE_2 HTTP_PHP_INI_ENTRY("http.only_exceptions", "0", PHP_INI_ALL, OnUpdateBool, only_exceptions) #endif @@ -297,7 +244,6 @@ PHP_MINIT_FUNCTION(http) if ( (SUCCESS != PHP_MINIT_CALL(http_support)) || (SUCCESS != PHP_MINIT_CALL(http_headers)) || - (SUCCESS != PHP_MINIT_CALL(http_cache)) || #ifdef HTTP_HAVE_CURL (SUCCESS != PHP_MINIT_CALL(http_request)) || #endif /* HTTP_HAVE_CURL */ @@ -386,16 +332,6 @@ PHP_MINFO_FUNCTION(http) #else php_info_print_table_row(2, "zlib GZIP Encodings", "disabled"); #endif -#ifdef HTTP_HAVE_MHASH - { - char mhash_info[32]; - - snprintf(mhash_info, 32, "libmhash/%d", MHASH_API_VERSION); - php_info_print_table_row(2, "mhash ETag Generator", mhash_info); - } -#else - php_info_print_table_row(2, "mhash ETag Generator", "disabled"); -#endif #if defined(HTTP_HAVE_MAGIC) && !defined(WONKY) php_info_print_table_row(2, "magic MIME Guessing", "libmagic/unknown"); #else @@ -419,37 +355,6 @@ PHP_MINFO_FUNCTION(http) } php_info_print_table_end(); - php_info_print_table_start(); - php_info_print_table_colspan_header(2, "Supported ETag Hash Algorithms"); - { - - php_info_print_table_row(2, "PHP", "CRC32, MD5, SHA1" -#ifdef HTTP_HAVE_HASH_EXT - ", SHA256, SHA384, SHA512, RIPEMD128, RIPEMD160" -#endif - ); -#ifdef HTTP_HAVE_MHASH - { - phpstr *algos = phpstr_new(); - int i, c = mhash_count(); - - for (i = 0; i <= c; ++i) { - const char *hash = mhash_get_hash_name_static(i); - - if (hash) { - phpstr_appendf(algos, "%s, ", hash); - } - } - phpstr_fix(algos); - php_info_print_table_row(2, "MHASH", PHPSTR_VAL(algos)); - phpstr_free(&algos); - } -#else - php_info_print_table_row(2, "MHASH", "not available"); -#endif - } - php_info_print_table_end(); - php_info_print_table_start(); php_info_print_table_colspan_header(2, "Request Methods"); { diff --git a/http.dsp b/http.dsp index e752a92..c52aec8 100644 --- a/http.dsp +++ b/http.dsp @@ -54,7 +54,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 -# ADD LINK32 libmhash.lib libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_http.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" +# ADD LINK32 libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Release_TS/php_http.dll" /libpath:"..\..\Release_TS" /libpath:"..\..\Release_TS_Inline" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" !ELSEIF "$(CFG)" == "http - Win32 Debug_TS" @@ -81,7 +81,7 @@ BSC32=bscmake.exe # ADD BSC32 /nologo LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts.lib /nologo /dll /machine:I386 -# ADD LINK32 libmhash.lib libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/http.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" +# ADD LINK32 libcurl.lib ssleay32.lib libeay32.lib zlib.lib winmm.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib php4ts_debug.lib wsock32.lib /nologo /dll /machine:I386 /out:"..\..\Debug_TS/http.dll" /libpath:"..\..\Debug_TS" /libpath:"..\..\..\php_build\curl\lib" /libpath:"..\..\..\php4\Release_TS" /libpath:"..\..\..\php4\Release_TS_Inline" !ENDIF diff --git a/http_api.c b/http_api.c index 2be27d0..a392801 100644 --- a/http_api.c +++ b/http_api.c @@ -50,7 +50,6 @@ PHP_MINIT_FUNCTION(http_support) HTTP_LONG_CONSTANT("HTTP_SUPPORT_REQUESTS", HTTP_SUPPORT_REQUESTS); HTTP_LONG_CONSTANT("HTTP_SUPPORT_MAGICMIME", HTTP_SUPPORT_MAGICMIME); HTTP_LONG_CONSTANT("HTTP_SUPPORT_ENCODINGS", HTTP_SUPPORT_ENCODINGS); - HTTP_LONG_CONSTANT("HTTP_SUPPORT_MHASHETAGS", HTTP_SUPPORT_MHASHETAGS); HTTP_LONG_CONSTANT("HTTP_SUPPORT_SSLREQUESTS", HTTP_SUPPORT_SSLREQUESTS); return SUCCESS; @@ -66,9 +65,6 @@ PHP_HTTP_API long _http_support(long feature) support |= HTTP_SUPPORT_SSLREQUESTS; # endif #endif -#ifdef HTTP_HAVE_MHASH - support |= HTTP_SUPPORT_MHASHETAGS; -#endif #ifdef HTTP_HAVE_MAGIC support |= HTTP_SUPPORT_MAGICMIME; #endif diff --git a/http_cache_api.c b/http_cache_api.c index 963bb7e..dab5552 100644 --- a/http_cache_api.c +++ b/http_cache_api.c @@ -20,8 +20,6 @@ #include "SAPI.h" #include "php_streams.h" #include "php_output.h" -#include "ext/standard/md5.h" -#include "ext/standard/sha1.h" #include "php_http.h" #include "php_http_std_defs.h" @@ -30,45 +28,8 @@ #include "php_http_send_api.h" #include "php_http_date_api.h" -#ifdef HTTP_HAVE_MHASH -# include -#endif - ZEND_EXTERN_MODULE_GLOBALS(http); -PHP_MINIT_FUNCTION(http_cache) -{ - HTTP_LONG_CONSTANT("HTTP_ETAG_MD5", HTTP_ETAG_MD5); - HTTP_LONG_CONSTANT("HTTP_ETAG_SHA1", HTTP_ETAG_SHA1); - HTTP_LONG_CONSTANT("HTTP_ETAG_CRC32", HTTP_ETAG_CRC32); - -#ifdef HTTP_HAVE_HASH_EXT - HTTP_LONG_CONSTANT("HTTP_ETAG_SHA256", HTTP_ETAG_SHA256); - HTTP_LONG_CONSTANT("HTTP_ETAG_SHA384", HTTP_ETAG_SHA384); - HTTP_LONG_CONSTANT("HTTP_ETAG_SHA512", HTTP_ETAG_SHA512); - HTTP_LONG_CONSTANT("HTTP_ETAG_RIPEMD128", HTTP_ETAG_RIPEMD128); - HTTP_LONG_CONSTANT("HTTP_ETAG_RIPEMD160", HTTP_ETAG_RIPEMD160); -#endif - -#ifdef HTTP_HAVE_MHASH - { - int l, i, c = mhash_count(); - - for (i = 0; i <= c; ++i) { - char const_name[256] = {0}; - const char *hash_name = mhash_get_hash_name_static(i); - - if (hash_name) { - l = snprintf(const_name, 255, "HTTP_ETAG_MHASH_%s", hash_name); - zend_register_long_constant(const_name, l + 1, i, CONST_CS|CONST_PERSISTENT, module_number TSRMLS_CC); - } - } - } -#endif - - return SUCCESS; -} - /* {{{ char *http_etag(void *, size_t, http_send_mode) */ PHP_HTTP_API char *_http_etag(const void *data_ptr, size_t data_len, http_send_mode data_mode TSRMLS_DC) { @@ -87,7 +48,7 @@ PHP_HTTP_API char *_http_etag(const void *data_ptr, size_t data_len, http_send_m } if (SUCCESS != ss) { - http_etag_free(&ctx); + efree(ctx); return NULL; } else { size_t ssb_len; @@ -100,7 +61,7 @@ PHP_HTTP_API char *_http_etag(const void *data_ptr, size_t data_len, http_send_m } } - return http_etag_finish(&ctx); + return http_etag_finish(ctx); } /* }}} */ @@ -237,7 +198,10 @@ PHP_HTTP_API zend_bool _http_interrupt_ob_etaghandler(TSRMLS_D) { if (HTTP_G(etag).started) { HTTP_G(etag).started = 0; - http_etag_free(&HTTP_G(etag).ctx); + if (HTTP_G(etag).ctx) { + efree(HTTP_G(etag).ctx); + HTTP_G(etag).ctx = NULL; + } return 1; } return 0; @@ -264,7 +228,9 @@ void _http_ob_etaghandler(char *output, uint output_len, /* finish */ if (mode & PHP_OUTPUT_HANDLER_END) { char *sent_header = NULL; - char *etag = http_etag_finish(&HTTP_G(etag).ctx); + char *etag = http_etag_finish(HTTP_G(etag).ctx); + + HTTP_G(etag).ctx = NULL; http_send_cache_control(HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL)); http_send_etag_ex(etag, strlen(etag), &sent_header); diff --git a/http_functions.c b/http_functions.c index e731d9a..aa49518 100644 --- a/http_functions.c +++ b/http_functions.c @@ -1649,8 +1649,6 @@ PHP_FUNCTION(http_uncompress) * and SSL requests can be issued *
  • HTTP_SUPPORT_ENCODINGS: whether ext/http was linked against zlib, * and compressed HTTP responses can be decoded - *
  • HTTP_SUPPORT_MHASHETAGS: whether ext/http was linked against libmhash, - * and ETags can be generated with the available mhash algorithms *
  • HTTP_SUPPORT_MAGICMIME: whether ext/http was linked against libmagic, * and the HttpResponse::guessContentType() method is usable * diff --git a/http_response_object.c b/http_response_object.c index 544b603..0d6cfa7 100644 --- a/http_response_object.c +++ b/http_response_object.c @@ -35,9 +35,6 @@ #include "php_http_cache_api.h" #include "php_http_headers_api.h" -#ifdef HTTP_HAVE_MHASH -# include -#endif #ifdef HTTP_HAVE_MAGIC # include #endif @@ -243,34 +240,6 @@ static inline void _http_response_object_declare_default_properties(TSRMLS_D) DCL_CONST(long, "REDIRECT_PERM", HTTP_REDIRECT_PERM); DCL_CONST(long, "REDIRECT_POST", HTTP_REDIRECT_POST); DCL_CONST(long, "REDIRECT_TEMP", HTTP_REDIRECT_TEMP); - - DCL_CONST(long, "ETAG_MD5", HTTP_ETAG_MD5); - DCL_CONST(long, "ETAG_SHA1", HTTP_ETAG_SHA1); - DCL_CONST(long, "ETAG_CRC32", HTTP_ETAG_CRC32); - -# ifdef HTTP_HAVE_HASH_EXT - DCL_CONST(long, "ETAG_SHA256", HTTP_ETAG_SHA256); - DCL_CONST(long, "ETAG_SHA384", HTTP_ETAG_SHA384); - DCL_CONST(long, "ETAG_SHA512", HTTP_ETAG_SHA512); - DCL_CONST(long, "ETAG_RIPEMD128", HTTP_ETAG_RIPEMD128); - DCL_CONST(long, "ETAG_RIPEMD160", HTTP_ETAG_RIPEMD160); -# endif - -# ifdef HTTP_HAVE_MHASH - { - int l, i, c = mhash_count(); - - for (i = 0; i <= c; ++i) { - char const_name[256] = {0}; - const char *hash_name = mhash_get_hash_name_static(i); - - if (hash_name) { - l = snprintf(const_name, 255, "ETAG_MHASH_%s", hash_name); - zend_declare_class_constant_long(ce, const_name, l, i TSRMLS_CC); - } - } - } -# endif /* HTTP_HAVE_MHASH */ #endif /* WONKY */ } diff --git a/package2.xml b/package2.xml index 316ac11..3e18b15 100644 --- a/package2.xml +++ b/package2.xml @@ -41,6 +41,8 @@ @@ -146,7 +148,6 @@ - @@ -238,11 +239,6 @@ prompt="whether to enable cURL HTTP requests; specify libcurl directory" default="yes" /> - #endif ZEND_EXTERN_MODULE_GLOBALS(http); -typedef enum { -#ifdef HTTP_HAVE_HASH_EXT - HTTP_ETAG_RIPEMD160 = -8, - HTTP_ETAG_RIPEMD128 = -7, - HTTP_ETAG_SHA512 = -6, - HTTP_ETAG_SHA384 = -5, - HTTP_ETAG_SHA256 = -4, -#endif - HTTP_ETAG_CRC32 = -3, - HTTP_ETAG_MD5 = -2, - HTTP_ETAG_SHA1 = -1, -} http_etag_mode; - -extern PHP_MINIT_FUNCTION(http_cache); - -#ifdef HTTP_HAVE_MHASH -static void *http_etag_alloc_mhash_digest(size_t size) -{ - return emalloc(size); -} -#endif - -#define http_etag_digest(d, l) _http_etag_digest((d), (l) TSRMLS_CC) -static inline char *_http_etag_digest(const unsigned char *digest, int len TSRMLS_DC) +#define http_etag_digest(d, l) _http_etag_digest((d), (l)) +static inline char *_http_etag_digest(const unsigned char *digest, int len) { static const char hexdigits[16] = "0123456789abcdef"; int i; @@ -78,184 +49,83 @@ static inline char *_http_etag_digest(const unsigned char *digest, int len TSRML return hex; } -#undef CASE_HTTP_ETAG_HASH -#define CASE_HTTP_ETAG_HASH(HASH) \ - case HTTP_ETAG_##HASH: \ - PHP_##HASH##Init(ctx = emalloc(sizeof(PHP_##HASH##_CTX))); \ - break; #define http_etag_init() _http_etag_init(TSRMLS_C) static inline void *_http_etag_init(TSRMLS_D) { void *ctx = NULL; - long mode = HTTP_G(etag).mode; - - switch (mode) - { - case HTTP_ETAG_CRC32: - ctx = emalloc(sizeof(uint)); - *((uint *) ctx) = ~0; - break; - -#ifdef HTTP_HAVE_HASH_EXT - CASE_HTTP_ETAG_HASH(RIPEMD160); - CASE_HTTP_ETAG_HASH(RIPEMD128); - CASE_HTTP_ETAG_HASH(SHA512); - CASE_HTTP_ETAG_HASH(SHA384); - CASE_HTTP_ETAG_HASH(SHA256); -#endif - CASE_HTTP_ETAG_HASH(SHA1); -#ifndef HTTP_HAVE_MHASH - default: -#endif - CASE_HTTP_ETAG_HASH(MD5); - -#ifdef HTTP_HAVE_MHASH - default: - if ((mode < 0) || ((ulong)mode > mhash_count()) || (!(ctx = mhash_init(mode)))) { - http_error_ex(HE_ERROR, HTTP_E_RUNTIME, "Invalid ETag mode: %ld", mode); - } - break; -#endif + char *mode = HTTP_G(etag).mode; + +#ifdef HTTP_HAVE_EXT_HASH + php_hash_ops *eho = NULL; + + if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) { + ctx = emalloc(eho->context_size); + eho->hash_init(ctx); + } else +#endif + if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) { + ctx = emalloc(sizeof(uint)); + *((uint *) ctx) = ~0; + } else if (mode && !strcasecmp(mode, "sha1")) { + PHP_SHA1Init(ctx = emalloc(sizeof(PHP_SHA1_CTX))); + } else { + PHP_MD5Init(ctx = emalloc(sizeof(PHP_MD5_CTX))); } return ctx; } -#undef CASE_HTTP_ETAG_HASH -#define CASE_HTTP_ETAG_HASH(HASH) \ - case HTTP_ETAG_##HASH: \ - if (*((PHP_##HASH##_CTX **) ctx_ptr)) { \ - efree(*((PHP_##HASH##_CTX **) ctx_ptr)); \ - *((PHP_##HASH##_CTX **) ctx_ptr) = NULL; \ - } \ - break; -#define http_etag_free(cp) _http_etag_free((cp) TSRMLS_CC) -static inline void _http_etag_free(void **ctx_ptr TSRMLS_DC) -{ - switch (HTTP_G(etag).mode) - { - case HTTP_ETAG_CRC32: - if (*((uint **) ctx_ptr)) { - efree(*((uint **) ctx_ptr)); - *((uint **) ctx_ptr) = NULL; - } - break; - -#ifdef HTTP_HAVE_HASH_EXT - CASE_HTTP_ETAG_HASH(RIPEMD160); - CASE_HTTP_ETAG_HASH(RIPEMD128); - CASE_HTTP_ETAG_HASH(SHA512); - CASE_HTTP_ETAG_HASH(SHA384); - CASE_HTTP_ETAG_HASH(SHA256); -#endif - CASE_HTTP_ETAG_HASH(SHA1); -#ifndef HTTP_HAVE_MHASH - default: -#endif - CASE_HTTP_ETAG_HASH(MD5); - -#ifdef HTTP_HAVE_MHASH - default: - /* mhash gets already freed in http_etag_finish() */ - if (*((MHASH *) ctx_ptr)) { - mhash_deinit(*((MHASH *) ctx_ptr), NULL); - *((MHASH *) ctx_ptr) = NULL; - } - break; -#endif - } -} - -#undef CASE_HTTP_ETAG_HASH -#define CASE_HTTP_ETAG_HASH(HASH, len) \ - case HTTP_ETAG_##HASH##: \ - PHP_##HASH##Final(digest, *((PHP_##HASH##_CTX **) ctx_ptr)); \ - etag = http_etag_digest(digest, len); \ - break; #define http_etag_finish(c) _http_etag_finish((c) TSRMLS_CC) -static inline char *_http_etag_finish(void **ctx_ptr TSRMLS_DC) +static inline char *_http_etag_finish(void *ctx TSRMLS_DC) { + unsigned char digest[128] = {0}; char *etag = NULL; - unsigned char digest[128]; - long mode = HTTP_G(etag).mode; - switch (mode) - { - case HTTP_ETAG_CRC32: - **((uint **) ctx_ptr) = ~**((uint **) ctx_ptr); - etag = http_etag_digest(*((const unsigned char **) ctx_ptr), sizeof(uint)); - break; - -#ifdef HTTP_HAVE_HASH_EXT - CASE_HTTP_ETAG_HASH(RIPEMD160, 20); - CASE_HTTP_ETAG_HASH(RIPEMD128, 16); - CASE_HTTP_ETAG_HASH(SHA512, 64); - CASE_HTTP_ETAG_HASH(SHA384, 48); - CASE_HTTP_ETAG_HASH(SHA256, 32); -#endif - CASE_HTTP_ETAG_HASH(SHA1, 20); -#ifndef HTTP_HAVE_MHASH - default: -#endif - CASE_HTTP_ETAG_HASH(MD5, 16); - -#ifdef HTTP_HAVE_MHASH - default: - { - unsigned char *mhash_digest = mhash_end_m(*((MHASH *) ctx_ptr), http_etag_alloc_mhash_digest); - etag = http_etag_digest(mhash_digest, mhash_get_block_size(mode)); - efree(mhash_digest); - /* avoid double free */ - *((MHASH *) ctx_ptr) = NULL; - } - break; -#endif - } +#ifdef HTTP_HAVE_EXT_HASH + php_hash_ops *eho = NULL; + char *mode = HTTP_G(etag).mode; - http_etag_free(ctx_ptr); + if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) { + eho->hash_final(digest, ctx); + etag = http_etag_digest(digest, eho->digest_size); + } else +#endif + if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) { + *((uint *) ctx) = ~*((uint *) ctx); + etag = http_etag_digest((const unsigned char *) ctx, sizeof(uint)); + } else if (mode && (!strcasecmp(mode, "sha1"))) { + PHP_SHA1Final(digest, ctx); + etag = http_etag_digest(digest, 20); + } else { + PHP_MD5Final(digest, ctx); + etag = http_etag_digest(digest, 16); + } + efree(ctx); return etag; } -#undef CASE_HTTP_ETAG_HASH -#define CASE_HTTP_ETAG_HASH(HASH) \ - case HTTP_ETAG_##HASH: \ - PHP_##HASH##Update(ctx, (const unsigned char *) data_ptr, data_len); \ - break; #define http_etag_update(c, d, l) _http_etag_update((c), (d), (l) TSRMLS_CC) static inline void _http_etag_update(void *ctx, const char *data_ptr, size_t data_len TSRMLS_DC) { - switch (HTTP_G(etag).mode) - { - case HTTP_ETAG_CRC32: - { - uint i, c = *((uint *) ctx); - - for (i = 0; i < data_len; ++i) { - c = CRC32(c, data_ptr[i]); - } - *((uint *)ctx) = c; +#ifdef HTTP_HAVE_EXT_HASH + php_hash_ops *eho = NULL; + char *mode = HTTP_G(etag).mode; + + if (mode && (eho = php_hash_fetch_ops(mode, strlen(mode)))) { + eho->hash_update(ctx, (const unsigned char *) data_ptr, data_len); + } else +#endif + if (mode && ((!strcasecmp(mode, "crc32")) || (!strcasecmp(mode, "crc32b")))) { + uint i, c = *((uint *) ctx); + for (i = 0; i < data_len; ++i) { + c = CRC32(c, data_ptr[i]); } - break; - -#ifdef HTTP_HAVE_HASH_EXT - CASE_HTTP_ETAG_HASH(RIPEMD160); - CASE_HTTP_ETAG_HASH(RIPEMD128); - CASE_HTTP_ETAG_HASH(SHA512); - CASE_HTTP_ETAG_HASH(SHA384); - CASE_HTTP_ETAG_HASH(SHA256); -#endif - CASE_HTTP_ETAG_HASH(SHA1); -#ifndef HTTP_HAVE_MHASH - default: -#endif - CASE_HTTP_ETAG_HASH(MD5); - -#ifdef HTTP_HAVE_MHASH - default: - mhash(ctx, data_ptr, data_len); - break; -#endif + *((uint *)ctx) = c; + } else if (mode && (!strcasecmp(mode, "sha1"))) { + PHP_SHA1Update(ctx, (const unsigned char *) data_ptr, data_len); + } else { + PHP_MD5Update(ctx, (const unsigned char *) data_ptr, data_len); } } diff --git a/tests/etag_mode_001.phpt b/tests/etag_mode_001.phpt index 8c396fb..787100b 100644 --- a/tests/etag_mode_001.phpt +++ b/tests/etag_mode_001.phpt @@ -8,7 +8,7 @@ checkmax(5.0); ?> --FILE-- diff --git a/tests/etag_mode_002.phpt b/tests/etag_mode_002.phpt index e0d809d..5ca8d8f 100644 --- a/tests/etag_mode_002.phpt +++ b/tests/etag_mode_002.phpt @@ -8,7 +8,7 @@ checkmax(5.0); ?> --FILE-- diff --git a/tests/etag_mode_003.phpt b/tests/etag_mode_003.phpt index 1e7789c..0b98f9f 100644 --- a/tests/etag_mode_003.phpt +++ b/tests/etag_mode_003.phpt @@ -8,7 +8,7 @@ checkmax(5.0); ?> --FILE-- diff --git a/tests/etag_mode_004.phpt b/tests/etag_mode_004.phpt index b8bb04d..cd56bae 100644 --- a/tests/etag_mode_004.phpt +++ b/tests/etag_mode_004.phpt @@ -1,16 +1,15 @@ --TEST-- -mhash etag +ext/hash etag --SKIPIF-- --FILE-- @@ -19,7 +18,7 @@ Content-type: %s X-Powered-By: PHP/%s Cache-Control: private, must-revalidate, max-age=0 Accept-Ranges: bytes -ETag: "53efa9e423f86dabd449b3e23dd0350def661b9e7055b23ceb2230c8b61bc0766514957ea9d349a88ef794715a1a17a409b549edfd6f43d696e63407fff3541c" +ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" Content-Length: 4 abc diff --git a/tests/etag_mode_005.phpt b/tests/etag_mode_005.phpt deleted file mode 100644 index cb15962..0000000 --- a/tests/etag_mode_005.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -ext/hash etag ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Content-type: %s -X-Powered-By: PHP/%s -Cache-Control: private, must-revalidate, max-age=0 -Accept-Ranges: bytes -ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" -Content-Length: 4 - -abc diff --git a/tests/etag_mode_011.phpt b/tests/etag_mode_011.phpt index d4a2712..5f9668e 100644 --- a/tests/etag_mode_011.phpt +++ b/tests/etag_mode_011.phpt @@ -8,7 +8,7 @@ checkmax(5.0); ?> --FILE-- diff --git a/tests/etag_mode_012.phpt b/tests/etag_mode_012.phpt index 72901e4..5a8702e 100644 --- a/tests/etag_mode_012.phpt +++ b/tests/etag_mode_012.phpt @@ -5,11 +5,10 @@ ob sha1 etag include 'skip.inc'; checkcgi(); checkmax(5.0); -skipif(!http_support(HTTP_SUPPORT_MHASHETAGS), 'need mhash support'); ?> --FILE-- diff --git a/tests/etag_mode_013.phpt b/tests/etag_mode_013.phpt index d81ba60..919d34e 100644 --- a/tests/etag_mode_013.phpt +++ b/tests/etag_mode_013.phpt @@ -8,7 +8,7 @@ checkmax(5.0); ?> --FILE-- diff --git a/tests/etag_mode_014.phpt b/tests/etag_mode_014.phpt index 29be1de..c6f1731 100644 --- a/tests/etag_mode_014.phpt +++ b/tests/etag_mode_014.phpt @@ -1,16 +1,15 @@ --TEST-- -ob mhash etag +ob ext/hash etag --SKIPIF-- --FILE-- @@ -18,6 +17,6 @@ print("abc\n"); Content-type: %s X-Powered-By: PHP/%s Cache-Control: private, must-revalidate, max-age=0 -ETag: "53efa9e423f86dabd449b3e23dd0350def661b9e7055b23ceb2230c8b61bc0766514957ea9d349a88ef794715a1a17a409b549edfd6f43d696e63407fff3541c" +ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" abc diff --git a/tests/etag_mode_015.phpt b/tests/etag_mode_015.phpt deleted file mode 100644 index d156bb9..0000000 --- a/tests/etag_mode_015.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -ob ext/hash etag ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Content-type: %s -X-Powered-By: PHP/%s -Cache-Control: private, must-revalidate, max-age=0 -ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" - -abc diff --git a/tests/etag_mode_031.phpt b/tests/etag_mode_031.phpt index 1ac27e2..29a7080 100644 --- a/tests/etag_mode_031.phpt +++ b/tests/etag_mode_031.phpt @@ -8,7 +8,7 @@ checkmin(5.1); ?> --FILE-- diff --git a/tests/etag_mode_032.phpt b/tests/etag_mode_032.phpt index 3806381..71ae9d3 100644 --- a/tests/etag_mode_032.phpt +++ b/tests/etag_mode_032.phpt @@ -8,7 +8,7 @@ checkmin(5.1); ?> --FILE-- diff --git a/tests/etag_mode_033.phpt b/tests/etag_mode_033.phpt index f87f3fa..f72b524 100644 --- a/tests/etag_mode_033.phpt +++ b/tests/etag_mode_033.phpt @@ -8,7 +8,7 @@ checkmin(5.1); ?> --FILE-- diff --git a/tests/etag_mode_034.phpt b/tests/etag_mode_034.phpt index b8bb04d..f0930ad 100644 --- a/tests/etag_mode_034.phpt +++ b/tests/etag_mode_034.phpt @@ -1,16 +1,15 @@ --TEST-- -mhash etag +ext/hash etag --SKIPIF-- --FILE-- @@ -19,7 +18,7 @@ Content-type: %s X-Powered-By: PHP/%s Cache-Control: private, must-revalidate, max-age=0 Accept-Ranges: bytes -ETag: "53efa9e423f86dabd449b3e23dd0350def661b9e7055b23ceb2230c8b61bc0766514957ea9d349a88ef794715a1a17a409b549edfd6f43d696e63407fff3541c" +ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" Content-Length: 4 abc diff --git a/tests/etag_mode_035.phpt b/tests/etag_mode_035.phpt deleted file mode 100644 index 1cd9430..0000000 --- a/tests/etag_mode_035.phpt +++ /dev/null @@ -1,24 +0,0 @@ ---TEST-- -ext/hash etag ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -X-Powered-By: PHP/%s -Cache-Control: private, must-revalidate, max-age=0 -Accept-Ranges: bytes -ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" -Content-Length: 4 -Content-type: %s - -abc diff --git a/tests/etag_mode_041.phpt b/tests/etag_mode_041.phpt index 3e15bc1..1a6a2ff 100644 --- a/tests/etag_mode_041.phpt +++ b/tests/etag_mode_041.phpt @@ -8,7 +8,7 @@ checkmin(5.1); ?> --FILE-- diff --git a/tests/etag_mode_042.phpt b/tests/etag_mode_042.phpt index 68aab73..5c77db4 100644 --- a/tests/etag_mode_042.phpt +++ b/tests/etag_mode_042.phpt @@ -5,11 +5,10 @@ ob sha1 etag include 'skip.inc'; checkcgi(); checkmin(5.1); -skipif(!http_support(HTTP_SUPPORT_MHASHETAGS), 'need mhash support'); ?> --FILE-- diff --git a/tests/etag_mode_043.phpt b/tests/etag_mode_043.phpt index 251381b..dbb5438 100644 --- a/tests/etag_mode_043.phpt +++ b/tests/etag_mode_043.phpt @@ -8,7 +8,7 @@ checkmin(5.1); ?> --FILE-- diff --git a/tests/etag_mode_044.phpt b/tests/etag_mode_044.phpt index c7c3e10..5f69d4b 100644 --- a/tests/etag_mode_044.phpt +++ b/tests/etag_mode_044.phpt @@ -1,23 +1,22 @@ --TEST-- -ob mhash etag +ob ext/hash etag --SKIPIF-- --FILE-- --EXPECTF-- X-Powered-By: PHP/%s Cache-Control: private, must-revalidate, max-age=0 -ETag: "53efa9e423f86dabd449b3e23dd0350def661b9e7055b23ceb2230c8b61bc0766514957ea9d349a88ef794715a1a17a409b549edfd6f43d696e63407fff3541c" +ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" Content-type: %s abc diff --git a/tests/etag_mode_045.phpt b/tests/etag_mode_045.phpt deleted file mode 100644 index b4c5dd6..0000000 --- a/tests/etag_mode_045.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -ob ext/hash etag ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -X-Powered-By: PHP/%s -Cache-Control: private, must-revalidate, max-age=0 -ETag: "edeaaff3f1774ad2888673770c6d64097e391bc362d7d6fb34982ddf0efd18cb" -Content-type: %s - -abc diff --git a/tests/etag_mode_crc.phpt b/tests/etag_mode_crc.phpt deleted file mode 100644 index 62fbb3f..0000000 --- a/tests/etag_mode_crc.phpt +++ /dev/null @@ -1,40 +0,0 @@ ---TEST-- -sane crc etags ---SKIPIF-- - ---FILE-- -