确保一个URI是有效的。

huangapple go评论90阅读模式
英文:

Ensure a URI is valid

问题

我正在尝试确保传递给我的Go程序的URL是有效的。然而,我似乎无法弄清楚如何做到这一点。我以为我可以通过url.Parse来实现,但似乎并没有起作用。

package main

import (
	"fmt"
	"net/url"
)

func main() {
	url, err := url.Parse("http:::/not.valid/a//a??a?b=&&c#hi")
	if err != nil {
		panic(err)
	}
	fmt.Println("It's valid!", url.String())
}

playground

有没有类似于filter_var的东西可以使用?

英文:

I'm trying to ensure that URLs passed to my go program are valid. However, I can't seem to work out how to. I thought I could just feed it through url.Parse, but that doesn't seem to do the job.

package main

import (
	"fmt"
	"net/url"
)

func main() {
	url, err := url.Parse("http:::/not.valid/a//a??a?b=&&c#hi")
	if err != nil {
		panic(err)
	}
	fmt.Println("It's valid!", url.String())
}

playground

Is there anything along the lines of filter_var I can use?

答案1

得分: 13

您可以检查您的URL是否具有Scheme、Host和/或Path。

如果您检查返回的URL,您会发现无效的部分被插入到不透明数据部分中(从某种意义上说,它是有效的)。

url.URL{Scheme:"http", Opaque:"::/not.valid/a//a", Host:"", Path:"", RawQuery:"?a?b=&c", Fragment:"hi"}

如果解析URL时没有Scheme、Host和Path,您可以假设它是无效的。(尽管没有Path的Host通常是可以的,因为它暗示着/,所以您需要检查这一点)

u, err := url.Parse("http:::/not.valid/a//a??a?b=&c#hi")
if err != nil {
    log.Fatal(err)
}

if u.Scheme == "" || u.Host == "" || u.Path == "" {
    log.Fatal("invalid URL")
}
英文:

You can check that your URL has a Scheme, Host, and/or a Path.

If you inspect the URL returned, you can see that the invalid part is inserted into the Opaque data section (so in a sense, it is valid).

url.URL{Scheme:"http", Opaque:"::/not.valid/a//a", Host:"", Path:"", RawQuery:"?a?b=&&c", Fragment:"hi"}

If you parse a URL and don't have a Scheme, Host and Path you can probably assume it's not valid. (though a host without a path is often OK, since it implies /, so you need to check for that)

u, err := url.Parse("http:::/not.valid/a//a??a?b=&&c#hi")
if err != nil {
	log.Fatal(err)
}

if u.Scheme == "" || u.Host == "" || u.Path == "" {
	log.Fatal("invalid URL")
}

答案2

得分: 2

尝试使用这个包go validator,其中的IsURL函数是你想要的。(你也可以使用regexp包)

package main

import (
    "fmt"
    "regexp"
)

const URL string = `^((ftp|http|https):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(((([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)\.)?)?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?)|localhost)(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

func Matches(str, pattern string) bool {
    match, _ := regexp.MatchString(pattern, str)
    return match
}
func main() {
    u1 := "http:::/not.valid/a//a??a?b=&&c#hi"
    u2 := "http://golang.fastrl.com"
    func(us ...string) {
        for _, u := range us {
            fmt.Println(Matches(u, URL))
        }
    }(u1, u2)
}
英文:

have a try of this package go validator and the IsURL func is what you want.(you can use regexp package as well)

package main

import (
    "fmt"
    "regexp"
)

const URL string = `^((ftp|http|https):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(((([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)\.)?)?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?_?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?)|localhost)(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

func Matches(str, pattern string) bool {
    match, _ := regexp.MatchString(pattern, str)
    return match
}
func main() {
    u1 := "http:::/not.valid/a//a??a?b=&&c#hi"
    u2 := "http://golang.fastrl.com"
    func(us ...string) {
        for _, u := range us {
            fmt.Println(Matches(u, URL))
        }
    }(u1, u2)
}

答案3

得分: 1

url.Parse() 函数主要在 viaRequest 为 true 时返回错误,这意味着如果假设 URL 是通过 HTTP 请求到达的情况下。但是当直接调用 url.Parse() 时,情况并非如此:请参考 源代码

if url, err = parse(u, false); err != nil {
    return nil, err
}

而且 func parse(rawurl string, viaRequest bool) (url *URL, err error) { 只有在 viaRequest 为 true 时才返回 err

这就是为什么直接使用 url.Parse() 时你永远不会看到任何错误。


在后一种情况下,即从未返回任何 err 的情况下,你可以检查返回的 URL 对象 的字段。空的 url.Scheme 或者不是预期的 url.Path 都可能表示错误。

英文:

The url.Parse() function will return an error mainly if viaRequest is true, meaning if the URL is assumed to have arrived via an HTTP request.
Which is not the case when you call url.Parse() directly: see the source code.

if url, err = parse(u, false); err != nil {
    return nil, err
}

And func parse(rawurl string, viaRequest bool) (url *URL, err error) { only returns err if viaRequest is true.

That is why you never see any error when using url.Parse() directly.


In that latter case, where no err is ever returned, you can check the fields of the URL object returned.
An empty url.Scheme, or an url.Path which isn't the one expected would indicate an error.

huangapple
  • 本文由 发表于 2014年9月9日 22:45:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/25747580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定