PHP_FALIAS(http_absolute_uri, http_build_uri, NULL)
PHP_FE(http_negotiate_language, http_arg_pass_ref_2)
PHP_FE(http_negotiate_charset, http_arg_pass_ref_2)
+ PHP_FE(http_negotiate_content_type, http_arg_pass_ref_2)
PHP_FE(http_redirect, NULL)
PHP_FE(http_throttle, NULL)
PHP_FE(http_send_status, NULL)
}
/* }}} */
+/* {{{ 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.
FOREACH_HASH_VAL(pos, supported, value) {
int len = dash_test - test;
#if HTTP_DBG_NEG
- fprintf(stderr, "strncascmp('%s', '%s', %d)\n", Z_STRVAL_PP(value), test, len);
+ fprintf(stderr, "strncasecmp('%s', '%s', %d)\n", Z_STRVAL_PP(value), test, len);
#endif
if ( (!strncasecmp(Z_STRVAL_PP(value), test, len)) &&
( (Z_STRVAL_PP(value)[len] == '\0') ||
array_init(&array);
FOREACH_HASH_VAL(pos, Z_ARRVAL(ex_arr), entry) {
+ int ident_len;
double quality;
- char *selected, *identifier;
+ char *selected, *identifier, *freeme;
const char *separator;
#if HTTP_DBG_NEG
if ((separator = strchr(Z_STRVAL_PP(entry), ';'))) {
const char *ptr = separator;
- while (*++ptr && !isdigit(*ptr));
+ while (*++ptr && !isdigit(*ptr) && '.' != *ptr);
quality = atof(ptr);
- identifier = estrndup(Z_STRVAL_PP(entry), separator - Z_STRVAL_PP(entry));
+ identifier = estrndup(Z_STRVAL_PP(entry), ident_len = separator - Z_STRVAL_PP(entry));
} else {
quality = 1000.0 - i++;
- identifier = estrndup(Z_STRVAL_PP(entry), Z_STRLEN_PP(entry));
+ identifier = estrndup(Z_STRVAL_PP(entry), ident_len = Z_STRLEN_PP(entry));
+ }
+ freeme = identifier;
+
+ while (isspace(*identifier)) {
+ ++identifier;
+ --ident_len;
+ }
+ while (isspace(identifier[ident_len - 1])) {
+ identifier[--ident_len] = '\0';
}
if ((selected = neg(identifier, &quality, supported TSRMLS_CC))) {
}
}
- efree(identifier);
+ efree(freeme);
}
result = Z_ARRVAL(array);
</lead>
<date>2005-00-00</date>
<version>
- <release>0.18.1</release>
- <api>0.18.0</api>
+ <release>0.19.0</release>
+ <api>0.19.0</api>
</version>
<stability>
<release>beta</release>
</stability>
<license>BSD, revised</license>
<notes><![CDATA[
-* Fixed build with PHP-4 and PHP-5.0
+* Fixed bug in http_negotiate_*() when client sends spaces within accept headers
+
++ Added http_negotiate_content_type()
]]></notes>
<contents>
<dir name="/">
PHP_FUNCTION(http_build_uri);
PHP_FUNCTION(http_negotiate_language);
PHP_FUNCTION(http_negotiate_charset);
+PHP_FUNCTION(http_negotiate_content_type);
PHP_FUNCTION(http_redirect);
PHP_FUNCTION(http_throttle);
PHP_FUNCTION(http_send_status);
#define http_negotiate_language_func _http_negotiate_language_func
extern char *_http_negotiate_language_func(const char *test, double *quality, HashTable *supported TSRMLS_DC);
+#define http_negotiate_content_type_func _http_negotiate_default_func
#define http_negotiate_encoding_func _http_negotiate_default_func
#define http_negotiate_charset_func _http_negotiate_default_func
#define http_negotiate_default_func _http_negotiate_default_func
#define http_negotiate_charset_ex(supported) http_negotiate_q("HTTP_ACCEPT_CHARSET", (supported), http_negotiate_charset_func)
#define http_negotiate_encoding(zsupported) http_negotiate_encoding_ex(Z_ARRVAL_P(zsupported))
#define http_negotiate_encoding_ex(supported) http_negotiate_q("HTTP_ACCEPT_ENCODING", (supported), http_negotiate_encoding_func)
+#define http_negotiate_content_type(zsupported) http_negotiate_content_type_ex(Z_ARRVAL_P(zsupported))
+#define http_negotiate_content_type_ex(supported) http_negotiate_q("HTTP_ACCEPT", (supported), http_negotiate_content_type_func)
#define http_negotiate_q(e, s, n) _http_negotiate_q((e), (s), (n) TSRMLS_CC)
PHP_HTTP_API HashTable *_http_negotiate_q(const char *header, HashTable *supported, negotiate_func_t neg TSRMLS_DC);
include 'skip.inc';
?>
--ENV--
+HTTP_ACCEPT=application/xml, application/xhtml+xml, text/html ; q = .8
HTTP_ACCEPT_LANGUAGE=de-AT,de-DE;q=0.8,en-GB;q=0.3,en-US;q=0.2
HTTP_ACCEPT_CHARSET=ISO-8859-1,utf-8;q=0.7,*;q=0.7
--FILE--
$csets = array(
array('utf-8', 'iso-8859-1'),
);
+$ctype = array(
+ array('foo/bar', 'application/xhtml+xml', 'text/html')
+);
var_dump(http_negotiate_language($langs[0]));
var_dump(http_negotiate_language($langs[0], $lresult));
var_dump(http_negotiate_charset($csets[0]));
var_dump(http_negotiate_charset($csets[0], $cresult));
+var_dump(http_negotiate_content_type($ctype[0]));
+var_dump(http_negotiate_content_type($ctype[0], $tresult));
print_r($lresult);
print_r($cresult);
+print_r($tresult);
echo "Done\n";
--EXPECTF--
%sTEST
string(2) "de"
string(10) "iso-8859-1"
string(10) "iso-8859-1"
+string(21) "application/xhtml+xml"
+string(21) "application/xhtml+xml"
Array
(
[de] => 900
[iso-8859-1] => 1000
[utf-8] => 0.7
)
+Array
+(
+ [application/xhtml+xml] => 999
+ [text/html] => 0.8
+)
Done