go-hep.org/x/hep@v0.38.1/xrootd/xrdio/parse.go (about) 1 // Copyright ©2018 The go-hep 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 xrdio 6 7 import ( 8 "fmt" 9 "net" 10 "strings" 11 ) 12 13 // URL stores an absolute reference to a XRootD path. 14 type URL struct { 15 Addr string // address (host [:port]) of the server 16 User string // user name to use to log in 17 Path string // path to the remote file or directory 18 } 19 20 // Parse parses name into an xrootd URL structure. 21 func Parse(name string) (URL, error) { 22 var ( 23 user string 24 addr string 25 path string 26 err error 27 ) 28 29 idx := strings.Index(name, "://") 30 switch idx { 31 case -1: 32 path = name 33 default: 34 uri := name[idx+len("://"):] 35 tok := strings.SplitN(uri, "/", 2) 36 user, addr, err = parseUA(tok[0]) 37 if err != nil { 38 return URL{}, fmt.Errorf("could not parse URI %q: %w", name, err) 39 } 40 path = "/" + tok[1] 41 } 42 43 if strings.HasPrefix(path, "//") { 44 path = path[1:] 45 } 46 47 return URL{Addr: addr, User: user, Path: path}, nil 48 } 49 50 func parseUA(s string) (user, addr string, err error) { 51 switch { 52 case strings.Contains(s, "@"): 53 toks := strings.SplitN(s, "@", 2) 54 user = parseUser(toks[0]) 55 addr = toks[1] 56 default: 57 addr = s 58 } 59 60 switch { 61 case strings.HasPrefix(addr, "["): // IPv6 literal 62 idx := strings.LastIndex(addr, "]") 63 col := strings.Index(addr[idx+1:], ":") 64 if col >= 0 { 65 _, _, err = net.SplitHostPort(addr) 66 } 67 case strings.Contains(addr, ":"): 68 _, _, err = net.SplitHostPort(addr) 69 } 70 71 if err != nil { 72 return "", "", fmt.Errorf("could not extract host+port from URI: %w", err) 73 } 74 75 return user, addr, nil 76 } 77 78 func parseUser(s string) string { 79 idx := strings.Index(s, ":") 80 if idx == -1 { 81 return s 82 } 83 return s[:idx] 84 }