一:问题
func main(){
url,err:= url.Parse("127.0.0.1:8080")
if err!=nil{
fmt.Println(err)
}
fmt.Println(url.Host,url.Port())
}
使用url.Parse()解析host是ip的url时(eg:127.0.0.1:8080),出现:first path segment in URL cannot contain colon
二:问题原因
报错的原因:url.Parse()里面调用的func parse(rawurl string, viaRequest bool) (*URL, error)
这个函数报错
func parse(rawurl string, viaRequest bool) (*URL, error) {
//.......
if !strings.HasPrefix(rest, "/") {
if url.Scheme != "" {
// We consider rootless paths per RFC 3986 as opaque.
url.Opaque = rest
return url, nil
}
if viaRequest {
return nil, errors.New("invalid URI for request")
}
// Avoid confusion with malformed schemes, like cache_object:foo/bar.
// See golang.org/issue/16822.
//
// RFC 3986, §3.3:
// In addition, a URI reference (Section 4.1) may be a relative-path reference,
// in which case the first path segment cannot contain a colon (":") character.
//报错位置
colon := strings.Index(rest, ":")
slash := strings.Index(rest, "/")
if colon >= 0 && (slash < 0 || colon < slash) {
// First path segment has colon. Not allowed in relative URL.
return nil, errors.New("first path segment in URL cannot contain colon")
}
}
//............
三.处理方法
在func parse(rawurl string, viaRequest bool) (*URL, error)中:
if (url.Scheme != "" || !viaRequest && !strings.HasPrefix(rest, "///")) && strings.HasPrefix(rest, "//") {
var authority string
authority, rest = split(rest[2:], "/", false)
url.User, url.Host, err = parseAuthority(authority)
if err != nil {
return nil, err
}
}
看到这个部分,可以在127.0.0.1:8080前面加”//”解决(eg://127.0.0.1:8080)
四:补充
关于//host:port
(this format is called the “network-path reference” from RFC 3986, section 4.2)
可以参考:https://stackoverflow.com/questions/3583103/network-path-reference-uri-scheme-relative-urls