|
Packit |
63bb0d |
package adal
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Copyright 2017 Microsoft Corporation
|
|
Packit |
63bb0d |
//
|
|
Packit |
63bb0d |
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
Packit |
63bb0d |
// you may not use this file except in compliance with the License.
|
|
Packit |
63bb0d |
// You may obtain a copy of the License at
|
|
Packit |
63bb0d |
//
|
|
Packit |
63bb0d |
// http://www.apache.org/licenses/LICENSE-2.0
|
|
Packit |
63bb0d |
//
|
|
Packit |
63bb0d |
// Unless required by applicable law or agreed to in writing, software
|
|
Packit |
63bb0d |
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
Packit |
63bb0d |
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
Packit |
63bb0d |
// See the License for the specific language governing permissions and
|
|
Packit |
63bb0d |
// limitations under the License.
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
import (
|
|
Packit |
63bb0d |
"crypto/tls"
|
|
Packit |
63bb0d |
"net/http"
|
|
Packit |
63bb0d |
"net/http/cookiejar"
|
|
Packit |
63bb0d |
"sync"
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
"github.com/Azure/go-autorest/tracing"
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
const (
|
|
Packit |
63bb0d |
contentType = "Content-Type"
|
|
Packit |
63bb0d |
mimeTypeFormPost = "application/x-www-form-urlencoded"
|
|
Packit |
63bb0d |
)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
var defaultSender Sender
|
|
Packit |
63bb0d |
var defaultSenderInit = &sync.Once{}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Sender is the interface that wraps the Do method to send HTTP requests.
|
|
Packit |
63bb0d |
//
|
|
Packit |
63bb0d |
// The standard http.Client conforms to this interface.
|
|
Packit |
63bb0d |
type Sender interface {
|
|
Packit |
63bb0d |
Do(*http.Request) (*http.Response, error)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// SenderFunc is a method that implements the Sender interface.
|
|
Packit |
63bb0d |
type SenderFunc func(*http.Request) (*http.Response, error)
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// Do implements the Sender interface on SenderFunc.
|
|
Packit |
63bb0d |
func (sf SenderFunc) Do(r *http.Request) (*http.Response, error) {
|
|
Packit |
63bb0d |
return sf(r)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// SendDecorator takes and possibly decorates, by wrapping, a Sender. Decorators may affect the
|
|
Packit |
63bb0d |
// http.Request and pass it along or, first, pass the http.Request along then react to the
|
|
Packit |
63bb0d |
// http.Response result.
|
|
Packit |
63bb0d |
type SendDecorator func(Sender) Sender
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// CreateSender creates, decorates, and returns, as a Sender, the default http.Client.
|
|
Packit |
63bb0d |
func CreateSender(decorators ...SendDecorator) Sender {
|
|
Packit |
63bb0d |
return DecorateSender(sender(), decorators...)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
// DecorateSender accepts a Sender and a, possibly empty, set of SendDecorators, which is applies to
|
|
Packit |
63bb0d |
// the Sender. Decorators are applied in the order received, but their affect upon the request
|
|
Packit |
63bb0d |
// depends on whether they are a pre-decorator (change the http.Request and then pass it along) or a
|
|
Packit |
63bb0d |
// post-decorator (pass the http.Request along and react to the results in http.Response).
|
|
Packit |
63bb0d |
func DecorateSender(s Sender, decorators ...SendDecorator) Sender {
|
|
Packit |
63bb0d |
for _, decorate := range decorators {
|
|
Packit |
63bb0d |
s = decorate(s)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
return s
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
|
|
Packit |
63bb0d |
func sender() Sender {
|
|
Packit |
63bb0d |
// note that we can't init defaultSender in init() since it will
|
|
Packit |
63bb0d |
// execute before calling code has had a chance to enable tracing
|
|
Packit |
63bb0d |
defaultSenderInit.Do(func() {
|
|
Packit |
63bb0d |
// Use behaviour compatible with DefaultTransport, but require TLS minimum version.
|
|
Packit |
63bb0d |
defaultTransport := http.DefaultTransport.(*http.Transport)
|
|
Packit |
63bb0d |
transport := &http.Transport{
|
|
Packit |
63bb0d |
Proxy: defaultTransport.Proxy,
|
|
Packit |
63bb0d |
DialContext: defaultTransport.DialContext,
|
|
Packit |
63bb0d |
MaxIdleConns: defaultTransport.MaxIdleConns,
|
|
Packit |
63bb0d |
IdleConnTimeout: defaultTransport.IdleConnTimeout,
|
|
Packit |
63bb0d |
TLSHandshakeTimeout: defaultTransport.TLSHandshakeTimeout,
|
|
Packit |
63bb0d |
ExpectContinueTimeout: defaultTransport.ExpectContinueTimeout,
|
|
Packit |
63bb0d |
TLSClientConfig: &tls.Config{
|
|
Packit |
63bb0d |
MinVersion: tls.VersionTLS12,
|
|
Packit |
63bb0d |
},
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
var roundTripper http.RoundTripper = transport
|
|
Packit |
63bb0d |
if tracing.IsEnabled() {
|
|
Packit |
63bb0d |
roundTripper = tracing.NewTransport(transport)
|
|
Packit |
63bb0d |
}
|
|
Packit |
63bb0d |
j, _ := cookiejar.New(nil)
|
|
Packit |
63bb0d |
defaultSender = &http.Client{Jar: j, Transport: roundTripper}
|
|
Packit |
63bb0d |
})
|
|
Packit |
63bb0d |
return defaultSender
|
|
Packit |
63bb0d |
}
|