Skip to content

Commit b2742e6

Browse files
authored
Add Content-Type application/json to all server responses (#2096)
fix #2094 --- <!-- Consider each and tick it off one way or the other --> * [x] CHANGELOG updated or not needed * [x] Documentation updated or not needed * [x] Haddocks updated or not needed * [x] No new TODOs introduced or explained herafter
2 parents 86f3679 + 5c189e0 commit b2742e6

File tree

2 files changed

+24
-17
lines changed

2 files changed

+24
-17
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
As a minor extension, we also keep a semantic version for the `UNRELEASED`
99
changes.
1010

11+
## [0.23.0] - UNRELEASED
12+
13+
- Hydra API server responds with the correct `Content-Type` header `application-json`.
14+
1115
## [0.22.1] - 2025.06.27
1216

1317
* Fix for bug where node got stalled at `ReplayingState` [#2089](https://github.com/cardano-scaling/hydra/issues/2089)

hydra-node/src/Hydra/API/HTTPServer.hs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import Hydra.Tx (
3434
IsTx (..),
3535
UTxOType,
3636
)
37-
import Network.HTTP.Types (status200, status400, status404, status500)
37+
import Network.HTTP.Types (ResponseHeaders, hContentType, status200, status400, status404, status500)
3838
import Network.Wai (
3939
Application,
4040
Request (pathInfo, requestMethod),
@@ -141,6 +141,9 @@ instance (Arbitrary tx, Arbitrary (UTxOType tx), IsTx tx) => Arbitrary (SideLoad
141141
shrink = \case
142142
SideLoadSnapshotRequest snapshot -> SideLoadSnapshotRequest <$> shrink snapshot
143143

144+
jsonContent :: ResponseHeaders
145+
jsonContent = [(hContentType, "application/json")]
146+
144147
-- | Hydra HTTP server
145148
httpApp ::
146149
forall tx.
@@ -193,19 +196,19 @@ httpApp tracer directChain env pparams getHeadState getCommitInfo getPendingDepo
193196
>>= handleRecoverCommitUtxo putClientInput (last . fromList $ pathInfo request)
194197
>>= respond
195198
("GET", ["commits"]) ->
196-
getPendingDeposits >>= respond . responseLBS status200 [] . Aeson.encode
199+
getPendingDeposits >>= respond . responseLBS status200 jsonContent . Aeson.encode
197200
("POST", ["decommit"]) ->
198201
consumeRequestBodyStrict request
199202
>>= handleDecommit putClientInput
200203
>>= respond
201204
("GET", ["protocol-parameters"]) ->
202-
respond . responseLBS status200 [] . Aeson.encode $ pparams
205+
respond . responseLBS status200 jsonContent . Aeson.encode $ pparams
203206
("POST", ["cardano-transaction"]) ->
204207
consumeRequestBodyStrict request
205208
>>= handleSubmitUserTx directChain
206209
>>= respond
207210
_ ->
208-
respond $ responseLBS status400 [] "Resource not found"
211+
respond $ responseLBS status400 jsonContent . Aeson.encode $ Aeson.String "Resource not found"
209212

210213
-- * Handlers
211214

@@ -225,7 +228,7 @@ handleDraftCommitUtxo ::
225228
handleDraftCommitUtxo env directChain getCommitInfo body = do
226229
case Aeson.eitherDecode' body :: Either String (DraftCommitTxRequest tx) of
227230
Left err ->
228-
pure $ responseLBS status400 [] (Aeson.encode $ Aeson.String $ pack err)
231+
pure $ responseLBS status400 jsonContent (Aeson.encode $ Aeson.String $ pack err)
229232
Right someCommitRequest ->
230233
getCommitInfo >>= \case
231234
NormalCommit headId ->
@@ -249,7 +252,7 @@ handleDraftCommitUtxo env directChain getCommitInfo body = do
249252
-- expires one deposit period before deadline.
250253
deadline <- addUTCTime (3 * toNominalDiffTime depositPeriod) <$> getCurrentTime
251254
draftDepositTx headId commitBlueprint deadline <&> \case
252-
Left e -> responseLBS status400 [] (Aeson.encode $ toJSON e)
255+
Left e -> responseLBS status400 jsonContent (Aeson.encode $ toJSON e)
253256
Right depositTx -> okJSON $ DraftCommitTxResponse depositTx
254257

255258
draftCommit headId lookupUTxO blueprintTx = do
@@ -282,11 +285,11 @@ handleRecoverCommitUtxo putClientInput recoverPath _body = do
282285
Left err -> pure err
283286
Right recoverTxId -> do
284287
putClientInput Recover{recoverTxId}
285-
pure $ responseLBS status200 [] (Aeson.encode $ Aeson.String "OK")
288+
pure $ responseLBS status200 jsonContent (Aeson.encode $ Aeson.String "OK")
286289
where
287290
parseTxIdFromPath txIdStr =
288291
case Aeson.eitherDecode (encodeUtf8 txIdStr) :: Either String (TxIdType tx) of
289-
Left e -> Left (responseLBS status400 [] (Aeson.encode $ Aeson.String $ "Cannot recover funds. Failed to parse TxId: " <> pack e))
292+
Left e -> Left (responseLBS status400 jsonContent (Aeson.encode $ Aeson.String $ "Cannot recover funds. Failed to parse TxId: " <> pack e))
290293
Right txid -> Right txid
291294

292295
-- | Handle request to submit a cardano transaction.
@@ -300,23 +303,23 @@ handleSubmitUserTx ::
300303
handleSubmitUserTx directChain body = do
301304
case Aeson.eitherDecode' body of
302305
Left err ->
303-
pure $ responseLBS status400 [] (Aeson.encode $ Aeson.String $ pack err)
306+
pure $ responseLBS status400 jsonContent (Aeson.encode $ Aeson.String $ pack err)
304307
Right txToSubmit -> do
305308
try (submitTx txToSubmit) <&> \case
306309
Left (e :: PostTxError Tx) -> badRequest e
307310
Right _ ->
308-
responseLBS status200 [] (Aeson.encode TransactionSubmitted)
311+
responseLBS status200 jsonContent (Aeson.encode TransactionSubmitted)
309312
where
310313
Chain{submitTx} = directChain
311314

312315
handleDecommit :: forall tx. FromJSON tx => (ClientInput tx -> IO ()) -> LBS.ByteString -> IO Response
313316
handleDecommit putClientInput body =
314317
case Aeson.eitherDecode' body :: Either String tx of
315318
Left err ->
316-
pure $ responseLBS status400 [] (Aeson.encode $ Aeson.String $ pack err)
319+
pure $ responseLBS status400 jsonContent (Aeson.encode $ Aeson.String $ pack err)
317320
Right decommitTx -> do
318321
putClientInput Decommit{decommitTx}
319-
pure $ responseLBS status200 [] (Aeson.encode $ Aeson.String "OK")
322+
pure $ responseLBS status200 jsonContent (Aeson.encode $ Aeson.String "OK")
320323

321324
-- | Handle request to side load confirmed snapshot.
322325
handleSideLoadSnapshot ::
@@ -328,16 +331,16 @@ handleSideLoadSnapshot ::
328331
handleSideLoadSnapshot putClientInput body = do
329332
case Aeson.eitherDecode' body :: Either String (SideLoadSnapshotRequest tx) of
330333
Left err ->
331-
pure $ responseLBS status400 [] (Aeson.encode $ Aeson.String $ pack err)
334+
pure $ responseLBS status400 jsonContent (Aeson.encode $ Aeson.String $ pack err)
332335
Right SideLoadSnapshotRequest{snapshot} -> do
333336
putClientInput $ SideLoadSnapshot snapshot
334-
pure $ responseLBS status200 [] (Aeson.encode $ Aeson.String "OK")
337+
pure $ responseLBS status200 jsonContent (Aeson.encode $ Aeson.String "OK")
335338

336339
badRequest :: IsChainState tx => PostTxError tx -> Response
337-
badRequest = responseLBS status400 [] . Aeson.encode . toJSON
340+
badRequest = responseLBS status400 jsonContent . Aeson.encode . toJSON
338341

339342
notFound :: Response
340-
notFound = responseLBS status404 [] ""
343+
notFound = responseLBS status404 jsonContent (Aeson.encode $ Aeson.String "")
341344

342345
okJSON :: ToJSON a => a -> Response
343-
okJSON = responseLBS status200 [] . Aeson.encode
346+
okJSON = responseLBS status200 jsonContent . Aeson.encode

0 commit comments

Comments
 (0)