2

I am using golang

func (ph *testHandler) GetData() gin.HandlerFunc { return func(ctx *gin.Context) { params := ctx.Request.URL.Query() search = strings.TrimSpace(params.Get("data")) } } 

here I am passing 'test+test' in url but I am getting 'test test'

How can I do query parsing in golang

1
  • 4
    The plus sign corresponds to a URL-encoded ASCII space. If you want to obtain "test+test" in the backend, you should percent-encode the plus sign in the value of the URL's query param: test%2Btest. Commented Jul 22, 2021 at 7:19

3 Answers 3

3

If you look at the source

func (u *URL) Query() Values { v, _ := ParseQuery(u.RawQuery) return v } 

Calls ParseQuery which calls unescape in the "encodeQueryComponent" mode as part of the things it does.

this code fragment is relevant

 case '+': if mode == encodeQueryComponent { t.WriteByte(' ') } else { t.WriteByte('+') } 

this is simply RFC compliant parsing, it's normal, the behaviour you are seeing is expected

see https://cs.opensource.google/go/go/+/refs/tags/go1.16.6:src/net/url/url.go;drc=refs%2Ftags%2Fgo1.16.6;l=182

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

1 Comment

If this is RFC complaint parsing, why does every other language (python, JS, etc) not convert + to space when decoding urls? See, i.e. unquote("+") (python), unescape("+") (JS) Does that mean python and JS are not RFC complaint?
1

The browsers treats + and %20 signs in URL as space character so test+test in query parameter will have value test test. To prevent this you have to manually add URL encoded value of + character literal in the URL - https://example.com?data=test%2Btest

For other URL encoded values see w3schools.

Comments

1

The plus sign in the value of your query parameter is actually an URL-encoded ASCII space. If you want to obtain "test+test" in the backend, you should percent-encode the plus sign in the value of the URL's query param: test%2Btest.

Some minimal server code to fix ideas:

package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/", handle) if err := http.ListenAndServe(":8080", nil); err != nil { log.Fatal(err) } } func handle(w http.ResponseWriter, r *http.Request) { data := r.URL.Query().Get("data") w.Header().Set("Content-type", "text/plain") fmt.Fprint(w, data) } 

Results:

  • http://localhost:8080/?data=test+test prints test test, whereas
  • http://localhost:8080/?data=test%2Btest prints test+test.

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.