http-client icon indicating copy to clipboard operation
http-client copied to clipboard

parseRequest can't deal with a JSON massive of objects

Open ddd356 opened this issue 3 years ago • 3 comments

{-# LANGUAGE OverloadedStrings #-}
module Main where

import Lib
import Network.HTTP.Simple

req1 = parseRequest_ "https://host.com/method/messages.send?keyboard=\"\""
req2 = parseRequest_ "https://host.com/method/messages.send?keyboard={\"buttons\":true}"

req3 = parseRequest_ "https://host.com/method/messages.send?keyboard={\"buttons\":[{\"prop\":\"val\"}]}"

main :: IO ()
main = putStrLn "main"

Hello! I try to parse URL where one of parameters is a JSON with a nested list of objects. parseRequest throws exception on req3 in this code. In req3 URL is incorrect, because of symbols, that can't be part of URL, but maybe parser can correctly encode by himself. Think it's a bug. Check it please.

ddd356 avatar Jan 31 '22 13:01 ddd356

This doesn't appear to be a bug, it looks like you have incorrectly escaped query string parameters. I'd recommend using a library for properly building up URLs that handles escaping correctly.

snoyberg avatar Jan 31 '22 15:01 snoyberg

But one thing still embarrassing me. That's when I use setRequestQueryString to set same JSON string to one of the parameters, it's works with no exceptions. It makes me think, that parser must do the same thing with a string. Function req4 works right.

req4 = setRequestQueryString [ ("keyboard", Just "{\"buttons\":[{\"prop\":\"val\"}]] . setRequestPath "/method/messages.send" . setRequestPort 443 . setRequestSecure True . setRequestHost "myhost.com" $ defaultRequest

ddd356 avatar Jan 31 '22 19:01 ddd356

@ddd356 That's because you're not parsing the URL in your last example. setRequestQueryString encodes the query parameters properly:

> getUri $ setQueryString [("foo", Just "[]")] defaultRequest
http://localhost/?foo=%5B%5D

The resulting URI can be parsed just fine:

> getUri $ parseRequest_ "http://localhost/?foo=%7B%7D"
http://localhost/?foo=%7B%7D

While unescaped brackets can't be parsed:

> getUri $ parseRequest_ "http://localhost/?foo=[]"
*** Exception: InvalidUrlException "http://localhost/?foo=[]" "Invalid URL"

robx avatar Feb 08 '22 14:02 robx