Skip to content

Commit

Permalink
[confighttp] support http+unix
Browse files Browse the repository at this point in the history
  • Loading branch information
atoulme committed Nov 8, 2023
1 parent 8e96749 commit e2a3057
Show file tree
Hide file tree
Showing 13 changed files with 310 additions and 40 deletions.
25 changes: 25 additions & 0 deletions .chloggen/unix-socket-support.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: confighttp

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Support http+unix scheme, for both client and HTTP servers.

# One or more tracking issues or pull requests related to the change
issues: [8752]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
1 change: 1 addition & 0 deletions cmd/otelcorecol/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ require (
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/mostynb/go-grpc-compression v1.2.2 // indirect
github.com/peterbourgon/unixtransport v0.0.3 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.17.0 // indirect
Expand Down
21 changes: 21 additions & 0 deletions cmd/otelcorecol/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 25 additions & 1 deletion config/confighttp/confighttp.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ package confighttp // import "go.opentelemetry.io/collector/config/confighttp"
import (
"crypto/tls"
"errors"
"fmt"
"io"
"net"
"net/http"
"time"

"github.com/peterbourgon/unixtransport"
"github.com/rs/cors"
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
"go.opentelemetry.io/otel"
Expand Down Expand Up @@ -189,6 +191,8 @@ func (hcs *HTTPClientSettings) ToClient(host component.Host, settings component.
}
}

unixtransport.Register(transport)

return &http.Client{
Transport: clientTransport,
Timeout: hcs.Timeout,
Expand All @@ -215,6 +219,10 @@ type HTTPServerSettings struct {
// Endpoint configures the listening address for the server.
Endpoint string `mapstructure:"endpoint"`

// Network configures the network associated with the server.
// The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
Network string `mapstructure:"network"`

// TLSSetting struct exposes TLS client configuration.
TLSSetting *configtls.TLSServerSetting `mapstructure:"tls"`

Expand All @@ -238,7 +246,14 @@ type HTTPServerSettings struct {

// ToListener creates a net.Listener.
func (hss *HTTPServerSettings) ToListener() (net.Listener, error) {
listener, err := net.Listen("tcp", hss.Endpoint)
network := hss.Network
if network == "" {
network = "tcp"
}
if network == "http+unix" || network == "https+unix" || network == "unixpacket" {
network = "unix"
}
listener, err := net.Listen(network, hss.Endpoint)
if err != nil {
return nil, err
}
Expand All @@ -255,6 +270,15 @@ func (hss *HTTPServerSettings) ToListener() (net.Listener, error) {
return listener, nil
}

func (hss *HTTPServerSettings) Validate() error {
switch hss.Network {
case "tcp", "tcp4", "tcp6", "unix", "unixpacket", "http+unix", "https+unix", "":
default:
return fmt.Errorf("invalid network %q", hss.Network)
}
return nil
}

// toServerOptions has options that change the behavior of the HTTP server
// returned by HTTPServerSettings.ToServer().
type toServerOptions struct {
Expand Down
130 changes: 130 additions & 0 deletions config/confighttp/confighttp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http/httptest"
"net/url"
"path/filepath"
"runtime"
"testing"
"time"

Expand Down Expand Up @@ -1303,3 +1304,132 @@ func BenchmarkHttpRequest(b *testing.B) {
})
}
}

type recordingHandler struct {
requests []*http.Request
}

func (r *recordingHandler) ServeHTTP(resp http.ResponseWriter, req *http.Request) {
r.requests = append(r.requests, req)
resp.WriteHeader(200)
}

func TestUnixSocket(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping for Windows")
}
socketLocation := filepath.Join(t.TempDir(), "foo")
hss := &HTTPServerSettings{Endpoint: socketLocation, Network: "unix"}
handler := &recordingHandler{}
s, err := hss.ToServer(componenttest.NewNopHost(), componenttest.NewNopTelemetrySettings(), handler)
require.NoError(t, err)
l, err := hss.ToListener()
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, s.Close())
})
go func() {
_ = s.Serve(l)
}()
hcs := NewDefaultHTTPClientSettings()
hcs.Endpoint = fmt.Sprintf("http+unix:%s:/", socketLocation)
c, err := hcs.ToClient(componenttest.NewNopHost(), componenttest.NewNopTelemetrySettings())
require.NoError(t, err)
resp, err := c.Get(hcs.Endpoint)
require.NoError(t, err)
require.Equal(t, 200, resp.StatusCode)
}

func TestHTTPServerSettings_Validate(t *testing.T) {
unixSocket := filepath.Join(t.TempDir(), "socket")
tests := []struct {
name string
hss *HTTPServerSettings
wantErr error
}{
{
"default",
&HTTPServerSettings{
Endpoint: "localhost:0",
},
nil,
},
{
"tcp",
&HTTPServerSettings{
Network: "tcp",
Endpoint: "localhost:0",
},
nil,
},
{
"tcp4",
&HTTPServerSettings{
Network: "tcp4",
Endpoint: "localhost:0",
},
nil,
},
{
"tcp6",
&HTTPServerSettings{
Network: "tcp6",
Endpoint: "localhost:0",
},
nil,
},
{
"unix",
&HTTPServerSettings{
Network: "unix",
Endpoint: unixSocket,
},
nil,
},
{
"unixpacket",
&HTTPServerSettings{
Network: "unixpacket",
Endpoint: unixSocket,
},
nil,
},
{
"http+unix",
&HTTPServerSettings{
Network: "http+unix",
Endpoint: unixSocket,
},
nil,
},
{
"https+unix",
&HTTPServerSettings{
Network: "https+unix",
Endpoint: unixSocket,
},
nil,
},
{
"invalid",
&HTTPServerSettings{
Network: "invalid",
},
errors.New("invalid network \"invalid\""),
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.hss.Validate()
if tt.wantErr == nil {
assert.NoError(t, err)
l, err2 := tt.hss.ToListener()
assert.NoError(t, err2)
require.NoError(t, l.Close())
} else {
assert.Equal(t, tt.wantErr, err)
}
})
}
}
1 change: 1 addition & 0 deletions config/confighttp/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.20
require (
github.com/golang/snappy v0.0.4
github.com/klauspost/compress v1.17.2
github.com/peterbourgon/unixtransport v0.0.3
github.com/rs/cors v1.10.1
github.com/stretchr/testify v1.8.4
go.opentelemetry.io/collector v0.88.0
Expand Down
Loading

0 comments on commit e2a3057

Please sign in to comment.