4

I'm interacting with an API which takes URI components that may contain both forward-slashes and spaces. I need to percent-encode this URI component so that both the forward-slashes and spaces are properly encoded. Example Go code can be found here.

I turned to net/url to tackle this, but turns out it doesn't do what I want, apparently.

  • url.QueryEscape() is intended for query strings, and as such it turns whitespace into + rather than %20.
  • url.Parse() and url.ParseRequestUri() will turn whitespace into %20, but it will ignore /, as it should.

Since I'm very likely to muck this up (escaping is non-trivial), I'd prefer I relied upon some standard library out there to do this for me. Does such a standard method exist in a well-tested Go library?

Side note: The behaviour I'm seeking is identical to JS's encodeURIcomponent.

alienth
  • 349
  • 2
  • 8
  • Possible duplicate of [Encode / decode URLs](http://stackoverflow.com/questions/13820280/encode-decode-urls) – icza Jun 29 '16 at 06:32
  • I did review that question before posting. It is not a duplicate, as the question and solution provided does not account for or work with escaping of forward slashes in the URI components. – alienth Jun 29 '16 at 08:43
  • What do you want exactly? The _exact_ equivalent of JavaScript's `encodeURIComponent()`? – icza Jun 29 '16 at 12:44
  • Something which will appropriately encode a URI component which includes forward slashes and spaces. I was hoping there was a standard lib out there to do so, but apparently there isn't - I created this as an issue on Golang's GH and it was tagged with Go1.8. – alienth Jun 29 '16 at 18:15
  • For those who want to follow the progress of the github issue, here's the link: [net/url: No adequate method exists for encoding a URI component #16207](https://github.com/golang/go/issues/16207) – icza Jun 29 '16 at 19:31

1 Answers1

1

Apparently a version of your issue made it in go1.8 as url.PathEscape.

In go1.8 the code you're looking for would be as simple as:

package main

import (
    "fmt"
    "net/url"
)

const expected = "/object/test%2Fbar%20baz"

func main() {
    uri := "/object/"
    name := "test/bar baz"

    fmt.Printf("%-25s %s\n", "Expected:", expected)
    fmt.Printf("%-25s %s\n", "Actual  :", uri+url.PathEscape(name))
}

Good question.

Josh Lubawy
  • 386
  • 1
  • 6