mirror of
				https://gitea.com/Lydanne/buildx.git
				synced 2025-11-04 10:03:42 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			106 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
Copyright 2017 The Kubernetes Authors.
 | 
						|
 | 
						|
Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
you may not use this file except in compliance with the License.
 | 
						|
You may obtain a copy of the License at
 | 
						|
 | 
						|
    http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 | 
						|
Unless required by applicable law or agreed to in writing, software
 | 
						|
distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
See the License for the specific language governing permissions and
 | 
						|
limitations under the License.
 | 
						|
*/
 | 
						|
 | 
						|
package spdy
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
	"net/url"
 | 
						|
	"time"
 | 
						|
 | 
						|
	"k8s.io/apimachinery/pkg/util/httpstream"
 | 
						|
	"k8s.io/apimachinery/pkg/util/httpstream/spdy"
 | 
						|
	restclient "k8s.io/client-go/rest"
 | 
						|
)
 | 
						|
 | 
						|
// Upgrader validates a response from the server after a SPDY upgrade.
 | 
						|
type Upgrader interface {
 | 
						|
	// NewConnection validates the response and creates a new Connection.
 | 
						|
	NewConnection(resp *http.Response) (httpstream.Connection, error)
 | 
						|
}
 | 
						|
 | 
						|
// RoundTripperFor returns a round tripper and upgrader to use with SPDY.
 | 
						|
func RoundTripperFor(config *restclient.Config) (http.RoundTripper, Upgrader, error) {
 | 
						|
	tlsConfig, err := restclient.TLSConfigFor(config)
 | 
						|
	if err != nil {
 | 
						|
		return nil, nil, err
 | 
						|
	}
 | 
						|
	proxy := http.ProxyFromEnvironment
 | 
						|
	if config.Proxy != nil {
 | 
						|
		proxy = config.Proxy
 | 
						|
	}
 | 
						|
	upgradeRoundTripper := spdy.NewRoundTripperWithConfig(spdy.RoundTripperConfig{
 | 
						|
		TLS:                      tlsConfig,
 | 
						|
		FollowRedirects:          true,
 | 
						|
		RequireSameHostRedirects: false,
 | 
						|
		Proxier:                  proxy,
 | 
						|
		PingPeriod:               time.Second * 5,
 | 
						|
	})
 | 
						|
	wrapper, err := restclient.HTTPWrappersForConfig(config, upgradeRoundTripper)
 | 
						|
	if err != nil {
 | 
						|
		return nil, nil, err
 | 
						|
	}
 | 
						|
	return wrapper, upgradeRoundTripper, nil
 | 
						|
}
 | 
						|
 | 
						|
// dialer implements the httpstream.Dialer interface.
 | 
						|
type dialer struct {
 | 
						|
	client   *http.Client
 | 
						|
	upgrader Upgrader
 | 
						|
	method   string
 | 
						|
	url      *url.URL
 | 
						|
}
 | 
						|
 | 
						|
var _ httpstream.Dialer = &dialer{}
 | 
						|
 | 
						|
// NewDialer will create a dialer that connects to the provided URL and upgrades the connection to SPDY.
 | 
						|
func NewDialer(upgrader Upgrader, client *http.Client, method string, url *url.URL) httpstream.Dialer {
 | 
						|
	return &dialer{
 | 
						|
		client:   client,
 | 
						|
		upgrader: upgrader,
 | 
						|
		method:   method,
 | 
						|
		url:      url,
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (d *dialer) Dial(protocols ...string) (httpstream.Connection, string, error) {
 | 
						|
	req, err := http.NewRequest(d.method, d.url.String(), nil)
 | 
						|
	if err != nil {
 | 
						|
		return nil, "", fmt.Errorf("error creating request: %v", err)
 | 
						|
	}
 | 
						|
	return Negotiate(d.upgrader, d.client, req, protocols...)
 | 
						|
}
 | 
						|
 | 
						|
// Negotiate opens a connection to a remote server and attempts to negotiate
 | 
						|
// a SPDY connection. Upon success, it returns the connection and the protocol selected by
 | 
						|
// the server. The client transport must use the upgradeRoundTripper - see RoundTripperFor.
 | 
						|
func Negotiate(upgrader Upgrader, client *http.Client, req *http.Request, protocols ...string) (httpstream.Connection, string, error) {
 | 
						|
	for i := range protocols {
 | 
						|
		req.Header.Add(httpstream.HeaderProtocolVersion, protocols[i])
 | 
						|
	}
 | 
						|
	resp, err := client.Do(req)
 | 
						|
	if err != nil {
 | 
						|
		return nil, "", fmt.Errorf("error sending request: %v", err)
 | 
						|
	}
 | 
						|
	defer resp.Body.Close()
 | 
						|
	conn, err := upgrader.NewConnection(resp)
 | 
						|
	if err != nil {
 | 
						|
		return nil, "", err
 | 
						|
	}
 | 
						|
	return conn, resp.Header.Get(httpstream.HeaderProtocolVersion), nil
 | 
						|
}
 |