Skip to content

Commit

Permalink
Restrict HTTP Client to one host
Browse files Browse the repository at this point in the history
The HTTP Client returned by bifrost.HTTPClient can make requests
to only the configured API URL host.
  • Loading branch information
ananthb committed May 5, 2023
1 parent a1ff2a0 commit 81b1f1d
Showing 1 changed file with 34 additions and 7 deletions.
41 changes: 34 additions & 7 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,44 @@ package bifrost

import (
"crypto/tls"
"fmt"
"net/http"
"net/url"
)

// HTTPClient returns a HTTP client that uses the provided certificate for
// mutual TLS authentication.
func HTTPClient(cert *tls.Certificate) *http.Client {
type singleHostRoundTripper struct {
apiurl *url.URL
transport http.RoundTripper
}

func (s singleHostRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) {
r.URL.Scheme = s.apiurl.Scheme
r.URL.Host = s.apiurl.Host
path, err := url.JoinPath(s.apiurl.Path, r.URL.Path)
if err != nil {
return nil, fmt.Errorf("error joining request path with apiurl path: %w", err)
}
r.URL.Path = path
return s.transport.RoundTrip(r)
}

// HTTPClient returns a HTTP client set up for mTLS with the provided api URL.
// The returned client will only send requests to the api URL host.
// The request path will be joined with the api URL path, if any.
// The client will use the provided TLS client certificate to identify itself.
func HTTPClient(apiUrl string, clientCert *tls.Certificate) (*http.Client, error) {
u, err := url.Parse(apiUrl)
if err != nil {
return nil, err
}
return &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{*cert},
Transport: &singleHostRoundTripper{
apiurl: u,
transport: &http.Transport{
TLSClientConfig: &tls.Config{
Certificates: []tls.Certificate{*clientCert},
},
},
},
}
}, nil
}

0 comments on commit 81b1f1d

Please sign in to comment.