Skip to content

Commit 9fe078a

Browse files
committed
[bugfix] set the correct media type for login header and parse the Accept header.
1 parent fb569d5 commit 9fe078a

1 file changed

Lines changed: 40 additions & 6 deletions

File tree

controller.xq

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ declare variable $local:config := config:get-configuration();
1717
declare variable $local:method := request:get-method() => lower-case();
1818
declare variable $local:uri := request:get-uri();
1919
declare 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

2321
declare 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+
4369
let $user := local:get-user()
4470
let $user-to-check := ($user, request:get-attribute("xquery.user"), 'nobody')[1]
4571
let $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

111137
else if (not($user-allowed))
112138
then (
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/212
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
:)
132162
else 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
)
137167
then (
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/212
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

Comments
 (0)