如何使用 Haskell 请求设置 HTTP 版本

How to set HTTP version with Haskell request

我正在完成 Plutus Pioneer Lectures 的第一次迭代,以及从 coinmarketcap.com returns 获取汇率的第 6 课代码出现 403 错误:

getExchangeRate = runReq defaultHttpConfig $ do
    v <- req
        GET
        (https "coinmarketcap.com" /: "currencies" /: "cardano")
        NoReqBody
        bsResponse
        mempty
    let priceRegex      = "priceValue___11gHJ\">\$([\.0-9]*)" :: ByteString
        (_, _, _, [bs]) = responseBody v =~ priceRegex :: (ByteString, ByteString, ByteString, [ByteString])
        d               = read $ unpack bs :: Double
        x               = round $ 1_000_000 * d
    liftIO $ putStrLn $ "queried exchange rate: " ++ show d
    return x 

如果我在 curl 中使用 -L 选项尝试相同的 url 来跟随重定向,它会起作用:

curl -i -L 'https://coinmarketcap.com/currencies/cardano'

我能看到的唯一区别是 Haskell 代码的请求是 HTTP/1.1,但是 curl 请求是用 HTTP/2[=15= 发送的]

我想更改 Haskell 库发送的 HTTP 版本,以检查这是否是问题所在。但是,我是 Haskell 的新手,所以我无法弄清楚 Haskell Network.HTTP.Req 模块是否可以设置 HTTP 版本。

有办法吗?

TIA

我相信 coinmarketcap.com 正在阻止没有指定 User-Agent header 的请求。你可以这样做:

getExchangeRate = runReq defaultHttpConfig $ do
    v <- req
        GET
        (https "coinmarketcap.com" /: "currencies" /: "cardano")
        NoReqBody
        bsResponse
        (header "User-Agent" "my-app/0.1.0.0")
    let priceRegex      = "priceValue___11gHJ\">\$([\.0-9]*)" :: ByteString
        (_, _, _, [bs]) = responseBody v =~ priceRegex :: (ByteString, ByteString, ByteString, [ByteString])
        d               = read $ unpack bs :: Double
        x               = round $ 1_000_000 * d
    liftIO $ putStrLn $ "queried exchange rate: " ++ show d
    return x 

使用此代码,请求正确完成,但我 运行 陷入模式匹配错误。 priceValue___11gHJ 正则表达式似乎不再起作用了。