github.com/la5nta/wl2k-go@v0.11.8/transport/url.go (about) 1 // Copyright 2016 Martin Hebnes Pedersen (LA5NTA). All rights reserved. 2 // Use of this source code is governed by the MIT-license that can be 3 // found in the LICENSE file. 4 5 package transport 6 7 import ( 8 "net/url" 9 "path" 10 "sort" 11 "strings" 12 ) 13 14 // URL contains all information needed to dial a remote node. 15 type URL struct { 16 // TNC/modem/interface/network type. 17 Scheme string 18 19 // The host interface address. 20 Host string 21 22 // Host username (typically the local stations callsign) and password information. 23 User *url.Userinfo 24 25 // Target callsign. 26 Target string 27 28 // List of digipeaters ("path" between origin and target). 29 Digis []string 30 31 // List of query parameters. 32 Params url.Values 33 } 34 35 // ParseURL parses a raw urlstring into an URL. 36 // 37 // scheme://(mycall(:password)@)(host)(/digi1/...)/targetcall 38 // Examples: 39 // - ardop:///LA1B (Addresses LA1B on ARDOP). 40 // - ax25://mycall@myaxport/LD5SK/LA1B-10 (Addresses LA1B-10 via LD5SK using AX.25-port "myaxport" and "MYCALL" as source callsign). 41 // 42 // The special query parameter host will override the host part of the path. (E.g. ax25:///LA1B?host=ax0 == ax25://ax0/LA1B). 43 func ParseURL(rawurl string) (*URL, error) { 44 u, err := url.Parse(rawurl) 45 if err != nil { 46 return nil, err 47 } 48 49 // The digis and target should be all upper case 50 u.Path = strings.ToUpper(u.Path) 51 52 via, target := path.Split(u.Path) 53 if len(target) < 3 { 54 return nil, ErrInvalidTarget 55 } 56 57 url := &URL{ 58 Scheme: u.Scheme, 59 Host: u.Host, 60 User: u.User, 61 Target: target, 62 Params: u.Query(), 63 } 64 65 if str := url.Params.Get("host"); str != "" { 66 url.Host = str 67 } 68 69 // Digis 70 url.Digis = strings.Split(strings.Trim(via, "/"), "/") 71 _ = sort.Reverse(sort.StringSlice(url.Digis)) 72 if len(url.Digis) == 1 && url.Digis[0] == "" { 73 url.Digis = []string{} 74 } 75 76 // TODO: This should be up to the specific transport to decide. 77 digisUnsupported := url.Scheme == "ardop" || url.Scheme == "telnet" 78 if len(url.Digis) > 0 && digisUnsupported { 79 return url, ErrDigisUnsupported 80 } 81 82 return url, nil 83 } 84 85 // Set the URL.User's username (usually the source callsign). 86 func (u *URL) SetUser(call string) { u.User = url.User(call) }