httpclient

package
v0.260.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 13, 2024 License: Apache-2.0 Imports: 27 Imported by: 72

Documentation

Overview

Package httpclient provides HTTP client and outgoing HTTP request middleware.

Index

Examples

Constants

View Source
const BasicAuthenticationMiddlewareName = "BasicAuth"

BasicAuthenticationMiddlewareName is the middleware name used by BasicAuthenticationMiddleware.

View Source
const ContextualMiddlewareName = "contextual-middleware"

ContextualMiddlewareName is the middleware name used by ContextualMiddleware.

View Source
const CustomHeadersMiddlewareName = "CustomHeaders"

CustomHeadersMiddlewareName is the middleware name used by CustomHeadersMiddleware.

View Source
const DataSourceMetricsMiddlewareName = "datasource_metrics"
View Source
const ErrorSourceMiddlewareName = "ErrorSource"

ErrorSourceMiddlewareName is the middleware name used by ErrorSourceMiddleware.

View Source
const ResponseLimitMiddlewareName = "response-limit"

ResponseLimitMiddlewareName is the middleware name used by ResponseLimitMiddleware.

View Source
const (
	TracingMiddlewareName = "Tracing"
)

Variables

View Source
var DefaultTimeoutOptions = TimeoutOptions{
	Timeout:               30 * time.Second,
	DialTimeout:           10 * time.Second,
	KeepAlive:             30 * time.Second,
	TLSHandshakeTimeout:   10 * time.Second,
	ExpectContinueTimeout: 1 * time.Second,
	MaxConnsPerHost:       0,
	MaxIdleConns:          100,
	MaxIdleConnsPerHost:   100,
	IdleConnTimeout:       90 * time.Second,
}

DefaultTimeoutOptions default timeout/connection options.

View Source
var ErrResponseBodyTooLarge = errors.New("http: response body too large")

ErrResponseBodyTooLarge indicates response body is too large

Functions

func CountBytesReader added in v0.245.0

func CountBytesReader(reader io.ReadCloser, callback CloseCallbackFunc) io.ReadCloser

CountBytesReader counts the total amount of bytes read from the underlying reader.

The provided callback func will be called before the underlying reader is closed.

func ErrorSourceRoundTripper added in v0.260.0

func ErrorSourceRoundTripper(_ Options, next http.RoundTripper) http.RoundTripper

ErrorSourceRoundTripper inspect the response error and wraps it in a status.DownstreamError if status.IsDownstreamHTTPError returns true.

func GetTLSConfig

func GetTLSConfig(opts ...Options) (*tls.Config, error)

GetTLSConfig creates a new tls.Config given provided options. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	tlsConfig, err := httpclient.GetTLSConfig(httpclient.Options{
		TLS: &httpclient.TLSOptions{
			InsecureSkipVerify: true,
		}})
	if err != nil {
		log.Fatalf("failed to get TLS config. error: %s", err)
	}

	client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: tlsConfig,
		},
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

func GetTransport

func GetTransport(opts ...Options) (http.RoundTripper, error)

GetTransport creates a new http.RoundTripper given provided options. If opts is nil the http.DefaultTransport will be returned. If no middlewares are provided the DefaultMiddlewares() will be used. If you provide middlewares you have to manually add the DefaultMiddlewares() for it to be enabled. Note: Middlewares will be executed in the same order as provided. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	transport, err := httpclient.GetTransport(httpclient.Options{
		Timeouts: &httpclient.TimeoutOptions{
			Timeout: 5 * time.Second,
		},
		Middlewares: []httpclient.Middleware{
			httpclient.MiddlewareFunc(func(_ httpclient.Options, next http.RoundTripper) http.RoundTripper {
				return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
					log.Println("Before outgoing request")
					res, err := next.RoundTrip(req)
					log.Println("After outgoing request")
					return res, err
				})
			}),
		},
	})
	if err != nil {
		log.Fatalf("failed to get HTTP transport. error: %s", err)
	}

	client := http.Client{
		Transport: transport,
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

func MaxBytesReader added in v0.215.0

func MaxBytesReader(r io.ReadCloser, n int64) io.ReadCloser

MaxBytesReader is similar to io.LimitReader but is intended for limiting the size of incoming request bodies. In contrast to io.LimitReader, MaxBytesReader's result is a ReadCloser, returns a non-EOF error for a Read beyond the limit, and closes the underlying reader when its Close method is called.

MaxBytesReader prevents clients from accidentally or maliciously sending a large request and wasting server resources.

func New

func New(opts ...Options) (*http.Client, error)

New creates a new http.Client. If opts is nil the http.DefaultClient will be returned. If no middlewares are provided the DefaultMiddlewares will be used. If you provide middlewares you have to manually add the DefaultMiddlewares for it to be enabled. Note: Middlewares will be executed in the same order as provided. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	client, err := httpclient.New(httpclient.Options{
		Timeouts: &httpclient.TimeoutOptions{
			Timeout: 5 * time.Second,
		},
		Middlewares: []httpclient.Middleware{
			httpclient.MiddlewareFunc(func(_ httpclient.Options, next http.RoundTripper) http.RoundTripper {
				return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
					log.Println("Before outgoing request")
					res, err := next.RoundTrip(req)
					log.Println("After outgoing request")
					return res, err
				})
			}),
		},
	})
	if err != nil {
		log.Fatalf("failed to create HTTP client. error: %s", err)
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

func WithContextualMiddleware added in v0.137.0

func WithContextualMiddleware(parent context.Context, middlewares ...Middleware) context.Context

WithContextualMiddleware returns a copy of parent in which the provided middlewares is associated. If contextual middleware already exists, new middleware will be appended.

Example
package main

import (
	"context"
	"log"
	"net/http"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	provider := httpclient.NewProvider()
	client, err := provider.New()
	if err != nil {
		log.Fatalf("failed to create HTTP client. error: %s", err)
	}

	parent := context.Background()
	ctx := httpclient.WithContextualMiddleware(parent,
		httpclient.MiddlewareFunc(func(_ httpclient.Options, next http.RoundTripper) http.RoundTripper {
			return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
				req.Header.Set("X-Custom-Header", "val")

				return next.RoundTrip(req)
			})
		}))

	req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://www.google.com", nil)
	if err != nil {
		log.Fatalf("failed to create request. error: %s", err)
	}

	rsp, err := client.Do(req)
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

Types

type BasicAuthOptions

type BasicAuthOptions struct {
	User     string
	Password string
}

BasicAuthOptions basic authentication options.

type CloseCallbackFunc added in v0.245.0

type CloseCallbackFunc func(bytesRead int64)

type ConfigureClientFunc

type ConfigureClientFunc func(opts Options, client *http.Client)

ConfigureClientFunc function signature for configuring http.Client. Called after http.Client creation.

type ConfigureMiddlewareFunc

type ConfigureMiddlewareFunc func(opts Options, existingMiddleware []Middleware) []Middleware

ConfigureMiddlewareFunc function signature for configuring middleware chain.

type ConfigureTLSConfigFunc

type ConfigureTLSConfigFunc func(opts Options, tlsConfig *tls.Config)

ConfigureTLSConfigFunc function signature for configuring tls.Config. Called after tls.Config creation.

type ConfigureTransportFunc

type ConfigureTransportFunc func(opts Options, transport *http.Transport)

ConfigureTransportFunc function signature for configuring http.Transport. Called after http.Transport creation.

type Middleware

type Middleware interface {
	// CreateMiddleware creates a new middleware.
	CreateMiddleware(opts Options, next http.RoundTripper) http.RoundTripper
}

Middleware is an interface representing the ability to create a middleware that implements the http.RoundTripper interface.

func BasicAuthenticationMiddleware

func BasicAuthenticationMiddleware() Middleware

BasicAuthenticationMiddleware applies basic authentication to the HTTP header "Authorization" in the outgoing request. If Authorization header is already set, it will not be overridden by this middleware. If opts.BasicAuth is nil, next will be returned.

func ContextualMiddleware added in v0.137.0

func ContextualMiddleware() Middleware

ContextualMiddleware is a middleware that allows the outgoing request to be modified with contextual middlewares. Use WithContextualMiddleware to provide contextual middlewares.

func ContextualMiddlewareFromContext added in v0.137.0

func ContextualMiddlewareFromContext(ctx context.Context) []Middleware

ContextualMiddlewareFromContext returns middlewares from context, if any.

func CustomHeadersMiddleware

func CustomHeadersMiddleware() Middleware

CustomHeadersMiddleware applies custom HTTP headers to the outgoing request.

If opts.Headers is empty, next will be returned.

func DataSourceMetricsMiddleware added in v0.259.0

func DataSourceMetricsMiddleware() Middleware

func DefaultMiddlewares

func DefaultMiddlewares() []Middleware

DefaultMiddlewares is the default middleware applied when creating new HTTP clients and no middleware is provided. TracingMiddleware, BasicAuthenticationMiddleware and CustomHeadersMiddleware are the default middlewares.

func ErrorSourceMiddleware added in v0.253.0

func ErrorSourceMiddleware() Middleware

ErrorSourceMiddleware inspect the response error and wraps it in a status.DownstreamError if status.IsDownstreamHTTPError returns true.

func NamedMiddlewareFunc

func NamedMiddlewareFunc(name string, fn MiddlewareFunc) Middleware

NamedMiddlewareFunc type is an adapter to allow the use of ordinary functions as Middleware. If f is a function with the appropriate signature, NamedMiddlewareFunc(f) is a Middleware that calls f.

func ResponseLimitMiddleware added in v0.215.0

func ResponseLimitMiddleware(limit int64) Middleware

func TracingMiddleware added in v0.157.0

func TracingMiddleware(tracer trace.Tracer) Middleware

TracingMiddleware is a middleware that creates spans for each outgoing request, tracking the url, method and response code as span attributes. If tracer is nil, it will use tracing.DefaultTracer().

type MiddlewareFunc

type MiddlewareFunc func(opts Options, next http.RoundTripper) http.RoundTripper

The MiddlewareFunc type is an adapter to allow the use of ordinary functions as Middlewares. If f is a function with the appropriate signature, MiddlewareFunc(f) is a Middleware that calls f.

func (MiddlewareFunc) CreateMiddleware

func (fn MiddlewareFunc) CreateMiddleware(opts Options, next http.RoundTripper) http.RoundTripper

CreateMiddleware implements the Middleware interface.

type MiddlewareName

type MiddlewareName interface {
	// MiddlewareName returns the middleware name.
	MiddlewareName() string
}

MiddlewareName is an interface representing the ability for a middleware to have a name.

type Options

type Options struct {
	// Timeouts timeout/connection related options.
	Timeouts *TimeoutOptions

	// BasicAuth basic authentication related options.
	BasicAuth *BasicAuthOptions

	// TLS related options.
	TLS *TLSOptions

	// SigV4 related options.
	SigV4 *SigV4Config

	// Proxy related options.
	ProxyOptions *proxy.Options

	// Headers custom headers.
	Header http.Header

	// CustomOptions allows custom options to be provided.
	CustomOptions map[string]interface{}

	// Labels could be used by certain middlewares.
	Labels map[string]string

	// Middlewares optionally provide additional middlewares.
	Middlewares []Middleware

	// ConfigureMiddleware optionally provide a ConfigureMiddlewareFunc
	// to modify the middlewares chain.
	ConfigureMiddleware ConfigureMiddlewareFunc

	// ConfigureClient optionally provide a ConfigureClientFunc
	// to modify the created http.Client.
	ConfigureClient ConfigureClientFunc

	// ConfigureTransport optionally provide a ConfigureTransportFunc
	// to modify the created http.Client.
	ConfigureTransport ConfigureTransportFunc

	// ConfigureTLSConfig optionally provide a ConfigureTLSConfigFunc
	// to modify the created http.Client.
	ConfigureTLSConfig ConfigureTLSConfigFunc

	// ForwardHTTPHeaders enable forwarding of all HTTP headers
	// included in backend.QueryDataRequest, backend.CallResourceRequest,
	// backend.CheckHealthRequest, e.g. based on if Allowed cookies or
	// Forward OAuth Identity is configured for the datasource or any
	// other forwarded HTTP header from Grafana.
	ForwardHTTPHeaders bool
}

Options defines options for creating HTTP clients.

type Provider

type Provider struct {
	Opts ProviderOptions
}

Provider is the default HTTP client provider implementation.

func NewProvider

func NewProvider(opts ...ProviderOptions) *Provider

NewProvider creates a new HTTP client provider. Optionally provide ProviderOptions which will be used as a fallback if no Options are provided to Provider.New, Provider.GetTransport or Provider.GetTLSConfig. If no middlewares are provided in opts the DefaultMiddlewares() will be used. If you provide middlewares you have to manually add the DefaultMiddlewares() for it to be enabled. Note: Middlewares will be executed in the same order as provided. Note: If more than one ProviderOption is provided a panic is raised.

Example
package main

import (
	"log"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	provider := httpclient.NewProvider(httpclient.ProviderOptions{Middlewares: []httpclient.Middleware{httpclient.CustomHeadersMiddleware()}})
	log.Printf("Middleware length: %d", len(provider.Opts.Middlewares))
}
Output:

func (*Provider) GetTLSConfig

func (p *Provider) GetTLSConfig(opts ...Options) (*tls.Config, error)

GetTLSConfig creates a new tls.Config given provided options. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	provider := httpclient.NewProvider(httpclient.ProviderOptions{Middlewares: []httpclient.Middleware{httpclient.CustomHeadersMiddleware()}})
	tlsConfig, err := provider.GetTLSConfig(httpclient.Options{
		TLS: &httpclient.TLSOptions{
			InsecureSkipVerify: true,
		}})
	if err != nil {
		log.Fatalf("failed to get TLS config. error: %s", err)
	}

	client := http.Client{
		Transport: &http.Transport{
			TLSClientConfig: tlsConfig,
		},
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

func (*Provider) GetTransport

func (p *Provider) GetTransport(opts ...Options) (http.RoundTripper, error)

GetTransport creates a new http.RoundTripper given provided options. If opts is nil the http.DefaultTransport will be returned and no outgoing request middleware applied. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	provider := httpclient.NewProvider(httpclient.ProviderOptions{Middlewares: []httpclient.Middleware{httpclient.CustomHeadersMiddleware()}})

	transport, err := provider.GetTransport(httpclient.Options{
		Timeouts: &httpclient.TimeoutOptions{
			Timeout: 5 * time.Second,
		},
		Middlewares: []httpclient.Middleware{
			httpclient.MiddlewareFunc(func(_ httpclient.Options, next http.RoundTripper) http.RoundTripper {
				return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
					log.Println("Before outgoing request")
					res, err := next.RoundTrip(req)
					log.Println("After outgoing request")
					return res, err
				})
			}),
		},
	})
	if err != nil {
		log.Fatalf("failed to get HTTP transport. error: %s", err)
	}

	client := http.Client{
		Transport: transport,
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

func (*Provider) New

func (p *Provider) New(opts ...Options) (*http.Client, error)

New creates a new http.Client given provided options. Note: If more than one Options is provided a panic is raised.

Example
package main

import (
	"log"
	"net/http"
	"time"

	"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
)

func main() {
	provider := httpclient.NewProvider(httpclient.ProviderOptions{Middlewares: []httpclient.Middleware{httpclient.CustomHeadersMiddleware()}})

	client, err := provider.New(httpclient.Options{
		Timeouts: &httpclient.TimeoutOptions{
			Timeout: 5 * time.Second,
		},
		Middlewares: []httpclient.Middleware{
			httpclient.MiddlewareFunc(func(_ httpclient.Options, next http.RoundTripper) http.RoundTripper {
				return httpclient.RoundTripperFunc(func(req *http.Request) (*http.Response, error) {
					log.Println("Before outgoing request")
					res, err := next.RoundTrip(req)
					log.Println("After outgoing request")
					return res, err
				})
			}),
		},
	})
	if err != nil {
		log.Fatalf("failed to create HTTP client. error: %s", err)
	}

	rsp, err := client.Get("http://www.google.com")
	if err != nil {
		log.Fatalf("failed to GET. error: %s", err)
	}
	if err := rsp.Body.Close(); err != nil {
		log.Printf("failed to close response body. error: %s", err)
	}

	log.Printf("Got response: %v", rsp.StatusCode)
}
Output:

type ProviderOptions

type ProviderOptions struct {
	// Timeouts timeout/connection related options.
	Timeout *TimeoutOptions

	TLS *TLSOptions

	// Middlewares optionally provides additional middlewares.
	Middlewares []Middleware

	// ConfigureMiddleware optionally provide a ConfigureMiddlewareFunc
	// to modify the middlewares chain.
	ConfigureMiddleware ConfigureMiddlewareFunc

	// ConfigureClient optionally provide a ConfigureClientFunc
	// to modify the created http.Client.
	ConfigureClient ConfigureClientFunc

	// ConfigureTransport optionally provide a ConfigureTransportFunc
	// to modify the created http.Client.
	ConfigureTransport ConfigureTransportFunc

	// ConfigureTLSConfig optionally provide a ConfigureTLSConfigFunc
	// to modify the created http.Client.
	ConfigureTLSConfig ConfigureTLSConfigFunc
}

ProviderOptions are the options that will be used as default if not specified in Options provided to Provider.New, Provider.GetTransport and Provider.GetTLSConfig.

type RoundTripperFunc

type RoundTripperFunc func(req *http.Request) (*http.Response, error)

The RoundTripperFunc type is an adapter to allow the use of ordinary functions as RoundTrippers. If f is a function with the appropriate signature, RountTripperFunc(f) is a RoundTripper that calls f.

func (RoundTripperFunc) RoundTrip

func (rt RoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error)

RoundTrip implements the RoundTripper interface.

type SigV4Config

type SigV4Config struct {
	AuthType      string
	Profile       string
	Service       string
	AccessKey     string
	SecretKey     string
	AssumeRoleARN string
	ExternalID    string
	Region        string
}

SigV4Config AWS SigV4 options.

type TLSOptions

type TLSOptions struct {
	CACertificate      string
	ClientCertificate  string
	ClientKey          string
	InsecureSkipVerify bool
	ServerName         string

	// MinVersion configures the tls.Config.MinVersion.
	MinVersion uint16

	// MaxVersion configures the tls.Config.MaxVersion.
	MaxVersion uint16
}

TLSOptions TLS options.

type TimeoutOptions

type TimeoutOptions struct {
	Timeout               time.Duration
	DialTimeout           time.Duration
	KeepAlive             time.Duration
	TLSHandshakeTimeout   time.Duration
	ExpectContinueTimeout time.Duration
	MaxConnsPerHost       int
	MaxIdleConns          int
	MaxIdleConnsPerHost   int
	IdleConnTimeout       time.Duration
}

TimeoutOptions timeout/connection options.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL