Skip to content

Commit 7976fc0

Browse files
DiogoSantossKaloyanTanev
authored andcommitted
http: translate basic authentication in url to authorization header (#13)
1 parent 7282a04 commit 7976fc0

2 files changed

Lines changed: 60 additions & 1 deletion

File tree

http/http_internal_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,38 @@ func TestParseAddress(t *testing.T) {
9696
}
9797
}
9898

99+
func TestParseBasicAuth(t *testing.T) {
100+
tests := []struct {
101+
name string
102+
address string
103+
headers map[string]string
104+
expHeaders map[string]string
105+
err string
106+
}{
107+
{
108+
name: "Simple",
109+
address: "http://user:pass@foo.com",
110+
expHeaders: map[string]string{"Authorization": "Basic dXNlcjpwYXNz"},
111+
},
112+
{
113+
name: "Invalid",
114+
address: "http:// foo",
115+
err: "failed to parse address",
116+
},
117+
}
118+
for _, test := range tests {
119+
t.Run(test.name, func(t *testing.T) {
120+
newHeaders, err := parseBasicAuth(test.address, test.headers)
121+
if test.err != "" {
122+
require.EqualError(t, err, test.err)
123+
} else {
124+
require.NoError(t, err)
125+
require.Equal(t, test.expHeaders, newHeaders)
126+
}
127+
})
128+
}
129+
}
130+
99131
func mustParseURL(input string) *url.URL {
100132
base, _, err := parseAddress(input)
101133
if err != nil {

http/service.go

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@ package http
1515

1616
import (
1717
"context"
18+
"encoding/base64"
1819
"errors"
1920
"fmt"
21+
"maps"
2022
"net"
2123
"net/http"
2224
"net/url"
@@ -112,6 +114,11 @@ func New(ctx context.Context, params ...Parameter) (client.Service, error) {
112114
}
113115
}
114116

117+
extraHeaders, err := parseBasicAuth(parameters.address, parameters.extraHeaders)
118+
if err != nil {
119+
return nil, err
120+
}
121+
115122
base, address, err := parseAddress(parameters.address)
116123
if err != nil {
117124
return nil, err
@@ -125,7 +132,7 @@ func New(ctx context.Context, params ...Parameter) (client.Service, error) {
125132
timeout: parameters.timeout,
126133
userIndexChunkSize: parameters.indexChunkSize,
127134
userPubKeyChunkSize: parameters.pubKeyChunkSize,
128-
extraHeaders: parameters.extraHeaders,
135+
extraHeaders: extraHeaders,
129136
enforceJSON: parameters.enforceJSON,
130137
pingSem: semaphore.NewWeighted(1),
131138
hooks: parameters.hooks,
@@ -425,3 +432,23 @@ func parseAddress(address string) (*url.URL, *url.URL, error) {
425432

426433
return base, &baseAddress, nil
427434
}
435+
436+
// parseBasicAuth adds an HTTP Basic Authorization header to a copy of the provided headers map if the address contains credentials.
437+
// If no credentials are present, it returns the original headers.
438+
func parseBasicAuth(address string, headers map[string]string) (map[string]string, error) {
439+
parsedURL, err := url.Parse(address)
440+
if err != nil {
441+
return nil, errors.New("failed to parse address")
442+
}
443+
if parsedURL.User == nil {
444+
return headers, nil
445+
}
446+
447+
headersWithAuth := make(map[string]string, len(headers)+1)
448+
maps.Copy(headersWithAuth, headers)
449+
450+
password, _ := parsedURL.User.Password()
451+
headersWithAuth["Authorization"] = "Basic " + base64.StdEncoding.EncodeToString([]byte(parsedURL.User.Username()+":"+password))
452+
453+
return headersWithAuth, nil
454+
}

0 commit comments

Comments
 (0)