Пакет url
Обзор
Пакет url разбирает URL и реализует экранирование запросов.
См. RFC 3986. Этот пакет в целом следует RFC 3986, за исключением случаев, когда отступает от него по причинам совместимости. Для литералов зон IPv6 соблюдается RFC 6874.
Указатель
Примеры
- ParseQuery
- PathEscape
- PathUnescape
- QueryEscape
- QueryUnescape
- URL
- URL.EscapedFragment
- URL.EscapedPath
- URL.Hostname
- URL.IsAbs
- URL.JoinPath
- URL.MarshalBinary
- URL.Parse
- URL.Port
- URL.Query
- URL.Redacted
- URL.RequestURI
- URL.ResolveReference
- URL.String
- URL.UnmarshalBinary
- URL (Roundtrip)
- Values
- Values.Add
- Values.Del
- Values.Encode
- Values.Get
- Values.Has
- Values.Set
Файлы пакета
encoding_table.go url.go
func JoinPath 1.19
func JoinPath(base string, elem ...string) (result string, err error)
JoinPath возвращает строку URL, в которой переданные элементы пути объединены с существующим путём base, а полученный путь очищен от всех элементов ./ и ../. Элементы пути должны быть уже экранированы, как при помощи PathEscape.
func PathEscape 1.8
func PathEscape(s string) string
PathEscape экранирует строку, чтобы её можно было безопасно поместить в сегмент пути URL, при необходимости заменяя специальные символы (включая /) последовательностями %XX.
Пример
Код:
path := url.PathEscape("my/cool+blog&about,stuff")
fmt.Println(path)
Вывод:
my%2Fcool+blog&about%2Cstuff
func PathUnescape 1.8
func PathUnescape(s string) (string, error)
PathUnescape выполняет обратное преобразование по отношению к PathEscape, преобразуя каждую закодированную подстроку из 3 байт вида "%AB" в байт 0xAB, полученный декодированием шестнадцатеричного значения. Функция возвращает ошибку, если за любым символом % не следуют две шестнадцатеричные цифры.
PathUnescape идентична QueryUnescape, за исключением того, что не преобразует '+' в ' ' (пробел).
Пример
Код:
escapedPath := "my%2Fcool+blog&about%2Cstuff"
path, err := url.PathUnescape(escapedPath)
if err != nil {
log.Fatal(err)
}
fmt.Println(path)
Вывод:
my/cool+blog&about,stuff
func QueryEscape
func QueryEscape(s string) string
QueryEscape экранирует строку, чтобы её можно было безопасно поместить в запрос URL.
Пример
Код:
query := url.QueryEscape("my/cool+blog&about,stuff")
fmt.Println(query)
Вывод:
my%2Fcool%2Bblog%26about%2Cstuff
func QueryUnescape
func QueryUnescape(s string) (string, error)
QueryUnescape выполняет обратное преобразование по отношению к QueryEscape, преобразуя каждую закодированную подстроку из 3 байт вида "%AB" в байт 0xAB, полученный декодированием шестнадцатеричного значения. Функция возвращает ошибку, если за любым символом % не следуют две шестнадцатеричные цифры.
Пример
Код:
escapedQuery := "my%2Fcool%2Bblog%26about%2Cstuff"
query, err := url.QueryUnescape(escapedQuery)
if err != nil {
log.Fatal(err)
}
fmt.Println(query)
Вывод:
my/cool+blog&about,stuff
type Error
Error сообщает об ошибке, а также об операции и URL, которые её вызвали.
type Error struct {
Op string
URL string
Err error
}
func (*Error) Error
func (e *Error) Error() string
func (*Error) Temporary 1.6
func (e *Error) Temporary() bool
func (*Error) Timeout 1.6
func (e *Error) Timeout() bool
func (*Error) Unwrap 1.13
func (e *Error) Unwrap() error
type EscapeError
type EscapeError string
func (EscapeError) Error
func (e EscapeError) Error() string
type InvalidHostError 1.6
type InvalidHostError string
func (InvalidHostError) Error 1.6
func (e InvalidHostError) Error() string
type URL
URL представляет разобранный URL (технически — ссылку URI).
Общий формат представления:
[scheme:][//[userinfo@]host][/]path[?query][#fragment]
URL, которые после схемы не начинаются с косой черты, интерпретируются следующим образом:
scheme:opaque[?query][#fragment]
Поле Host содержит компоненты URL — хост и порт. Если порт указан, он отделяется от хоста двоеточием. Если хост является адресом IPv6, его необходимо заключить в квадратные скобки: "[fe80::1]:80". Функция net.JoinHostPort объединяет хост и порт в строку, подходящую для поля Host, добавляя к хосту квадратные скобки при необходимости.
Обратите внимание, что поле Path хранится в декодированном виде: /%47%6f%2f превращается в /Go/. В результате невозможно определить, какие косые черты в Path были косыми чертами в исходном URL, а какие — %2f. Это различие редко имеет значение, но в таких случаях следует использовать метод URL.EscapedPath, сохраняющий исходное кодирование Path. Поле Fragment также хранится в декодированном виде; чтобы получить исходное кодирование, используйте URL.EscapedFragment.
Метод URL.String использует метод URL.EscapedPath для получения пути.
type URL struct {
Scheme string
Opaque string // encoded opaque data
User *Userinfo // username and password information
Host string // "host" or "host:port" (see Hostname and Port methods)
Path string // path (relative paths may omit leading slash)
Fragment string // fragment for references (without '#')
// RawQuery contains the encoded query values, without the initial '?'.
// Use URL.Query to decode the query.
RawQuery string
// RawPath is an optional field containing an encoded path hint.
// See the EscapedPath method for more details.
//
// In general, code should call EscapedPath instead of reading RawPath.
RawPath string // Go 1.5
// RawFragment is an optional field containing an encoded fragment hint.
// See the EscapedFragment method for more details.
//
// In general, code should call EscapedFragment instead of reading RawFragment.
RawFragment string // Go 1.15
// ForceQuery indicates whether the original URL contained a query ('?') character.
// When set, the String method will include a trailing '?', even when RawQuery is empty.
ForceQuery bool // Go 1.7
// OmitHost indicates the URL has an empty host (authority).
// When set, the String method will not include the host when it is empty.
OmitHost bool // Go 1.19
}
Пример
Код:
u, err := url.Parse("http://bing.com/search?q=dotnet")
if err != nil {
log.Fatal(err)
}
u.Scheme = "https"
u.Host = "google.com"
q := u.Query()
q.Set("q", "golang")
u.RawQuery = q.Encode()
fmt.Println(u)
Вывод:
https://google.com/search?q=golang
Пример (обратное преобразование)
Код:
// Parse + String preserve the original encoding.
u, err := url.Parse("https://example.com/foo%2fbar")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Path)
fmt.Println(u.RawPath)
fmt.Println(u.String())
Вывод:
/foo/bar /foo%2fbar https://example.com/foo%2fbar
func Parse
func Parse(rawURL string) (*URL, error)
Parse разбирает исходный URL в структуру URL.
URL может быть относительным (путь без хоста) или абсолютным (начинающимся со схемы). Попытка разобрать имя хоста и путь без схемы некорректна, но из-за неоднозначности разбора не обязательно приведёт к ошибке.
func ParseRequestURI
func ParseRequestURI(rawURL string) (*URL, error)
ParseRequestURI разбирает исходный URL в структуру URL. Предполагается, что URL получен в HTTP-запросе, поэтому он интерпретируется только как абсолютный URI или абсолютный путь. Предполагается, что строка URL не имеет суффикса #fragment. (Веб-браузеры удаляют #fragment перед отправкой URL веб-серверу.)
func (*URL) AppendBinary 1.24
func (u *URL) AppendBinary(b []byte) ([]byte, error)
func (*URL) Clone 1.27
func (u *URL) Clone() *URL
Clone создаёт глубокую копию полей данного URL.
func (*URL) EscapedFragment 1.15
func (u *URL) EscapedFragment() string
EscapedFragment возвращает экранированную форму u.Fragment. В общем случае для любого фрагмента возможно несколько вариантов экранирования. EscapedFragment возвращает u.RawFragment, если он представляет собой допустимое экранирование u.Fragment. В противном случае EscapedFragment игнорирует u.RawFragment и самостоятельно вычисляет экранированную форму. Метод URL.String использует EscapedFragment для формирования результата. Как правило, вместо прямого чтения u.RawFragment следует вызывать EscapedFragment.
Пример
Код:
u, err := url.Parse("http://example.com/#x/y%2Fz")
if err != nil {
log.Fatal(err)
}
fmt.Println("Fragment:", u.Fragment)
fmt.Println("RawFragment:", u.RawFragment)
fmt.Println("EscapedFragment:", u.EscapedFragment())
Вывод:
Fragment: x/y/z RawFragment: x/y%2Fz EscapedFragment: x/y%2Fz
func (*URL) EscapedPath 1.5
func (u *URL) EscapedPath() string
EscapedPath возвращает экранированную форму u.Path. В общем случае для любого пути возможно несколько вариантов экранирования. EscapedPath возвращает u.RawPath, если он представляет собой допустимое экранирование u.Path. В противном случае EscapedPath игнорирует u.RawPath и самостоятельно вычисляет экранированную форму. Методы URL.String и URL.RequestURI используют EscapedPath для формирования результатов. Как правило, вместо прямого чтения u.RawPath следует вызывать EscapedPath.
Пример
Код:
u, err := url.Parse("http://example.com/x/y%2Fz")
if err != nil {
log.Fatal(err)
}
fmt.Println("Path:", u.Path)
fmt.Println("RawPath:", u.RawPath)
fmt.Println("EscapedPath:", u.EscapedPath())
Вывод:
Path: /x/y/z RawPath: /x/y%2Fz EscapedPath: /x/y%2Fz
func (*URL) Hostname 1.8
func (u *URL) Hostname() string
Hostname возвращает u.Host, удаляя допустимый номер порта, если он указан.
Если результат заключён в квадратные скобки, как это бывает с литеральными адресами IPv6, скобки удаляются.
Пример
Код:
u, err := url.Parse("https://example.org:8000/path")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Hostname())
u, err = url.Parse("https://[2001:0db8:85a3:0000:0000:8a2e:0370:7334]:17000")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Hostname())
Вывод:
example.org 2001:0db8:85a3:0000:0000:8a2e:0370:7334
func (*URL) IsAbs
func (u *URL) IsAbs() bool
IsAbs сообщает, является ли URL абсолютным. Абсолютный URL имеет непустую схему.
Пример
Код:
u := url.URL{Host: "example.com", Path: "foo"}
fmt.Println(u.IsAbs())
u.Scheme = "http"
fmt.Println(u.IsAbs())
Вывод:
false true
func (*URL) JoinPath 1.19
func (u *URL) JoinPath(elem ...string) *URL
JoinPath возвращает новый URL, в котором переданные элементы пути объединены с любым существующим путём, а полученный путь очищен от всех элементов ./ и ../. Любые последовательности из нескольких символов / сокращаются до одного /. Элементы пути должны быть уже экранированы, как при помощи PathEscape.
Пример
Код:
u, err := url.Parse("https://example.com/foo/bar")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.JoinPath("baz", "qux"))
Вывод:
https://example.com/foo/bar/baz/qux
func (*URL) MarshalBinary 1.8
func (u *URL) MarshalBinary() (text []byte, err error)
Пример
Код:
u, _ := url.Parse("https://example.org")
b, err := u.MarshalBinary()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", b)
Вывод:
https://example.org
func (*URL) Parse
func (u *URL) Parse(ref string) (*URL, error)
Parse разбирает URL в контексте получателя. Переданный URL может быть относительным или абсолютным. При ошибке разбора Parse возвращает nil, err; в противном случае возвращаемое значение совпадает с результатом URL.ResolveReference.
Пример
Код:
u, err := url.Parse("https://example.org")
if err != nil {
log.Fatal(err)
}
rel, err := u.Parse("/foo")
if err != nil {
log.Fatal(err)
}
fmt.Println(rel)
_, err = u.Parse(":foo")
if _, ok := err.(*url.Error); !ok {
log.Fatal(err)
}
Вывод:
https://example.org/foo
func (*URL) Port 1.8
func (u *URL) Port() string
Port возвращает часть u.Host, содержащую порт, без начального двоеточия.
Если u.Host не содержит допустимого числового порта, Port возвращает пустую строку.
Пример
Код:
u, err := url.Parse("https://example.org")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Port())
u, err = url.Parse("https://example.org:8080")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.Port())
Вывод:
8080
func (*URL) Query
func (u *URL) Query() Values
Query разбирает RawQuery и возвращает соответствующие значения. Некорректные пары значений отбрасываются без уведомления. Чтобы проверить наличие ошибок, используйте ParseQuery.
Пример
Код:
u, err := url.Parse("https://example.org/?a=1&a=2&b=&=3&&&&")
if err != nil {
log.Fatal(err)
}
q := u.Query()
fmt.Println(q["a"])
fmt.Println(q.Get("b"))
fmt.Println(q.Get(""))
Вывод:
[1 2] 3
func (*URL) Redacted 1.15
func (u *URL) Redacted() string
Redacted работает как URL.String, но заменяет любой пароль на "xxxxx". Скрывается только пароль в u.User.
Пример
Код:
u := &url.URL{
Scheme: "https",
User: url.UserPassword("user", "password"),
Host: "example.com",
Path: "foo/bar",
}
fmt.Println(u.Redacted())
u.User = url.UserPassword("me", "newerPassword")
fmt.Println(u.Redacted())
Вывод:
https://user:xxxxx@example.com/foo/bar https://me:xxxxx@example.com/foo/bar
func (*URL) RequestURI
func (u *URL) RequestURI() string
RequestURI возвращает строку в формате encoded path?query или opaque?query, которая использовалась бы в HTTP-запросе для u.
Пример
Код:
u, err := url.Parse("https://example.org/path?foo=bar")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.RequestURI())
Вывод:
/path?foo=bar
func (*URL) ResolveReference
func (u *URL) ResolveReference(ref *URL) *URL
ResolveReference разрешает ссылку URI в абсолютный URI относительно абсолютного базового URI u согласно разделу 5.2 RFC 3986. Ссылка URI может быть относительной или абсолютной. ResolveReference всегда возвращает новый экземпляр URL, даже если возвращённый URL совпадает с базовым URL или ссылкой. Если ref — абсолютный URL, ResolveReference игнорирует базовый URL и возвращает копию ref.
Пример
Код:
u, err := url.Parse("../../..//search?q=dotnet")
if err != nil {
log.Fatal(err)
}
base, err := url.Parse("http://example.com/directory/")
if err != nil {
log.Fatal(err)
}
fmt.Println(base.ResolveReference(u))
Вывод:
http://example.com/search?q=dotnet
func (*URL) String
func (u *URL) String() string
String собирает URL в строку допустимого URL. Общая форма результата — одна из следующих:
scheme:opaque?query#fragment scheme://userinfo@host/path?query#fragment
Если u.Opaque не пуст, String использует первую форму; в противном случае — вторую. Все символы хоста, не входящие в ASCII, экранируются. Для получения пути String использует u.EscapedPath().
Для второй формы действуют следующие правила:
- если u.Scheme пуст, scheme: опускается.
- если u.User равен nil, userinfo@ опускается.
- если u.Host пуст, host/ опускается.
- если u.Scheme и u.Host пусты и u.User равен nil, вся часть scheme://userinfo@host/ опускается.
- если u.Host не пуст и u.Path начинается с /, форма host/path не добавляет собственный /.
- если u.RawQuery пуст, ?query опускается.
- если u.Fragment пуст, #fragment опускается.
Пример
Код:
u := &url.URL{
Scheme: "https",
User: url.UserPassword("me", "pass"),
Host: "example.com",
Path: "foo/bar",
RawQuery: "x=1&y=2",
Fragment: "anchor",
}
fmt.Println(u.String())
u.Opaque = "opaque"
fmt.Println(u.String())
Вывод:
https://me:pass@example.com/foo/bar?x=1&y=2#anchor https:opaque?x=1&y=2#anchor
func (*URL) UnmarshalBinary 1.8
func (u *URL) UnmarshalBinary(text []byte) error
Пример
Код:
u := &url.URL{}
err := u.UnmarshalBinary([]byte("https://example.org/foo"))
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", u)
Вывод:
https://example.org/foo
type Userinfo
Тип Userinfo — это неизменяемая инкапсуляция данных об имени пользователя и пароле для URL. Для существующего значения Userinfo гарантируется наличие имени пользователя (возможно, пустого, как допускает RFC 2396) и, при необходимости, пароля.
type Userinfo struct {
// contains filtered or unexported fields
}
func User
func User(username string) *Userinfo
User возвращает Userinfo, содержащий переданное имя пользователя и не содержащий пароль.
func UserPassword
func UserPassword(username, password string) *Userinfo
UserPassword возвращает Userinfo, содержащий переданные имя пользователя и пароль.
Эту возможность следует использовать только для устаревших веб-сайтов. В RFC 2396 указано, что интерпретация Userinfo таким образом «НЕ РЕКОМЕНДУЕТСЯ, поскольку передача данных аутентификации в открытом виде (например, в URI) почти во всех случаях, когда она использовалась, представляла угрозу безопасности».
func (*Userinfo) Password
func (u *Userinfo) Password() (string, bool)
Password возвращает пароль, если он задан, и сообщает, задан ли он.
func (*Userinfo) String
func (u *Userinfo) String() string
String возвращает закодированные данные пользователя в стандартном формате "username[:password]".
func (*Userinfo) Username
func (u *Userinfo) Username() string
Username возвращает имя пользователя.
type Values
Values сопоставляет строковый ключ со списком значений. Обычно используется для параметров запроса и значений формы. В отличие от карты http.Header, ключи карты Values чувствительны к регистру.
type Values map[string][]string
Пример
Код:
v := url.Values{}
v.Set("name", "Ava")
v.Add("friend", "Jess")
v.Add("friend", "Sarah")
v.Add("friend", "Zoe")
fmt.Println(v.Encode())
fmt.Println(v.Get("name"))
fmt.Println(v.Get("friend"))
fmt.Println(v["friend"])
Вывод:
friend=Jess&friend=Sarah&friend=Zoe&name=Ava Ava Jess [Jess Sarah Zoe]
func ParseQuery
func ParseQuery(query string) (Values, error)
ParseQuery разбирает закодированную для URL строку запроса и возвращает карту со значениями, указанными для каждого ключа. ParseQuery всегда возвращает ненулевую карту, содержащую все найденные допустимые параметры запроса; err описывает первую обнаруженную ошибку декодирования, если таковая имеется.
Предполагается, что Query представляет собой список пар key=value, разделённых амперсандами. Настройка без знака равенства интерпретируется как ключ с пустым значением. Настройки, содержащие точку с запятой, не закодированную для URL, считаются недопустимыми.
Пример
Код:
m, err := url.ParseQuery(`x=1&y=2&y=3`)
if err != nil {
log.Fatal(err)
}
fmt.Println(toJSON(m))
Вывод:
{"x":["1"], "y":["2", "3"]}
func (Values) Add
func (v Values) Add(key, value string)
Add добавляет значение к ключу. Оно добавляется после всех существующих значений, связанных с этим ключом.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew")
v.Add("cat sounds", "mau")
fmt.Println(v["cat sounds"])
Вывод:
[meow mew mau]
func (Values) Clone 1.27
func (vs Values) Clone() Values
Clone создаёт глубокую копию данного значения Values.
func (Values) Del
func (v Values) Del(key string)
Del удаляет значения, связанные с ключом.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew")
v.Add("cat sounds", "mau")
fmt.Println(v["cat sounds"])
v.Del("cat sounds")
fmt.Println(v["cat sounds"])
Вывод:
[meow mew mau] []
func (Values) Encode
func (v Values) Encode() string
Encode кодирует значения в форму «закодированную для URL» ("bar=baz&foo=quux"), упорядоченную по ключу.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew/")
v.Add("cat sounds", "mau$")
fmt.Println(v.Encode())
Вывод:
cat+sounds=meow&cat+sounds=mew%2F&cat+sounds=mau%24
func (Values) Get
func (v Values) Get(key string) string
Get получает первое значение, связанное с указанным ключом. Если с ключом не связано ни одного значения, Get возвращает пустую строку. Чтобы получить несколько значений, используйте карту напрямую.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew")
v.Add("cat sounds", "mau")
fmt.Printf("%q\n", v.Get("cat sounds"))
fmt.Printf("%q\n", v.Get("dog sounds"))
Вывод:
"meow" ""
func (Values) Has 1.17
func (v Values) Has(key string) bool
Has проверяет, задан ли указанный ключ.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew")
v.Add("cat sounds", "mau")
fmt.Println(v.Has("cat sounds"))
fmt.Println(v.Has("dog sounds"))
Вывод:
true false
func (Values) Set
func (v Values) Set(key, value string)
Set задаёт для ключа указанное значение. Все существующие значения заменяются.
Пример
Код:
v := url.Values{}
v.Add("cat sounds", "meow")
v.Add("cat sounds", "mew")
v.Add("cat sounds", "mau")
fmt.Println(v["cat sounds"])
v.Set("cat sounds", "meow")
fmt.Println(v["cat sounds"])
Вывод:
[meow mew mau] [meow]
© Google, Inc.
Licensed under the Creative Commons Attribution License 3.0.
http://golang.org/pkg/net/url/