hyper icon indicating copy to clipboard operation
hyper copied to clipboard

Optionally replace `+` in `parseUrlencoded`

Open paluh opened this issue 7 years ago • 6 comments

This PR provides a way to optionally replace + by space in query values before passing them to uri decoding. (I want to reemphasize importance of this change, so I'm coping here my arguments from purescript-uri issue).

Without this option hyper user is not able to distinguish + from %2B in original query as both are decoded to + and finally is not able parse text input values containing spaces send by all tested by me modern browsers.

I've tested on two versions of Firefox and Chromium (latest Firefox nightly 59.0a1 (2017-11-20), Chromium 62.0.3202.89 and Firefox 56.0.2) that this form:

<!DOCTYPE html>
<html>
<body>
  <form action=".">
    <input name="name with spaces" value="value with spaces" />
    <input type="submit" value="send" />
  </form>
</body>
</html>

results in + in queries (so we get "value+with+spaces"). The same behavior is observed when I add explicit enctype=application/x-www-form-urlencoded.

I know that this is not a real argument for discussion, but other libs/tools/frameworks do seem to decode + as space in query strings:

  • Haskell http-types (Servant uses http-api-data which uses http-types):

    parseQuery calls two times urlDecode with True as the first argument:

    https://github.com/aristidb/http-types/blob/master/Network/HTTP/Types/URI.hs#L136

    urlDecode:

    https://github.com/aristidb/http-types/blob/master/Network/HTTP/Types/URI.hs#L206

  • Haskell Snap framework decodes + in query keys and values to space:

    https://github.com/snapframework/snap-core/blob/master/src/Snap/Internal/Parsing.hs#L368

  • Python3 urllib.parse decodes + in queries (even in strict mode ;-)):

    https://github.com/python/cpython/blob/3.6/Lib/urllib/parse.py#L697

  • Javascript query-string repalces + in query keys and values:

    https://github.com/sindresorhus/query-string/blob/master/index.js#L148

paluh avatar Jun 01 '18 11:06 paluh

In this commit I've also dropped FromForm and ToForm type classes as I've not found any use of them (in any hyper related repository on github). I know that this is probably drastic change and this API approach shift should be discussed more extensively... In general I think that it will be easier to replace some of hyper type classes with simple record of functions.

@owickstrom: What do you think about these changes?

Should I open separate issue regarding refactoring of some type classes into plain records (so I think we will have more flexible and extensible API and simpler type inference)?

paluh avatar Jun 01 '18 11:06 paluh

Travis detected that examples from docs use ToForm and FromForm type classes so I should somehow fix them... I'm not sure if I want to bring these classes back (and add additional parameter to FromForm method with Urlencode.Options). Any comments?

paluh avatar Jun 01 '18 11:06 paluh

I've tried to fix example for form handling, but I'm not sure if I should finish this fix or drop it all together.

I don't know if we should provide an API or make any assumptions about API for validation (which assumes for example error type to be String and not for example some Variant (e | row)).

As an author of validation libraries (https://github.com/paluh/purescript-polyform) I think that such a validation glue code could be easily extracted into separate library.

paluh avatar Jun 01 '18 11:06 paluh

Can I merge this (dropping FromForm and ToForm type classes)?

paluh avatar Jul 15 '18 12:07 paluh

@owickstrom ping...

paluh avatar Jul 15 '18 14:07 paluh

Sorry for unresponsiveness! Yeah, I think ultimately these form-related things shouldn't go in the core Hyper library. I did the initial versions a bit to feature-heavy just to try out things. I'm happy you remove them and remove the corresponding docs. :+1:

owickstrom avatar Jul 17 '18 18:07 owickstrom