go-micro.dev/v5@v5.12.0/transport/http_transport.go (about) 1 package transport 2 3 import ( 4 "bufio" 5 "crypto/tls" 6 "net" 7 "net/http" 8 9 "go-micro.dev/v5/logger" 10 maddr "go-micro.dev/v5/util/addr" 11 mnet "go-micro.dev/v5/util/net" 12 mls "go-micro.dev/v5/util/tls" 13 ) 14 15 type httpTransport struct { 16 opts Options 17 } 18 19 func NewHTTPTransport(opts ...Option) *httpTransport { 20 options := Options{ 21 BuffSizeH2: DefaultBufSizeH2, 22 Logger: logger.DefaultLogger, 23 } 24 25 for _, o := range opts { 26 o(&options) 27 } 28 29 return &httpTransport{opts: options} 30 } 31 32 func (h *httpTransport) Init(opts ...Option) error { 33 for _, o := range opts { 34 o(&h.opts) 35 } 36 37 return nil 38 } 39 40 func (h *httpTransport) Dial(addr string, opts ...DialOption) (Client, error) { 41 dopts := DialOptions{ 42 Timeout: DefaultDialTimeout, 43 } 44 45 for _, opt := range opts { 46 opt(&dopts) 47 } 48 49 var ( 50 conn net.Conn 51 err error 52 ) 53 54 if h.opts.Secure || h.opts.TLSConfig != nil { 55 config := h.opts.TLSConfig 56 if config == nil { 57 config = &tls.Config{ 58 InsecureSkipVerify: dopts.InsecureSkipVerify, 59 } 60 } 61 62 config.NextProtos = []string{"http/1.1"} 63 64 conn, err = newConn(func(addr string) (net.Conn, error) { 65 return tls.DialWithDialer(&net.Dialer{Timeout: dopts.Timeout}, "tcp", addr, config) 66 })(addr) 67 } else { 68 conn, err = newConn(func(addr string) (net.Conn, error) { 69 return net.DialTimeout("tcp", addr, dopts.Timeout) 70 })(addr) 71 } 72 73 if err != nil { 74 return nil, err 75 } 76 77 return &httpTransportClient{ 78 ht: h, 79 addr: addr, 80 conn: conn, 81 buff: bufio.NewReader(conn), 82 dialOpts: dopts, 83 req: make(chan *http.Request, 100), 84 local: conn.LocalAddr().String(), 85 remote: conn.RemoteAddr().String(), 86 }, nil 87 } 88 89 func (h *httpTransport) Listen(addr string, opts ...ListenOption) (Listener, error) { 90 var options ListenOptions 91 for _, o := range opts { 92 o(&options) 93 } 94 95 var ( 96 list net.Listener 97 err error 98 ) 99 100 switch listener := getNetListener(&options); { 101 // Extracted listener from context 102 case listener != nil: 103 getList := func(addr string) (net.Listener, error) { 104 return listener, nil 105 } 106 107 list, err = mnet.Listen(addr, getList) 108 109 // Needs to create self signed certificate 110 case h.opts.Secure || h.opts.TLSConfig != nil: 111 config := h.opts.TLSConfig 112 113 getList := func(addr string) (net.Listener, error) { 114 if config != nil { 115 return tls.Listen("tcp", addr, config) 116 } 117 118 hosts := []string{addr} 119 120 // check if its a valid host:port 121 if host, _, err := net.SplitHostPort(addr); err == nil { 122 if len(host) == 0 { 123 hosts = maddr.IPs() 124 } else { 125 hosts = []string{host} 126 } 127 } 128 129 // generate a certificate 130 cert, err := mls.Certificate(hosts...) 131 if err != nil { 132 return nil, err 133 } 134 135 config = &tls.Config{ 136 Certificates: []tls.Certificate{cert}, 137 MinVersion: tls.VersionTLS12, 138 } 139 140 return tls.Listen("tcp", addr, config) 141 } 142 143 list, err = mnet.Listen(addr, getList) 144 145 // Create new basic net listener 146 default: 147 getList := func(addr string) (net.Listener, error) { 148 return net.Listen("tcp", addr) 149 } 150 151 list, err = mnet.Listen(addr, getList) 152 } 153 154 if err != nil { 155 return nil, err 156 } 157 158 return &httpTransportListener{ 159 ht: h, 160 listener: list, 161 }, nil 162 } 163 164 func (h *httpTransport) Options() Options { 165 return h.opts 166 } 167 168 func (h *httpTransport) String() string { 169 return "http" 170 }