Skip to content

Commit

Permalink
Merge pull request #128 from roboslone/v1
Browse files Browse the repository at this point in the history
Fix concurrent map writes to oldClients
  • Loading branch information
maxatome authored May 6, 2022
2 parents 70189fd + da037fb commit fbf2267
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
14 changes: 14 additions & 0 deletions race_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package httpmock_test

import (
"net/http"
"testing"

. "github.com/jarcoal/httpmock"
)

func TestActivateNonDefaultRace(t *testing.T) {
for i := 0; i < 10; i++ {
go ActivateNonDefault(&http.Client{})
}
}
7 changes: 7 additions & 0 deletions transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,9 @@ var InitialTransport = http.DefaultTransport
// than http.DefaultClient).
var oldClients = map[*http.Client]http.RoundTripper{}

// oldClientsLock protects oldClients from concurrent writes.
var oldClientsLock sync.Mutex

// Activate starts the mock environment. This should be called before
// your tests run. Under the hood this replaces the Transport on the
// http.DefaultClient with httpmock.DefaultTransport.
Expand Down Expand Up @@ -826,6 +829,8 @@ func ActivateNonDefault(client *http.Client) {
}

// save the custom client & it's RoundTripper
oldClientsLock.Lock()
defer oldClientsLock.Unlock()
if _, ok := oldClients[client]; !ok {
oldClients[client] = client.Transport
}
Expand Down Expand Up @@ -887,6 +892,8 @@ func Deactivate() {
http.DefaultTransport = InitialTransport

// reset the custom clients to use their original RoundTripper
oldClientsLock.Lock()
defer oldClientsLock.Unlock()
for oldClient, oldTransport := range oldClients {
oldClient.Transport = oldTransport
delete(oldClients, oldClient)
Expand Down

0 comments on commit fbf2267

Please sign in to comment.