@@ -17,8 +17,6 @@ declare variable $local:config := config:get-configuration();
1717declare variable $local:method := request:get-method () => lower-case ();
1818declare variable $local:uri := request:get-uri ();
1919declare variable $local:forwarded-for := request:get-header ("X-Forwarded-URI" );
20- declare variable $local:wants-json := tokenize (request:get-header ('Accept' ), ', ?' ) = 'application/json' ;
21- declare variable $local:is-ajax-request := request:get-header ("X-Requested-With" ) = "XMLHttpRequest" ;
2220
2321declare function local:get-user () as xs:string? {
2422 let $login := login:set-user ($local:login-domain, xs:dayTimeDuration ("P7D" ), false ())
@@ -40,6 +38,34 @@ declare function local:query-execution-allowed($user as xs:string?, $is-dba as x
4038 )
4139};
4240
41+ declare function local:parse-accept-header () as map (xs:float, xs:string+) {
42+ let $media-type-maps as map (xs:float, xs:string)* := (
43+ let $media-types-and-quality := tokenize (request:get-header ('Accept' ), ',\s*' )
44+ for $media-type-and-quality in $media-types-and-quality
45+ let $parts := tokenize ($media-type-and-quality, ';\s*q=' )
46+ let $weight := if ($parts[2 ]) then xs:float ($parts[2 ]) else xs:float (1.0 )
47+ let $media-type := $parts[1 ]
48+ return
49+ map { $weight: $media-type }
50+ )
51+ return
52+ map:merge ($media-type-maps, map { "duplicates" : "combine" })
53+ };
54+
55+ declare function local:preferred-media-type ($media-type-map as map (xs:float, xs:string+) ) as xs:string {
56+ let $highest-weight := sort (map:keys ($media-type-map))[last ()]
57+ return
58+ map:get ($media-type-map, $highest-weight)[1 ]
59+ };
60+
61+ declare function local:accept-json ($media-type-map as map (xs:float, xs:string+)) as xs:boolean {
62+ let $contains-json-media-type-results := map:for-each ($media-type-map, function ($key, $value) {
63+ $value = "application/json"
64+ })
65+ return
66+ $contains-json-media-type-results = true ()
67+ };
68+
4369let $user := local:get-user ()
4470let $user-to-check := ($user, request:get-attribute ("xquery.user" ), 'nobody' )[1 ]
4571let $user-is-dba := sm:is-dba ($user-to-check)
@@ -110,9 +136,13 @@ else if ($local:method = 'get' and $exist:resource = "backdrop.svg") then
110136
111137else if (not ($user-allowed))
112138then (
113- if ($ local:wants -json or $ local:is-ajax-request )
139+ if (local:accept -json ( local:parse-accept-header ()) )
114140 then (
115- util:declare-option ("exist:serialize" , "method=json media-type=application/json" ),
141+ util:declare-option ("output:method" , "json" ),
142+ util:declare-option ("output:media-type" , "application/json" ), (: does not work due to bug in writeResultJSON :)
143+ (:~ the response:set-header("Content-Type" is used as a workaround until https://github.com/evolvedbinary/elemental/pull/211
144+ : is merged on Elemental and the same should be done for eXist-db
145+ Then the we can use the output:media-type option as expected :)
116146 response:set-header ("Content-Type" , "application/json; charset=UTF-8" ),
117147 response:set-status-code (401 ),
118148 <status>
@@ -130,12 +160,16 @@ then (
130160 : Login a user via AJAX. Just returns a 401 if login fails.
131161 :)
132162else if (
133- ($ local:wants -json or $ local:is-ajax-request ) and
163+ local:accept -json ( local:parse-accept-header () ) and
134164 $local:method = 'post' and
135165 $exist:resource = 'login'
136166)
137167then (
138- util:declare-option ("exist:serialize" , "method=json media-type=application/json" ),
168+ util:declare-option ("output:method" , "json" ),
169+ util:declare-option ("output:media-type" , "application/json" ), (: does not work due to bug in writeResultJSON :)
170+ (:~ the response:set-header("Content-Type" is used as a workaround until https://github.com/evolvedbinary/elemental/pull/211
171+ : is merged on Elemental and the same should be done for eXist-db
172+ Then the we can use the output:media-type option as expected :)
139173 response:set-header ("Content-Type" , "application/json; charset=UTF-8" ),
140174 <status>
141175 <user>{$user}</user>
0 commit comments