Search code examples
gogo-http

Inconsistent key maps from r.URL.Query()


When parsing URLs using r.URL.Query(), I am getting inconsistent results and was wondering if anyone else has had the same issue and/or a viable workaround. Keys sometimes return ?keyName instead of keyName so often i'll do keys.Get on both values.

func(w http.ResponseWriter, r *http.Request) {
        keys := r.URL.Query()
        lat := keys.Get("lat")
        if lat == "" {
                // r.URL.Query sometimes comes back with ?lat instead of lat for some reason...
            lat = keys.Get("?lat")
            if lat == "" {
                            // error here
            }
        }

        lng := keys.Get("lng")
        if lng == "" {
            lng = keys.Get("?lng")
            if lng == "" {
                            // error here
            }
        }
}

Test URL: http://localhost:3000/?lng=-75.7572111845&type=property

Current Outputs

2019/04/08 10:59:27 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:28 map[?lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:29 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:30 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:31 map[lat:[39.5040840724] ?lng:[-75.7572111845]]

Expected

2019/04/08 10:59:27 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:28 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:29 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:30 map[lat:[39.5040840724] lng:[-75.7572111845]]
2019/04/08 10:59:31 map[lat:[39.5040840724] lng:[-75.7572111845]]

Solution

  • Figured out the culprit- there was a middleware that was preprocessing the query and forwarding requests through a proxy for some reason.

    func (h *Handler) proxy(w http.ResponseWriter, r *http.Request, uri *url.URL) {
        params := r.URL.Query()
        proxy := httputil.ReverseProxy{Director: func(proxyRequest *http.Request) {
            proxyRequest.URL.Scheme = uri.Scheme
            proxyRequest.URL.Host = uri.Host
            proxyRequest.URL.Path = uri.Path
            proxyRequest.Body = r.Body
            proxyRequest.URL.RawQuery = paramsToString(params)
        }}
        proxy.ServeHTTP(w, r)
    }
    
    func paramsToString(m url.Values) string {
        keys := make([]string, 0, len(m))
        for k := range m {
            keys = append(keys, k+"="+m[k][0])
        }
        return "?" + strings.Join(keys, "&")
    }
    

    proxyRequest.URL.RawQuery expects the raw query, not a query with ?; the paramsToString func should actually be this

    func paramsToString(m url.Values) string {
        keys := make([]string, 0, len(m))
        for k := range m {
            keys = append(keys, k+"="+m[k][0])
        }
        return strings.Join(keys, "&")
    }