Проверка URL кажется неработоспособной - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь проверить URL с помощью стандартной библиотеки Go. Вот как выглядит мой код в настоящее время.

import (
    "fmt"
    "net/url"
)

func isValidURL(tocheck string) bool {
    _, err := url.ParseRequestURI(tocheck)
    return err == nil
}

func main() {
    fmt.Println(isValidURL("google.com"))      //returns false, expected true
    fmt.Println(isValidURL("www.google.com"))  //returns false, expected true
    fmt.Println(isValidURL("google"))          //returns false, expected false
    fmt.Println(isValidURL("/google"))         //returns true, expected false
}

Все три примера выдают false, хотя первые два должны быть верными. Затем я попытался добавить https:// в начало URL-адресов, которые не начинаются с них, но затем все, например https://aaaa, анализируется как допустимое. Что я могу сделать, чтобы убедиться, что он возвращает true только тогда, когда URL действительно действителен?

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Большинство из них являются доменными именами. https://aaaa является действительным URL. /google не является URL-адресом, но допустимо для ParseRequestURI, поскольку оно также принимает абсолютные пути.

" rawurl интерпретируется только как абсолютный URI или абсолютный путь "

Когда вы спрашиваете ParseRequestURI, вы запрашиваете строгую проверку синтаксиса либо абсолютного URL, либо абсолютного пути. Абсолютный путь - это что-то вроде /foo/bar. То, что является и не является абсолютным URL-адресом, покрывается RFC 3986 . Вот основная грамматика для URI:

URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]

hier-part   = "//" authority path-abempty
            / path-absolute
            / path-rootless
            / path-empty

«Абсолютный URL» означает, что часть path является абсолютным или пустым путем, поэтому path-abempty или path-absolute выше. http и https URL могут быть только абсолютными. foo:bar/baz является примером относительного URL.

А вот пример.

  foo://example.com:8042/over/there?name=ferret#nose
  \_/   \______________/\_________/ \_________/ \__/
   |           |            |            |        |
scheme     authority       path        query   fragment
   |   _____________________|__
  / \ /                        \
  urn:example:animal:ferret:nose

google.com не имеет scheme, поэтому это не URL. https://aaaa имеет схему https и hier-part, //aaaa, поэтому это URL. У него нет query или fragement, но они необязательны.

Очевидно, это немного широко. В реальном мире вам нужно сузить свои требования. Обычно это что-то вроде ...

  1. Проверьте, что это URL, который вы не совсем делаете, вызвав ParseRequestURI, потому что это также может быть абсолютный путь.
  2. Проверьте, имеет ли она приемлемую схему, url.Scheme. Это отбросит абсолютные пути.
  3. Проверьте правильность имени домена, url.Host.

И любые другие проверки, которые вы, возможно, захотите сделать, чтобы ограничить то, что вы считаете действительным URL.

Так что ваша полная проверка может выглядеть так ...

package main

import (
    "fmt"
    "net"
    "net/url"
    "errors"
)

func isValidURL(tocheck string) (bool, error) {
    // Check it's an Absolute URL or absolute path
    uri, err := url.ParseRequestURI(tocheck)
    if err != nil {
        return false, err
    }

    // Check it's an acceptable scheme
    switch uri.Scheme {
        case "http":
        case "https":
        default:
            return false, errors.New("Invalid scheme")
    }

    // Check it's a valid domain name
    _,err = net.LookupHost(uri.Host)
    if err != nil {
        return false, err
    }

    return true, nil
}

func main() {
    // False, no scheme
    fmt.Println(isValidURL("/google"))
    // True, good scheme, good domain
    fmt.Println(isValidURL("https://google.com"))
    // False, bad domain
    fmt.Println(isValidURL("http://halghalghlakdjfl.blarg"))
}
0 голосов
/ 27 июня 2018

Вы перепутали домены с URL-адресами, домен является только частью URL-адреса.

Допустимые примеры доменов: www.google.com, localhost и a.b.c.a.google.com.

Чтобы URL был действительным, должна присутствовать часть схемы / протокола (обычно https://), см. Синтаксис в Википедии для простого объяснения .

http://aaa является действительным URL-адресом по тем же правилам, что и http://localhost действителен

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...