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  }