mirror of
https://github.com/thegeeklab/wp-plugin-go.git
synced 2024-11-23 06:40:40 +00:00
feat: add network struct to expose http client and options (#12)
This commit is contained in:
parent
d3d0d5bb06
commit
b5465c55af
@ -41,7 +41,7 @@ func Flags() []cli.Flag {
|
|||||||
|
|
||||||
// Plugin flags
|
// Plugin flags
|
||||||
flags = append(flags, loggingFlags(FlagsPluginCategory)...)
|
flags = append(flags, loggingFlags(FlagsPluginCategory)...)
|
||||||
flags = append(flags, httpClientFlags(FlagsPluginCategory)...)
|
flags = append(flags, networkFlags(FlagsPluginCategory)...)
|
||||||
|
|
||||||
return flags
|
return flags
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,9 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog"
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
"github.com/thegeeklab/wp-plugin-go/trace"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
)
|
)
|
||||||
@ -34,7 +36,23 @@ const (
|
|||||||
HTTPTransportMaxIdleConns = 100
|
HTTPTransportMaxIdleConns = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
func httpClientFlags(category string) []cli.Flag {
|
// Network contains options for connecting to the network.
|
||||||
|
type Network struct {
|
||||||
|
// Context for making network requests.
|
||||||
|
//
|
||||||
|
// If `trace` logging is requested the context will use `httptrace` to
|
||||||
|
// capture all network requests.
|
||||||
|
//nolint:containedctx
|
||||||
|
Context context.Context
|
||||||
|
|
||||||
|
/// Whether SSL verification is skipped
|
||||||
|
SkipVerify bool
|
||||||
|
|
||||||
|
// Client for making network requests.
|
||||||
|
Client *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func networkFlags(category string) []cli.Flag {
|
||||||
return []cli.Flag{
|
return []cli.Flag{
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "transport.skip-verify",
|
Name: "transport.skip-verify",
|
||||||
@ -57,9 +75,10 @@ func httpClientFlags(category string) []cli.Flag {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func HTTPClientFromContext(ctx *cli.Context) *http.Client {
|
func NetworkFromContext(ctx *cli.Context) Network {
|
||||||
var (
|
var (
|
||||||
skip = ctx.Bool("transport.skip-verify")
|
skip = ctx.Bool("transport.skip-verify")
|
||||||
|
defaultContext = context.Background()
|
||||||
socks = ctx.String("transport.socks-proxy")
|
socks = ctx.String("transport.socks-proxy")
|
||||||
socksoff = ctx.Bool("transport.socks-proxy-off")
|
socksoff = ctx.Bool("transport.socks-proxy-off")
|
||||||
)
|
)
|
||||||
@ -106,7 +125,17 @@ func HTTPClientFromContext(ctx *cli.Context) *http.Client {
|
|||||||
transport.DialContext = dialer.DialContext
|
transport.DialContext = dialer.DialContext
|
||||||
}
|
}
|
||||||
|
|
||||||
return &http.Client{
|
if zerolog.GlobalLevel() == zerolog.TraceLevel {
|
||||||
|
defaultContext = trace.HTTP(defaultContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &http.Client{
|
||||||
Transport: transport,
|
Transport: transport,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return Network{
|
||||||
|
Context: defaultContext,
|
||||||
|
SkipVerify: skip,
|
||||||
|
Client: client,
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,7 +17,6 @@ package plugin
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -46,7 +45,8 @@ type Options struct {
|
|||||||
type Plugin struct {
|
type Plugin struct {
|
||||||
app *cli.App
|
app *cli.App
|
||||||
execute ExecuteFunc
|
execute ExecuteFunc
|
||||||
client *http.Client
|
// Network options.
|
||||||
|
Network Network
|
||||||
// Metadata of the current pipeline.
|
// Metadata of the current pipeline.
|
||||||
Metadata Metadata
|
Metadata Metadata
|
||||||
}
|
}
|
||||||
@ -87,7 +87,7 @@ func (p *Plugin) action(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
p.Metadata = MetadataFromContext(ctx)
|
p.Metadata = MetadataFromContext(ctx)
|
||||||
p.client = HTTPClientFromContext(ctx)
|
p.Network = NetworkFromContext(ctx)
|
||||||
|
|
||||||
if p.execute == nil {
|
if p.execute == nil {
|
||||||
panic("plugin execute function is not set")
|
panic("plugin execute function is not set")
|
||||||
@ -96,11 +96,6 @@ func (p *Plugin) action(ctx *cli.Context) error {
|
|||||||
return p.execute(ctx.Context, ctx)
|
return p.execute(ctx.Context, ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTPClient returns the http.Client instance.
|
|
||||||
func (p *Plugin) HTTPClient() *http.Client {
|
|
||||||
return p.client
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run the plugin.
|
// Run the plugin.
|
||||||
func (p *Plugin) Run() {
|
func (p *Plugin) Run() {
|
||||||
if err := p.app.Run(os.Args); err != nil {
|
if err := p.app.Run(os.Args); err != nil {
|
||||||
|
119
trace/http.go
Normal file
119
trace/http.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright (c) 2019, Drone Plugins project authors
|
||||||
|
// Copyright (c) 2021, Robert Kaussow <mail@thegeeklab.de>
|
||||||
|
|
||||||
|
// Use of this source code is governed by an Apache 2.0 license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
package trace
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"net/http/httptrace"
|
||||||
|
"net/textproto"
|
||||||
|
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HTTP uses httptrace to log all network activity for HTTP requests.
|
||||||
|
func HTTP(ctx context.Context) context.Context {
|
||||||
|
return httptrace.WithClientTrace(ctx, &httptrace.ClientTrace{
|
||||||
|
GetConn: func(hostPort string) {
|
||||||
|
log.Trace().Str("host-port", hostPort).Msg("ClientTrace.GetConn")
|
||||||
|
},
|
||||||
|
|
||||||
|
GotConn: func(connInfo httptrace.GotConnInfo) {
|
||||||
|
log.Trace().
|
||||||
|
Str("local-address", connInfo.Conn.LocalAddr().String()).
|
||||||
|
Str("remote-address", connInfo.Conn.RemoteAddr().String()).
|
||||||
|
Bool("reused", connInfo.Reused).
|
||||||
|
Bool("was-idle", connInfo.WasIdle).
|
||||||
|
Dur("idle-time", connInfo.IdleTime).
|
||||||
|
Msg("ClientTrace.GoConn")
|
||||||
|
},
|
||||||
|
|
||||||
|
PutIdleConn: func(err error) {
|
||||||
|
log.Trace().Err(err).Msg("ClientTrace.GoConn")
|
||||||
|
},
|
||||||
|
|
||||||
|
GotFirstResponseByte: func() {
|
||||||
|
log.Trace().Msg("ClientTrace.GotFirstResponseByte")
|
||||||
|
},
|
||||||
|
|
||||||
|
Got100Continue: func() {
|
||||||
|
log.Trace().Msg("ClientTrace.Got100Continue")
|
||||||
|
},
|
||||||
|
|
||||||
|
Got1xxResponse: func(code int, header textproto.MIMEHeader) error {
|
||||||
|
log.Trace().
|
||||||
|
Int("code", code).
|
||||||
|
Str("header", fmt.Sprint(header)).
|
||||||
|
Msg("ClientTrace.Got1xxxResponse")
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
|
||||||
|
DNSStart: func(dnsInfo httptrace.DNSStartInfo) {
|
||||||
|
log.Trace().Str("host", dnsInfo.Host).Msg("ClientTrace.DNSStart")
|
||||||
|
},
|
||||||
|
|
||||||
|
DNSDone: func(dnsInfo httptrace.DNSDoneInfo) {
|
||||||
|
log.Trace().
|
||||||
|
Str("addresses", fmt.Sprint(dnsInfo.Addrs)).
|
||||||
|
Err(dnsInfo.Err).
|
||||||
|
Bool("coalesced", dnsInfo.Coalesced).
|
||||||
|
Msg("ClientTrace.DNSDone")
|
||||||
|
},
|
||||||
|
|
||||||
|
ConnectStart: func(network, addr string) {
|
||||||
|
log.Trace().
|
||||||
|
Str("network", network).
|
||||||
|
Str("address", addr).
|
||||||
|
Msg("ClientTrace.ConnectStart")
|
||||||
|
},
|
||||||
|
|
||||||
|
ConnectDone: func(network, addr string, err error) {
|
||||||
|
log.Trace().
|
||||||
|
Str("network", network).
|
||||||
|
Str("address", addr).
|
||||||
|
Err(err).
|
||||||
|
Msg("ClientTrace.ConnectDone")
|
||||||
|
},
|
||||||
|
|
||||||
|
TLSHandshakeStart: func() {
|
||||||
|
log.Trace().Msg("ClientTrace.TLSHandshakeStart")
|
||||||
|
},
|
||||||
|
|
||||||
|
TLSHandshakeDone: func(connState tls.ConnectionState, err error) {
|
||||||
|
log.Trace().
|
||||||
|
Uint16("version", connState.Version).
|
||||||
|
Bool("handshake-complete", connState.HandshakeComplete).
|
||||||
|
Bool("did-resume", connState.DidResume).
|
||||||
|
Uint16("cipher-suite", connState.CipherSuite).
|
||||||
|
Str("negotiated-protocol", connState.NegotiatedProtocol).
|
||||||
|
Str("server-name", connState.ServerName).
|
||||||
|
Err(err).
|
||||||
|
Msg("ClientTrace.TLSHandshakeDone")
|
||||||
|
},
|
||||||
|
|
||||||
|
WroteHeaderField: func(key string, value []string) {
|
||||||
|
log.Trace().
|
||||||
|
Str("key", key).
|
||||||
|
Strs("values", value).
|
||||||
|
Msg("ClientTrace.WroteHeaderField")
|
||||||
|
},
|
||||||
|
|
||||||
|
WroteHeaders: func() {
|
||||||
|
log.Trace().Msg("ClientTrace.WroteHeaders")
|
||||||
|
},
|
||||||
|
|
||||||
|
Wait100Continue: func() {
|
||||||
|
log.Trace().Msg("ClientTrace.Wait100Continue")
|
||||||
|
},
|
||||||
|
|
||||||
|
WroteRequest: func(reqInfo httptrace.WroteRequestInfo) {
|
||||||
|
log.Trace().Err(reqInfo.Err).Msg("ClientTrace.WroteRequest")
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user