2

I'm trying to pass a URL as a parameter in Golang, and I haven't been able to find a solution in all of the tutorials I've looked at. The problem is that I can only get the url to return minus a crucial forward slash.

My handler looks like this:

router.HandleFunc("/new/{url}", createURL) 

So the request would look like:

www.myapp.heroku.com/new/https://www.google.com 

However, the url that I results is missing a slash:

http:/www.google.com 

I sure it's probably got something to do with RFC3986, but is there a way to pass in the url as it is?

6
  • 4
    Pass it in a query param and urlencode it. Because depending on what mux you use to parse that, might interpret that differently. Eg.: '?url=https%3A%2F%2Fwww.google.com%2F' Commented Apr 26, 2017 at 13:33
  • @BogdanIulianBursuc The only thing is the user will just be passing in the url after the /new parameter. So, they'd first go to www.myapp.heroku.com then get an instruction to pass the url in after /new like so: www.myapp.heroku.com/new/https://www.google.com. I don't know how to pass it in a query param unfortunately. Commented Apr 26, 2017 at 13:47
  • It should still be URL-encoded. The example URLs given are not valid URLs, so you'll get no guarantees they'll work correctly with any parser. Commented Apr 26, 2017 at 14:34
  • @Adrian True. And depends also if you have a proxy server in between. Might parse it differently also. Commented Apr 26, 2017 at 15:21
  • @BogdanIulianBursuc Just to clarify, the urls can't be passed in a query param and then parsed. The URLs are passed in like in this app: little-url.herokuapp.com Commented Apr 27, 2017 at 3:59

2 Answers 2

2

After reading the other question, I understand what do you mean. Implement a kind of URL re-writer before URL goes to gorilla/mux. The function will look like:

func Rewriter(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { //Simple URL rewriter. Rewrite if it's started with API path pathReq := r.RequestURI if strings.HasPrefix(pathReq, "/new/") { //Use url.QueryEscape for pre go1.8 pe := url.PathEscape(strings.TrimLeft(pathReq, "/new/")) r.URL.Path = "/new/" + pe r.URL.RawQuery = "" } h.ServeHTTP(w, r) }) } 

Wrap gorilla router when starting the http server:

r := mux.NewRouter() // ... other handler r.HandleFunc("/new/{original-url}", NewHandler) //Wrap mux.Router using Rewriter log.Fatal(http.ListenAndServe(":8080", Rewriter(r))) 

Then in your URL shortener handler, the original URL can be extracted using the following code:

func NewHandler(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) ou := vars["original-url"] //Use url.QueryUnascape for pre go1.8 originalURL, err := url.PathUnescape(ou) //... other processing } 

IMHO, implementing URL shortener service like this is not recommended, mainly due to incorrect use of HTTP verbs. Any GET request should not leave side effect in server e.g. no record creation in database, etc.

Sign up to request clarification or add additional context in comments.

Comments

2

This particular behavior in Gorilla Mux can be changed by setting SkipClean to true.

router := mux.NewRouter() router.SkipClean(true) router.HandleFunc("/new/", index) router.HandleFunc("/", index) http.ListenAndServe(":"+port, router) 

The relevant documentation can be found here.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.