You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi,
I'm trying to understand how to properly write proxy server which will properly handle user credentials in HTTP requests. For instance, let's say I have a CouchDB with admin:admin credentials, i.e. it should be accessed via http://admin:admin@localhost:5984 URL. We can easily write simple program to access it via default HTTP client. My question is how to do the same using HTTP reverse proxy.
Below you can find a fully working code which uses both HTTP client and HTTP reverse proxy. In both cases I pass around the same HTTP request, but results are completely different. For this demo, I setup CouchDB with admin username and admin password, I used stdout writer which implements HTTP response writer, and I omit errors for simplicity:
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
)
// StdoutWriter provides the same functionality as http.ResponseWriter
// and print results to stdout.
type StdoutWriter string
// Header implements Header() API of http.ResponseWriter interface
func (s StdoutWriter) Header() http.Header {
return http.Header{}
}
// Write implements Write API of http.ResponseWriter interface
func (s StdoutWriter) Write(b []byte) (int, error) {
v := string(b)
log.Println(v)
return len(v), nil
}
// WriteHeader implements WriteHeader API of http.ResponseWriter interface
func (s StdoutWriter) WriteHeader(statusCode int) {
log.Println("statusCode", statusCode)
}
func main() {
surl := "http://admin:admin@localhost:5984/_all_dbs"
rurl, _ := url.Parse(surl)
log.Println("url", rurl, rurl.Host, rurl.Scheme, rurl.User)
r, _ := http.NewRequest("GET", surl, nil)
w := StdoutWriter("")
// make HTTP call via HTTP client
client := http.Client{}
resp, _ := client.Do(r)
log.Println("HTTP response", resp.Status)
// do the same via proxy
log.Println("proxy request with", rurl)
proxy := httputil.NewSingleHostReverseProxy(rurl)
proxy.ServeHTTP(w, r)
}
When you'll run this program (assuming that you have your local CouchDB running) you'll get the following output:
2022/02/04 16:01:19 url http://admin:admin@localhost:5984/_all_dbs localhost:5984 http admin:admin
2022/02/04 16:01:19 HTTP response 200 OK
2022/02/04 16:01:19 proxy request with http://admin:admin@localhost:5984/_all_dbs
2022/02/04 16:01:19 statusCode 401
2022/02/04 16:01:19 {"error":"unauthorized","reason":"You are not a server admin."}
As you can see the http client works as expected and provides 200 OK, while proxy fails because it does not pass properly user credentials.
What did you expect to see?
The proxy server should keep user credentials when passing HTTP request.
What did you see instead?
I see that reverse proxy does not pass user info within HTTP request and can't access requested resource.
The text was updated successfully, but these errors were encountered:
NewSingleHostReverseProxy returns a new ReverseProxy that routes URLs to the scheme, host, and base path provided in target
...
To rewrite Host headers, use ReverseProxy directly with a custom Director policy
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
Hi,
I'm trying to understand how to properly write proxy server which will properly handle user credentials in HTTP requests. For instance, let's say I have a CouchDB with admin:admin credentials, i.e. it should be accessed via
http://admin:admin@localhost:5984
URL. We can easily write simple program to access it via default HTTP client. My question is how to do the same using HTTP reverse proxy.Below you can find a fully working code which uses both HTTP client and HTTP reverse proxy. In both cases I pass around the same HTTP request, but results are completely different. For this demo, I setup CouchDB with admin username and admin password, I used stdout writer which implements HTTP response writer, and I omit errors for simplicity:
When you'll run this program (assuming that you have your local CouchDB running) you'll get the following output:
As you can see the http client works as expected and provides 200 OK, while proxy fails because it does not pass properly user credentials.
What did you expect to see?
The proxy server should keep user credentials when passing HTTP request.
What did you see instead?
I see that reverse proxy does not pass user info within HTTP request and can't access requested resource.
The text was updated successfully, but these errors were encountered: