如何轻松获取https发布回复数据?

时间:2011-04-10 13:47:35

标签: haskell https google-api

我正在开发一个使用Google URL缩短器API的玩具程序。要缩短网址,您需要发送此请求:

POST https://www.googleapis.com/urlshortener/v1/url
Content-Type: application/json

{"longUrl": "http://www.google.com/"}

你会得到这个回复:

{
 "kind": "urlshortener#url",
 "id": "http://goo.gl/fbsS",
 "longUrl": "http://www.google.com/"
}

首先我使用Network.HTTP,但发现它不支持HTTPS,而Google的API仅支持HTTPS。所以我转向Network.Curl。我发现HTTP GET有一个方便的功能

curlGetString :: URLString -> [CurlOption] -> IO (CurlCode, String)

但HTTP POST没有这样的功能。更糟糕的是,我找不到获取HTTP POST响应数据的方法。我所知道的是我可以使用

发出HTTP POST请求
curlPost :: URLString -> [String] -> IO ()

有人能告诉我出路吗?感谢。

3 个答案:

答案 0 :(得分:15)

仅使用http-enumerator提供替代解决方案:

{-# LANGUAGE OverloadedStrings #-}

import Network.HTTP.Enumerator
import Network.HTTP.Types
import qualified Data.ByteString.Lazy as L

main = do
  req0 <- parseUrl "https://www.googleapis.com/urlshortener/v1/url"

  let req = req0 { method = methodPost
                 , requestHeaders = [("Content-Type", "application/json")]
                 , requestBody = RequestBodyLBS "{\"longUrl\": \"http://www.google.com/\"}"
                 }

  res <- withManager $ httpLbs req

  L.putStrLn $ responseBody res

答案 1 :(得分:15)

使用http-conduit提供另一种选择:

{-# LANGUAGE OverloadedStrings #-}

import Network.HTTP.Conduit
import qualified Data.ByteString.Lazy as L

main = do
  initReq <- parseUrl "https://www.googleapis.com/urlshortener/v1/url"

  let req' = initReq { secure = True } -- Turn on https
  let req = (flip urlEncodedBody) req' $
             [ ("longUrl", "http://www.google.com/")
  --           ,
             ]

  response <- withManager $ httpLbs req

  L.putStr $ responseBody response

与http-enumerator的区别

  1. 会自动为您设置POST方法。
  2. 已发布的有效内容会自动进行urlencoded。
  3. Content-Type自动设置为“application / x-www-form-urlencoded”

答案 2 :(得分:2)

如果您查看curlPost的来源,您会看到它执行此操作:

curlPost s ps = initialize >>= \ h -> do
  setopt h (CurlVerbose True)
  setopt h (CurlPostFields ps)
  setopt h (CurlCookieJar "cookies")
  setopt h (CurlURL s)
  perform h
  return ()

所以我认为你需要做类似的事情,但不是最后两行,写

  resp <- perform_with_response h

此外看起来setopt未导出,但setopts是,所以您可以使用它。