github.com/ethersphere/bee/v2@v2.2.0/pkg/resolver/multiresolver/config.go (about)

     1  // Copyright 2020 The Swarm Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package multiresolver
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  	"unicode"
    11  
    12  	"github.com/ethereum/go-ethereum/common"
    13  )
    14  
    15  // Defined as per RFC 1034. For reference, see:
    16  // https://en.wikipedia.org/wiki/Domain_Name_System#cite_note-rfc1034-1
    17  const maxTLDLength = 63
    18  
    19  // ConnectionConfig contains the TLD, endpoint and contract address used to
    20  // establish to a resolver.
    21  type ConnectionConfig struct {
    22  	TLD      string
    23  	Address  string
    24  	Endpoint string
    25  }
    26  
    27  // ParseConnectionString will try to parse a connection string used to connect
    28  // the Resolver to a name resolution service. The resulting config can be
    29  // used to initialize a resolver Service.
    30  func parseConnectionString(cs string) (ConnectionConfig, error) {
    31  	isAllUnicodeLetters := func(s string) bool {
    32  		for _, r := range s {
    33  			if !unicode.IsLetter(r) {
    34  				return false
    35  			}
    36  		}
    37  		return true
    38  	}
    39  
    40  	endpoint := cs
    41  	var tld string
    42  	var addr string
    43  
    44  	// Split TLD and Endpoint strings.
    45  	if i := strings.Index(endpoint, ":"); i > 0 {
    46  		// Make sure not to grab the protocol, as it contains "://"!
    47  		// Eg. in http://... the "http" is NOT a tld.
    48  		if isAllUnicodeLetters(endpoint[:i]) && len(endpoint) > i+2 && endpoint[i+1:i+3] != "//" {
    49  			tld = endpoint[:i]
    50  			if len(tld) > maxTLDLength {
    51  				return ConnectionConfig{}, fmt.Errorf("tld %s: %w", tld, ErrTLDTooLong)
    52  
    53  			}
    54  			endpoint = endpoint[i+1:]
    55  		}
    56  	}
    57  	// Split the address string.
    58  	if i := strings.Index(endpoint, "@"); i > 0 {
    59  		addr = common.HexToAddress(endpoint[:i]).String()
    60  		endpoint = endpoint[i+1:]
    61  	}
    62  
    63  	return ConnectionConfig{
    64  		Endpoint: endpoint,
    65  		Address:  addr,
    66  		TLD:      tld,
    67  	}, nil
    68  }
    69  
    70  // ParseConnectionStrings will apply ParseConnectionString to each connection
    71  // string. Returns first error found.
    72  func ParseConnectionStrings(cstrs []string) ([]ConnectionConfig, error) {
    73  	res := make([]ConnectionConfig, 0, len(cstrs))
    74  
    75  	for _, cs := range cstrs {
    76  		cfg, err := parseConnectionString(cs)
    77  		if err != nil {
    78  			return nil, err
    79  		}
    80  		res = append(res, cfg)
    81  	}
    82  
    83  	return res, nil
    84  }