Skip to content

Commit

Permalink
v3.2.0 No Longer Supports Proxy Settings (#198)
Browse files Browse the repository at this point in the history
* Adding ProxyFromEnvironment to http transport (#197)

* Switching to using DefaultTransport (#197)

* Reinstating equivalency check for server and proxy active connections (#197)

* Using http Transport with ProxyFromEnvironment set to determine if test failures are attributable to using http DefaultTransport (#197)

* Switching to using httputil single host reverse proxy for testing (#197)

* Removing unneeded files and moving test (#197)

* Adding some clarifying comments to test (#197)

* Updating CHANGELOG.md (#197)

* Use func to obtain proxy from environment to avoid issues with caching during testing (#197)

* Cloning default transport before modifying to avoid issues with caching during testing (#197)

* Apply suggestions from code review

Co-authored-by: Brian Flad <bflad417@gmail.com>

* Bumping golang.org/x/net to v0.1.0 (#197)

Co-authored-by: Brian Flad <bflad417@gmail.com>
  • Loading branch information
bendbennett and bflad authored Nov 7, 2022
1 parent a8616c2 commit bdf31bd
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 19 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
## 3.2.1 (unreleased)

BUG FIXES

* data-source/http: Using DefaultTransport to reinstate previous behavior (e.g., ProxyFromEnvironment) ([#198](https://github.com/hashicorp/terraform-provider-http/pull/198)).

## 3.2.0 (October 31, 2022)

ENHANCEMENTS:
Expand Down
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ require (
github.com/hashicorp/terraform-plugin-framework-validators v0.5.0
github.com/hashicorp/terraform-plugin-go v0.14.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.0
golang.org/x/net v0.1.0
)

require (
Expand Down Expand Up @@ -61,9 +62,8 @@ require (
github.com/vmihailenco/tagparser v0.1.2 // indirect
github.com/zclconf/go-cty v1.11.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/net v0.0.0-20220708220712-1185a9018129 // indirect
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/text v0.4.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20200711021454-869866162049 // indirect
google.golang.org/grpc v1.48.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20220708220712-1185a9018129 h1:vucSRfWwTsoXro7P+3Cjlr6flUMtzCwzlvkxEQtHHB0=
golang.org/x/net v0.0.0-20220708220712-1185a9018129/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -314,15 +314,15 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
Expand Down
44 changes: 34 additions & 10 deletions internal/provider/data_source_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@ import (
"io/ioutil"
"mime"
"net/http"
"net/url"
"regexp"
"strings"

"github.com/hashicorp/terraform-plugin-framework-validators/schemavalidator"
"github.com/hashicorp/terraform-plugin-framework/path"

"github.com/hashicorp/terraform-plugin-framework-validators/stringvalidator"
"github.com/hashicorp/terraform-plugin-framework/datasource"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/tfsdk"
"github.com/hashicorp/terraform-plugin-framework/types"
"golang.org/x/net/http/httpproxy"
)

var _ datasource.DataSource = (*httpDataSource)(nil)
Expand Down Expand Up @@ -151,7 +152,7 @@ func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
return
}

url := model.URL.ValueString()
requestURL := model.URL.ValueString()
method := model.Method.ValueString()
requestHeaders := model.RequestHeaders
requestBody := strings.NewReader(model.RequestBody.ValueString())
Expand All @@ -162,12 +163,32 @@ func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, r

caCertificate := model.CaCertificate

tr := &http.Transport{
TLSClientConfig: &tls.Config{},
tr, ok := http.DefaultTransport.(*http.Transport)
if !ok {
resp.Diagnostics.AddError(
"Error configuring http transport",
"Error http: Can't configure http transport.",
)
return
}

// Prevent issues with multiple data source configurations modifying the shared transport.
clonedTr := tr.Clone()

// Prevent issues with tests caching the proxy configuration.
clonedTr.Proxy = func(req *http.Request) (*url.URL, error) {
return httpproxy.FromEnvironment().ProxyFunc()(req.URL)
}

if clonedTr.TLSClientConfig == nil {
clonedTr.TLSClientConfig = &tls.Config{}
}

if !model.Insecure.IsNull() {
tr.TLSClientConfig.InsecureSkipVerify = model.Insecure.ValueBool()
if clonedTr.TLSClientConfig == nil {
clonedTr.TLSClientConfig = &tls.Config{}
}
clonedTr.TLSClientConfig.InsecureSkipVerify = model.Insecure.ValueBool()
}

// Use `ca_cert_pem` cert pool
Expand All @@ -181,14 +202,17 @@ func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
return
}

tr.TLSClientConfig.RootCAs = caCertPool
if clonedTr.TLSClientConfig == nil {
clonedTr.TLSClientConfig = &tls.Config{}
}
clonedTr.TLSClientConfig.RootCAs = caCertPool
}

client := &http.Client{
Transport: tr,
Transport: clonedTr,
}

request, err := http.NewRequestWithContext(ctx, method, url, requestBody)
request, err := http.NewRequestWithContext(ctx, method, requestURL, requestBody)
if err != nil {
resp.Diagnostics.AddError(
"Error creating request",
Expand Down Expand Up @@ -251,7 +275,7 @@ func (d *httpDataSource) Read(ctx context.Context, req datasource.ReadRequest, r
return
}

model.ID = types.StringValue(url)
model.ID = types.StringValue(requestURL)
model.ResponseHeaders = respHeadersState
model.ResponseBody = types.StringValue(responseBody)
model.Body = types.StringValue(responseBody)
Expand Down
72 changes: 72 additions & 0 deletions internal/provider/data_source_http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import (
"fmt"
"net/http"
"net/http/httptest"
"net/http/httputil"
"net/url"
"regexp"
"strings"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestDataSource_200(t *testing.T) {
Expand Down Expand Up @@ -471,6 +474,75 @@ func TestDataSource_UnsupportedInsecureCaCert(t *testing.T) {
})
}

// testProxiedURL is a hardcoded URL used in acceptance testing where it is
// expected that a locally started HTTP proxy will handle the request.
//
// Neither localhost nor the loopback interface (127.0.0.1) can be used for the
// address of the server as httpproxy/proxy.go will ignore these addresses.
//
// References:
// - https://cs.opensource.google/go/x/net/+/internal-branch.go1.19-vendor:http/httpproxy/proxy.go;l=181
// - https://cs.opensource.google/go/x/net/+/internal-branch.go1.19-vendor:http/httpproxy/proxy.go;l=186
const testProxiedURL = "http://terraform-provider-http-test-proxy"

func TestDataSource_HTTPViaProxyWithEnv(t *testing.T) {
proxyRequests := 0
serverRequests := 0

// Content-Type is set to text/plain otherwise the http data source issues a warning which
// causes Terraform 0.14 to not write any data to state.
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
serverRequests++
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
}))

defer server.Close()

serverURL, err := url.Parse(server.URL)

if err != nil {
t.Fatalf("error parsing server URL: %s", err)
}

proxy := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
proxyRequests++
httputil.NewSingleHostReverseProxy(serverURL).ServeHTTP(w, r)
}))
defer proxy.Close()

t.Setenv("HTTP_PROXY", proxy.URL)
t.Setenv("HTTPS_PROXY", proxy.URL)

resource.UnitTest(t, resource.TestCase{
ProtoV5ProviderFactories: protoV5ProviderFactories(),

Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
data "http" "http_test" {
url = "%s"
}
`, testProxiedURL),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr("data.http.http_test", "status_code", "200"),
CheckServerAndProxyRequestCount(&proxyRequests, &serverRequests),
),
},
},
})
}

func CheckServerAndProxyRequestCount(proxyRequestCount, serverRequestCount *int) resource.TestCheckFunc {
return func(_ *terraform.State) error {
if *proxyRequestCount != *serverRequestCount {
return fmt.Errorf("expected proxy and server request count to match: proxy was %d, while server was %d", *proxyRequestCount, *serverRequestCount)
}

return nil
}
}

type TestHttpMock struct {
server *httptest.Server
}
Expand Down

0 comments on commit bdf31bd

Please sign in to comment.