Package list golang-github-tv42-httpunix / upstream/0.0_git20191220.2ba4b9c
Import upstream version 0.0~git20191220.2ba4b9c Debian Janitor 24 days ago
3 changed file(s) with 57 addition(s) and 26 deletion(s). Raw diff Collapse all Expand all
0 Copyright (c) 2013-2015 Tommi Virtanen.
0 Copyright (c) 2013-2019 Tommi Virtanen.
11
22 Permission is hereby granted, free of charge, to any person obtaining a copy
33 of this software and associated documentation files (the "Software"), to deal
0 module github.com/tv42/httpunix
1
2 go 1.13
1414 package httpunix
1515
1616 import (
17 "bufio"
17 "context"
1818 "errors"
1919 "net"
2020 "net/http"
2828 // Transport is a http.RoundTripper that connects to Unix domain
2929 // sockets.
3030 type Transport struct {
31 DialTimeout time.Duration
32 RequestTimeout time.Duration
31 // DialTimeout is deprecated. Use context instead.
32 DialTimeout time.Duration
33 // RequestTimeout is deprecated and has no effect.
34 RequestTimeout time.Duration
35 // ResponseHeaderTimeout is deprecated. Use context instead.
3336 ResponseHeaderTimeout time.Duration
37
38 onceInit sync.Once
39 transport http.Transport
3440
3541 mu sync.Mutex
3642 // map a URL "hostname" to a UNIX domain socket path
3743 loc map[string]string
44 }
45
46 func (t *Transport) initTransport() {
47 t.transport.DialContext = t.dialContext
48 t.transport.DialTLS = t.dialTLS
49 t.transport.DisableCompression = true
50 t.transport.ResponseHeaderTimeout = t.ResponseHeaderTimeout
51 }
52
53 func (t *Transport) getTransport() *http.Transport {
54 t.onceInit.Do(t.initTransport)
55 return &t.transport
56 }
57
58 func (t *Transport) dialContext(ctx context.Context, network, addr string) (net.Conn, error) {
59 if network != "tcp" {
60 return nil, errors.New("httpunix internals are confused: network=" + network)
61 }
62 host, port, err := net.SplitHostPort(addr)
63 if err != nil {
64 return nil, err
65 }
66 if port != "80" {
67 return nil, errors.New("httpunix internals are confused: port=" + port)
68 }
69 t.mu.Lock()
70 path, ok := t.loc[host]
71 t.mu.Unlock()
72 if !ok {
73 return nil, errors.New("unknown location: " + host)
74 }
75 d := net.Dialer{
76 Timeout: t.DialTimeout,
77 }
78 return d.DialContext(ctx, "unix", path)
79 }
80
81 func (t *Transport) dialTLS(network, addr string) (net.Conn, error) {
82 return nil, errors.New("httpunix: TLS over UNIX domain sockets is not supported")
3883 }
3984
4085 // RegisterLocation registers an URL location and maps it to the given
68113 if req.URL.Host == "" {
69114 return nil, errors.New("http+unix: no Host in request URL")
70115 }
71 t.mu.Lock()
72 path, ok := t.loc[req.URL.Host]
73 t.mu.Unlock()
74 if !ok {
75 return nil, errors.New("unknown location: " + req.Host)
76 }
77116
78 c, err := net.DialTimeout("unix", path, t.DialTimeout)
79 if err != nil {
80 return nil, err
81 }
82 r := bufio.NewReader(c)
83 if t.RequestTimeout > 0 {
84 c.SetWriteDeadline(time.Now().Add(t.RequestTimeout))
85 }
86 if err := req.Write(c); err != nil {
87 return nil, err
88 }
89 if t.ResponseHeaderTimeout > 0 {
90 c.SetReadDeadline(time.Now().Add(t.ResponseHeaderTimeout))
91 }
92 resp, err := http.ReadResponse(r, req)
93 return resp, err
117 tt := t.getTransport()
118 req = req.Clone(req.Context())
119 // get http.Transport to cooperate
120 req.URL.Scheme = "http"
121 return tt.RoundTrip(req)
94122 }