- add http_negotiate_content_type()
[m6w6/ext-http] / http_functions.c
index 7d82438ef6e059f52465c1343dac139d46545ca0..e731d9af041343c08112d467568f228d7d7a9f75 100644 (file)
@@ -108,7 +108,7 @@ PHP_FUNCTION(http_build_uri)
 #define HTTP_DO_NEGOTIATE(type, supported, rs_array) \
 { \
        HashTable *result; \
-       if (result = http_negotiate_ ##type(supported)) { \
+       if ((result = http_negotiate_ ##type(supported))) { \
                char *key; \
                uint key_len; \
                ulong idx; \
@@ -137,9 +137,10 @@ PHP_FUNCTION(http_build_uri)
                } \
                \
                if (rs_array) { \
+                       HashPosition pos; \
                        zval **value; \
                         \
-                       FOREACH_VAL(supported, value) { \
+                       FOREACH_VAL(pos, supported, value) { \
                                convert_to_string_ex(value); \
                                add_assoc_double(rs_array, Z_STRVAL_PP(value), 1.0); \
                        } \
@@ -250,6 +251,44 @@ PHP_FUNCTION(http_negotiate_charset)
 }
 /* }}} */
 
+/* {{{ proto 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:
+ * <pre>
+ * <?php
+ * $ctypes = array('application/xhtml+xml', 'text/html');
+ * http_send_content_type(http_negotiate_content_type($ctypes));
+ * ?>
+ * </pre>
+ */
+PHP_FUNCTION(http_negotiate_content_type)
+{
+       zval *supported, *rs_array = NULL;
+       
+       if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|z", &supported, &rs_array)) {
+               RETURN_FALSE;
+       }
+       
+       if (rs_array) {
+               zval_dtor(rs_array);
+               array_init(rs_array);
+       }
+       
+       HTTP_DO_NEGOTIATE(content_type, supported, rs_array);
+}
+/* }}} */
+
 /* {{{ proto bool http_send_status(int status)
  *
  * Send HTTP status code.
@@ -438,13 +477,15 @@ PHP_FUNCTION(http_cache_last_modified)
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &last_modified) != SUCCESS) {
                RETURN_FALSE;
        }
+       
+       HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
 
        t = (long) time(NULL);
 
        /* 0 or omitted */
        if (!last_modified) {
                /* does the client have? (att: caching "forever") */
-               if (zlm = http_get_server_var("HTTP_IF_MODIFIED_SINCE")) {
+               if ((zlm = http_get_server_var("HTTP_IF_MODIFIED_SINCE"))) {
                        last_modified = send_modified = http_parse_date(Z_STRVAL_P(zlm));
                /* send current time */
                } else {
@@ -485,6 +526,8 @@ PHP_FUNCTION(http_cache_etag)
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &etag, &etag_len) != SUCCESS) {
                RETURN_FALSE;
        }
+       
+       HTTP_CHECK_HEADERS_SENT(RETURN_FALSE);
 
        RETURN_SUCCESS(http_cache_etag(etag, etag_len, HTTP_DEFAULT_CACHECONTROL, lenof(HTTP_DEFAULT_CACHECONTROL)));
 }
@@ -812,7 +855,7 @@ PHP_FUNCTION(http_parse_message)
                RETURN_NULL();
        }
        
-       if (msg = http_message_parse(message, message_len)) {
+       if ((msg = http_message_parse(message, message_len))) {
                object_init(return_value);
                http_message_tostruct_recursive(msg, return_value);
                http_message_free(&msg);
@@ -1264,7 +1307,7 @@ PHP_FUNCTION(http_request_method_register)
        if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &method, &method_len)) {
                RETURN_FALSE;
        }
-       if (existing = http_request_method_exists(1, 0, method)) {
+       if ((existing = http_request_method_exists(1, 0, method))) {
                RETURN_LONG((long) existing);
        }
 
@@ -1391,7 +1434,7 @@ PHP_FUNCTION(http_build_query)
        }
 
        formstr = phpstr_new();
-       if (SUCCESS != http_urlencode_hash_recursive(HASH_OF(formdata), formstr, arg_sep, prefix, prefix_len)) {
+       if (SUCCESS != http_urlencode_hash_recursive(HASH_OF(formdata), formstr, arg_sep, arg_sep_len, prefix, prefix_len)) {
                phpstr_free(&formstr);
                RETURN_FALSE;
        }