]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
add content negotiation for media type
authorEvan Prodromou <evan@prodromou.name>
Fri, 13 Jun 2008 14:49:13 +0000 (10:49 -0400)
committerEvan Prodromou <evan@prodromou.name>
Fri, 13 Jun 2008 14:49:13 +0000 (10:49 -0400)
darcs-hash:20080613144913-84dde-3e970b4e6f19ea1e0db09d7ab133a6c148be7a75.gz

doc/roadmap
lib/util.php

index a3e72583397df26eb537134a26dfab6152b72754..4caeb4e6121fec15ce781d4c810eee223720136b 100644 (file)
@@ -91,8 +91,8 @@ First public release (theoretically). Added distributed subscriptions,
 + log of consumers who ask for access
 + receive remote notice
 + send remote notice
-- receive remote profile update
-- send remote profile update
++ receive remote profile update
++ send remote profile update
 + subscribe form for not-logged-in users on showstream
 + pretty URLs
 + doc action
@@ -138,8 +138,8 @@ First public release (theoretically). Added distributed subscriptions,
 - graphic refresh on remotesubscribe
 + graphic refresh on shownotice
 + graphic refresh on showstream
-- graphic refresh on subscribed
-- graphic refresh on subscriptions
++ graphic refresh on subscribed
++ graphic refresh on subscriptions
 + graphic refresh on userauthorization
 - update default theme to use new, more semantic, HTML
 - subscribe/unsubscribe on subscriptions page
@@ -147,10 +147,12 @@ First public release (theoretically). Added distributed subscriptions,
 + correct use of views menu in settings
 + correct use of views menu in streams
 - INSTALL file
+- content negotiation for content type
 
 Release 0.4
 -----------
 
+- jQuery for as much as possible
 - microid for profile page
 - format times per user
 - timezone preferences in Profile settings
@@ -164,8 +166,6 @@ Release 0.4
 - email confirmation for registration
 - email options
 - change cookie handling for anon users to be more cache-friendly
-- jQuery for as much as possible
-- content negotiation for content type
 - content negotiation for encoding
 - If-Modified-Since support
 - Vary
index d6c1a9f8b9ee863016faad36573a0d5d1dc89344..e1e50817652843add1ce2d96e309bd13e037cc1c 100644 (file)
@@ -123,10 +123,24 @@ function common_end_xml() {
        $xw->flush();
 }
 
+define('PAGE_TYPE_PREFS', 'application/xhtml+xml,text/html;q=0.7,application/xml;q=0.3,text/xml;q=0.2');
+          
 function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall=NULL) {
        global $config, $xw;
 
-       header('Content-Type: application/xhtml+xml');
+       $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : NULL;
+
+       # XXX: allow content negotiation for RDF, RSS, or XRDS
+       
+       $type = common_negotiate_type(common_accept_to_prefs($httpaccept),
+                                                                 common_accept_to_prefs(PAGE_TYPE_PREFS));
+
+       if (!$type) {
+               common_client_error(_t('This page is not available in a media type you accept'), 406);
+               exit(0);
+       }
+       
+       header('Content-Type: '.$type);
 
        common_start_xml('html',
                                         '-//W3C//DTD XHTML 1.0 Strict//EN',
@@ -736,3 +750,81 @@ function common_pagination($have_before, $have_after, $page, $action, $args=NULL
                common_element_end('div');
        }
 }
+
+/* Following functions are copied from MediaWiki GlobalFunctions.php
+ * and written by Evan Prodromou. */
+
+function common_accept_to_prefs($accept, $def = '*/*') {
+       # No arg means accept anything (per HTTP spec)
+       if(!$accept) {
+               return array($def => 1);
+       }
+
+       $prefs = array();
+
+       $parts = explode(',', $accept);
+
+       foreach($parts as $part) {
+               # FIXME: doesn't deal with params like 'text/html; level=1'
+               @list($value, $qpart) = explode(';', $part);
+               $match = array();
+               if(!isset($qpart)) {
+                       $prefs[$value] = 1;
+               } elseif(preg_match('/q\s*=\s*(\d*\.\d+)/', $qpart, $match)) {
+                       $prefs[$value] = $match[1];
+               }
+       }
+
+       return $prefs;
+}
+
+function common_mime_type_match($type, $avail) {
+       if(array_key_exists($type, $avail)) {
+               return $type;
+       } else {
+               $parts = explode('/', $type);
+               if(array_key_exists($parts[0] . '/*', $avail)) {
+                       return $parts[0] . '/*';
+               } elseif(array_key_exists('*/*', $avail)) {
+                       return '*/*';
+               } else {
+                       return NULL;
+               }
+       }
+}
+
+function common_negotiate_type($cprefs, $sprefs) {
+       $combine = array();
+
+       foreach(array_keys($sprefs) as $type) {
+               $parts = explode('/', $type);
+               if($parts[1] != '*') {
+                       $ckey = common_mime_type_match($type, $cprefs);
+                       if($ckey) {
+                               $combine[$type] = $sprefs[$type] * $cprefs[$ckey];
+                       }
+               }
+       }
+
+       foreach(array_keys($cprefs) as $type) {
+               $parts = explode('/', $type);
+               if($parts[1] != '*' && !array_key_exists($type, $sprefs)) {
+                       $skey = common_mime_type_match($type, $sprefs);
+                       if($skey) {
+                               $combine[$type] = $sprefs[$skey] * $cprefs[$type];
+                       }
+               }
+       }
+
+       $bestq = 0;
+       $besttype = NULL;
+
+       foreach(array_keys($combine) as $type) {
+               if($combine[$type] > $bestq) {
+                       $besttype = $type;
+                       $bestq = $combine[$type];
+               }
+       }
+
+       return $besttype;
+}