github.com/core-coin/go-core/v2@v2.1.9/rpc/client_opt.go (about)

     1  // Copyright 2024 by the Authors
     2  // This file is part of the go-core library.
     3  //
     4  // The go-core library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-core library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-core library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package rpc
    18  
    19  import (
    20  	"net/http"
    21  
    22  	"github.com/gorilla/websocket"
    23  )
    24  
    25  // ClientOption is a configuration option for the RPC client.
    26  type ClientOption interface {
    27  	applyOption(*clientConfig)
    28  }
    29  
    30  type clientConfig struct {
    31  	httpClient  *http.Client
    32  	httpHeaders http.Header
    33  	httpAuth    HTTPAuth
    34  
    35  	wsDialer *websocket.Dialer
    36  }
    37  
    38  func (cfg *clientConfig) initHeaders() {
    39  	if cfg.httpHeaders == nil {
    40  		cfg.httpHeaders = make(http.Header)
    41  	}
    42  }
    43  
    44  func (cfg *clientConfig) setHeader(key, value string) {
    45  	cfg.initHeaders()
    46  	cfg.httpHeaders.Set(key, value)
    47  }
    48  
    49  type optionFunc func(*clientConfig)
    50  
    51  func (fn optionFunc) applyOption(opt *clientConfig) {
    52  	fn(opt)
    53  }
    54  
    55  // WithWebsocketDialer configures the websocket.Dialer used by the RPC client.
    56  func WithWebsocketDialer(dialer websocket.Dialer) ClientOption {
    57  	return optionFunc(func(cfg *clientConfig) {
    58  		cfg.wsDialer = &dialer
    59  	})
    60  }
    61  
    62  // WithHeader configures HTTP headers set by the RPC client. Headers set using this option
    63  // will be used for both HTTP and WebSocket connections.
    64  func WithHeader(key, value string) ClientOption {
    65  	return optionFunc(func(cfg *clientConfig) {
    66  		cfg.initHeaders()
    67  		cfg.httpHeaders.Set(key, value)
    68  	})
    69  }
    70  
    71  // WithHeaders configures HTTP headers set by the RPC client. Headers set using this
    72  // option will be used for both HTTP and WebSocket connections.
    73  func WithHeaders(headers http.Header) ClientOption {
    74  	return optionFunc(func(cfg *clientConfig) {
    75  		cfg.initHeaders()
    76  		for k, vs := range headers {
    77  			cfg.httpHeaders[k] = vs
    78  		}
    79  	})
    80  }
    81  
    82  // WithHTTPClient configures the http.Client used by the RPC client.
    83  func WithHTTPClient(c *http.Client) ClientOption {
    84  	return optionFunc(func(cfg *clientConfig) {
    85  		cfg.httpClient = c
    86  	})
    87  }
    88  
    89  // WithHTTPAuth configures HTTP request authentication. The given provider will be called
    90  // whenever a request is made. Note that only one authentication provider can be active at
    91  // any time.
    92  func WithHTTPAuth(a HTTPAuth) ClientOption {
    93  	if a == nil {
    94  		panic("nil auth")
    95  	}
    96  	return optionFunc(func(cfg *clientConfig) {
    97  		cfg.httpAuth = a
    98  	})
    99  }
   100  
   101  // A HTTPAuth function is called by the client whenever a HTTP request is sent.
   102  // The function must be safe for concurrent use.
   103  //
   104  // Usually, HTTPAuth functions will call h.Set("authorization", "...") to add
   105  // auth information to the request.
   106  type HTTPAuth func(h http.Header) error