@@ -207,7 +207,7 @@ getAction PathInfo{pathIsProc, pathIsDefSpec} method =
207207
208208getMediaTypes :: AppConfig -> RequestHeaders -> Action -> PathInfo -> Either ApiRequestError (MediaType , MediaType )
209209getMediaTypes conf hdrs action path = do
210- acceptMediaType <- findAcceptMediaType conf action path accepts
210+ acceptMediaType <- negotiateContent conf action path accepts
211211 pure (acceptMediaType, contentMediaType)
212212 where
213213 accepts = maybe [MTAny ] (map MediaType. decodeMediaType . parseHttpAccept) $ lookupHeader " accept"
@@ -299,19 +299,6 @@ getPayload reqBody contentMediaType QueryParams{qsColumns} action PathInfo{pathI
299299 ActionInvoke InvPost -> qsColumns
300300 _ -> Nothing
301301
302- {-|
303- Find the best match from a list of media types accepted by the
304- client in order of decreasing preference and a list of types
305- producible by the server. If there is no match but the client
306- accepts */* then return the top server pick.
307- -}
308- mutuallyAgreeable :: [MediaType ] -> [MediaType ] -> Maybe MediaType
309- mutuallyAgreeable sProduces cAccepts =
310- let exact = listToMaybe $ L. intersect cAccepts sProduces in
311- if isNothing exact && MTAny `elem` cAccepts
312- then listToMaybe sProduces
313- else exact
314-
315302type CsvData = V. Vector (M. Map Text LBS. ByteString )
316303
317304{-|
@@ -361,20 +348,24 @@ payloadAttributes raw json =
361348 where
362349 emptyPJArray = ProcessedJSON (JSON. encode emptyArray) S. empty
363350
364- findAcceptMediaType :: AppConfig -> Action -> PathInfo -> [MediaType ] -> Either ApiRequestError MediaType
365- findAcceptMediaType conf action path accepts =
366- case mutuallyAgreeable (requestMediaTypes conf action path) accepts of
367- Just ct ->
368- Right ct
369- Nothing ->
370- Left . MediaTypeError $ map MediaType. toMime accepts
371351
372- requestMediaTypes :: AppConfig -> Action -> PathInfo -> [MediaType ]
373- requestMediaTypes conf action path =
352+ -- | Do content negotiation. i.e. choose a media type based on the intersection of accepted/produced media types.
353+ negotiateContent :: AppConfig -> Action -> PathInfo -> [MediaType ] -> Either ApiRequestError MediaType
354+ negotiateContent conf action path accepts =
355+ case firstAcceptedPick of
356+ Just MTAny -> Right MTApplicationJSON -- by default(for */*) we respond with json
357+ Just mt -> Right mt
358+ Nothing -> Left . MediaTypeError $ map MediaType. toMime accepts
359+ where
360+ -- if there are multiple accepted media types, pick the first
361+ firstAcceptedPick = listToMaybe $ L. intersect accepts $ producedMediaTypes conf action path
362+
363+ producedMediaTypes :: AppConfig -> Action -> PathInfo -> [MediaType ]
364+ producedMediaTypes conf action path =
374365 case action of
375366 ActionRead _ -> defaultMediaTypes ++ rawMediaTypes
376367 ActionInvoke _ -> invokeMediaTypes
377- ActionInspect _ -> [MTOpenAPI , MTApplicationJSON ]
368+ ActionInspect _ -> [MTOpenAPI , MTApplicationJSON , MTAny ]
378369 ActionInfo -> defaultMediaTypes
379370 ActionMutate _ -> defaultMediaTypes
380371 where
@@ -384,5 +375,5 @@ requestMediaTypes conf action path =
384375 ++ [MTOpenAPI | pathIsRootSpec path]
385376 defaultMediaTypes =
386377 [MTApplicationJSON , MTSingularJSON , MTGeoJSON , MTTextCSV ] ++
387- [MTPlan $ MTPlanAttrs Nothing PlanJSON mempty | configDbPlanEnabled conf]
378+ [MTPlan $ MTPlanAttrs Nothing PlanJSON mempty | configDbPlanEnabled conf] ++ [ MTAny ]
388379 rawMediaTypes = configRawMediaTypes conf `union` [MTOctetStream , MTTextPlain , MTTextXML ]
0 commit comments