aboutsummaryrefslogtreecommitdiff
path: root/guix-data-service/web/util.scm
diff options
context:
space:
mode:
authorChristopher Baines <mail@cbaines.net>2019-05-11 22:56:25 +0100
committerChristopher Baines <mail@cbaines.net>2019-05-11 22:56:25 +0100
commit658a1a20b20760cbe11d6442e3a15c7f27ae568e (patch)
tree569fe03ebc9a59e5e1bf047c2ab725bb4e0feab3 /guix-data-service/web/util.scm
parent640fb8a2ad262e06b138deb975f92e6acb3a423b (diff)
downloaddata-service-658a1a20b20760cbe11d6442e3a15c7f27ae568e.tar
data-service-658a1a20b20760cbe11d6442e3a15c7f27ae568e.tar.gz
Improve the content negotiation handling in general
Previously, the routing layer handled the content negotiation, and the Accept header was ignored. Now, the extension if one is provided in the URL is still used, and more widely than before, but the Accept header is also taken in to account. This all now happens before the routing decisions are made, so the routing is now pretty much extension independant (with the exception of the /gnu/store/... routes).
Diffstat (limited to 'guix-data-service/web/util.scm')
-rw-r--r--guix-data-service/web/util.scm52
1 files changed, 49 insertions, 3 deletions
diff --git a/guix-data-service/web/util.scm b/guix-data-service/web/util.scm
index 574b29b..6e1abb7 100644
--- a/guix-data-service/web/util.scm
+++ b/guix-data-service/web/util.scm
@@ -22,15 +22,61 @@
#:use-module (srfi srfi-1)
#:use-module (web request)
#:use-module (web uri)
- #:export (request-path-components
+ #:export (most-appropriate-mime-type
+ request->path-components-and-mime-type
file-extension
directory?
hyphenate-words
underscore-join-words))
-(define (request-path-components request)
- (split-and-decode-uri-path (uri-path (request-uri request))))
+(define (most-appropriate-mime-type accepted-mime-types
+ supported-mime-types)
+ (or
+ ;; Pick the first supported mime-type
+ (find (lambda (accepted-mime-type)
+ (memq accepted-mime-type
+ supported-mime-types))
+ accepted-mime-types)
+ ;; Default to the first supported mime-type if none are accepted
+ (first supported-mime-types)))
+
+(define (request->path-components-and-mime-type request)
+ (define extensions-to-mime-types
+ '(("json" . application/json)
+ ("html" . text/html)))
+
+ (match (split-and-decode-uri-path (uri-path (request-uri request)))
+ (()
+ (values '()
+ (or (request-accept request)
+ (list 'text/html))))
+ ((single-component)
+ (match (string-split single-component #\.)
+ ((part)
+ (values (list single-component)
+ (or (request-accept request)
+ (list 'text/html))))
+ ((first-parts ... extension)
+ (values (string-join first-parts ".")
+ (or (cons
+ (or (assoc-ref extensions-to-mime-types extension)
+ 'text/html)
+ (request-accept request)))))))
+ ((first-components ... last-component)
+ (match (string-split last-component #\.)
+ ((part)
+ (values (append first-components
+ (list part))
+ (or (request-accept request)
+ (list 'text/html))))
+ ((first-parts ... extension)
+ (values (append first-components
+ (list (string-join first-parts ".")))
+ (or (cons
+ (or (assoc-ref extensions-to-mime-types extension)
+ 'text/html)
+ (request-accept request)))))))))
(define (file-extension file-name)
(last (string-split file-name #\.)))