Пакет url анализирует URL-адреса и реализует экранирование запросов.
Функция PathEscape
func PathEscape(s string) string
PathEscape экранирует строку, чтобы ее можно было безопасно разместить внутри сегмента пути URL, заменяя при необходимости специальные символы (включая /) последовательностями %XX.
Пример использования функции PathEscape
package main
import (
"fmt"
"net/url"
)
func main() {
space := url.PathEscape("one two")
fmt.Println(space)
percent := url.PathEscape("10%")
fmt.Println(percent)
symbols := url.PathEscape(" ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;")
fmt.Println(symbols)
}
Вывод:
one%20two
10%25
%20%3F&=%23+%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09:%2F@$%27%28%29%2A%2C%3B
Пример в песочнице https://play.golang.org/p/LNmUJmU8uaq
Функция PathUnescape
func PathUnescape(s string) (string, error)
PathUnescape выполняет обратное преобразование PathEscape, преобразуя каждую 3-байтовую закодированную подстроку формы "%AB" в шестнадцатеричный байт 0xAB. Он возвращает ошибку, если за любым % не следуют две шестнадцатеричные цифры.
PathUnescape идентичен QueryUnescape, за исключением того, что он не отменяет экранирование '+' на ' ' (пробел).
Пример использования функции PathUnescape
package main
import (
"fmt"
"net/url"
)
func main() {
space, err := url.PathUnescape("one%20two")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(space)
percent, err := url.PathUnescape("10%25")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(percent)
symbols, err := url.PathUnescape("%20%3F&=%23+%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09:%2F@$%27%28%29%2A%2C%3B")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(symbols)
}
Вывод:
one two
10%
?&=#+%!<>#"{}|\^[]`☺ :/@$'()*,;
Пример в песочнице https://play.golang.org/p/RevOg4UxSG7
Функция QueryEscape
func QueryEscape(s string) string
QueryEscape экранирует строку, чтобы ее можно было безопасно поместить в URL-запрос.
Пример использования функции QueryEscape
package main
import (
"fmt"
"net/url"
)
func main() {
space := url.QueryEscape("one two")
fmt.Println(space)
percent := url.QueryEscape("10%")
fmt.Println(percent)
symbols := url.QueryEscape(" ?&=#+%!<>#\"{}|\\^[]`☺\t:/@$'()*,;")
fmt.Println(symbols)
}
Вывод:
one+two
10%25
+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29%2A%2C%3B
Пример в песочнице https://play.golang.org/p/hfKAuFsV00i
Функция QueryUnescape
func QueryUnescape(s string) (string, error)
QueryUnescape выполняет обратное преобразование QueryEscape, преобразуя каждую 3-байтовую закодированную подстроку формы "%AB" в шестнадцатеричный байт 0xAB. Он возвращает ошибку, если за любым % не следуют две шестнадцатеричные цифры.
Пример использования функции QueryUnescape
package main
import (
"fmt"
"net/url"
)
func main() {
space, err := url.QueryUnescape("one+two")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(space)
percent, err := url.QueryUnescape("10%25")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(percent)
symbols, err := url.QueryUnescape("+%3F%26%3D%23%2B%25%21%3C%3E%23%22%7B%7D%7C%5C%5E%5B%5D%60%E2%98%BA%09%3A%2F%40%24%27%28%29%2A%2C%3B")
if err != nil {
fmt.Println(err.Error())
}
fmt.Println(symbols)
}
Вывод:
one two
10%
?&=#+%!<>#"{}|\^[]`☺ :/@$'()*,;
Пример в песочнице https://play.golang.org/p/cIDrkclH5Qa
Тип URL
type URL struct {
Scheme string
Opaque string // закодированные непрозрачные данные
User *Userinfo // username и password информация
Host string // host или host:port
Path string // путь (в относительных путях может отсутствовать начальная косая черта)
RawPath string // закодированный путь (EscapedPath)
ForceQuery bool // добавить запрос ('?') даже если RawQuery пуст
RawQuery string // закодированные значения запроса, без '?'
Fragment string // фрагмент для ссылок, без '#'
RawFragment string // закодированный фрагмент (EscapedFragment)
}
URL представляет собой проанализированный URL-адрес (технически ссылка на URI).
Общая форма представленна как:
[scheme:][//[userinfo@]host][/]path[?query][#fragment]
URL-адреса, которые не начинаются с косой черты после схемы, интерпретируются как:
scheme:opaque[?query][#fragment]
Обратите внимание, что поле Path хранится в декодированной форме: /%47%6f%2f становится /Go/. Как следствие, невозможно определить, какие косые черты в пути были косыми чертами в необработанном URL, а какие были %2f. Это различие редко бывает важным, но когда это так, код должен использовать RawPath, необязательное поле, которое устанавливается только в том случае, если кодировка по умолчанию отличается от Path.
Метод URL String использует метод EscapedPath для получения пути.
Пример использования типа URL
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример использования типа URL
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
// Parse + String сохраняют первоначальное кодирование.
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
Функция Parse
func Parse(rawURL string) (*URL, error)
Parse анализирует необработанный URL-адрес в структуру URL.
URL-адрес может быть относительным (путь без хоста) или абсолютным (начиная со схемы). Попытка проанализировать имя хоста и путь без схемы недопустима, но может не обязательно возвращать ошибку из-за неоднозначности синтаксического анализа.
Пример использования функции Parse
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("http://bing.com/search?q=dotnet")
if err != nil {
log.Fatal(err)
}
fmt.Println("Scheme: ", u.Scheme)
fmt.Println("Host: ", u.Host)
fmt.Println("Path: ", u.Path)
fmt.Println("RawQuery: ", u.RawQuery)
}
Вывод
Scheme: http
Host: bing.com
Path: /search
RawQuery: q=dotnet
Пример в песочнице https://play.golang.org/p/o5gLj5_fteS
Функция ParseRequestURI
func ParseRequestURI(rawURL string) (*URL, error)
ParseRequestURI анализирует необработанный URL-адрес в структуру URL. Предполагается, что URL-адрес был получен в HTTP-запросе, поэтому URL-адрес интерпретируется только как абсолютный URI или абсолютный путь. Предполагается, что строковый url не имеет суффикса #fragment. (Веб-браузеры удаляют #fragment перед отправкой URL-адреса на веб-сервер.)
Метод EscapedFragment
func (u *URL) EscapedFragment() string
EscapedFragment возвращает экранированную форму u.Fragment. В общем, существует несколько возможных экранированных форм любого фрагмента. EscapedFragment возвращает u.RawFragment, если это допустимое экранирование u.Fragment. В противном случае EscapedFragment игнорирует u.RawFragment и самостоятельно вычисляет экранированную форму. Метод String использует EscapedFragment для построения своего результата. В общем, код должен вызывать EscapedFragment вместо непосредственного чтения u.RawFragment.
Пример использования метода EscapedFragment
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/Q-I-8bfoXFO
Метод EscapedPath
func (u *URL) EscapedPath() string
EscapedPath возвращает экранированную форму u.Path. Как правило, у любого пути есть несколько возможных экранированных форм. EscapedPath возвращает u.RawPath, если это действительное экранирование u.Path. В противном случае EscapedPath игнорирует u.RawPath и вычисляет экранированную форму самостоятельно. Методы String и RequestURI используют EscapedPath для построения своих результатов. В общем, код должен вызывать EscapedPath вместо непосредственного чтения u.RawPath.
Пример использования метода EscapedPath
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/xvc45jZkqq6
Метод Hostname
func (u *URL) Hostname() string
Hostname возвращает u.Host, удаляя любой допустимый номер порта, если он присутствует.
Если результат заключен в квадратные скобки, как буквальные адреса IPv6, квадратные скобки удаляются из результата.
Пример использования метода Hostname
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/0MV8vkqssmO
Метод IsAbs
func (u *URL) IsAbs() bool
IsAbs сообщает, является ли URL абсолютным. Абсолютное означает, что у него непустая схема.
Пример использования метода IsAbs
package main
import (
"fmt"
"net/url"
)
func main() {
u := url.URL{Host: "example.com", Path: "foo"}
fmt.Println(u.IsAbs())
u.Scheme = "http"
fmt.Println(u.IsAbs())
}
Вывод
false
true
Пример в песочнице https://play.golang.org/p/UfOBOdHopyF
Метод MarshalBinary
func (u *URL) MarshalBinary() (text []byte, err error)
Преобразует URL в срез байтов, выдает ошибку если она возникает при преобразовании.
Пример использования метода MarshalBinary
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, _ := url.Parse("https://example.org")
b, err := u.MarshalBinary()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", b)
}
Вывод
https://example.org
Пример в песочнице https://play.golang.org/p/L2uSp9WIN1Y
Метод Parse
func (u *URL) Parse(ref string) (*URL, error)
Parse анализирует URL-адрес в контексте получателя. Предоставленный URL-адрес может быть относительным или абсолютным. Parse возвращает nil, ошибку при сбое синтаксического анализа, в противном случае его возвращаемое значение такое же, как ResolveReference.
Пример использования метода Parse
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/lyPqaigN1pw
Метод Port
func (u *URL) Port() string
Port возвращает часть порта u.Host без начального двоеточия.
Если u.Host не содержит допустимого числового порта, Port возвращает пустую строку.
Пример использования метода Port
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/xcP1_ozPxfG
Метод Query
func (u *URL) Query() Values
Query анализирует RawQuery и возвращает соответствующие значения. Он молча отбрасывает искаженные пары значений. Для проверки ошибок используйте ParseQuery.
Пример использования метода Query
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/MJrTerqSaqd
Метод Redacted
func (u *URL) Redacted() string
Redacted аналогично String, но заменяет любой пароль на "xxxxx". Удаляется только пароль в u.URL.
Пример использования метода Redacted
package main
import (
"fmt"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/FPsxk_4bbCV
Метод RequestURI
func (u *URL) RequestURI() string
RequestURI возвращает закодированный path?query или opaque?query строку, которая будет использоваться в HTTP-запросе для u.
Пример использования метода RequestURI
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
u, err := url.Parse("https://example.org/path?foo=bar")
if err != nil {
log.Fatal(err)
}
fmt.Println(u.RequestURI())
}
Вывод
/path?foo=bar
Пример в песочнице https://play.golang.org/p/QK-lScEgjou
Метод ResolveReference
func (u *URL) ResolveReference(ref *URL) *URL
ResolveReference разрешает ссылку URI на абсолютный URI из абсолютного базового URI u, согласно RFC 3986. Ссылка URI может быть относительной или абсолютной. ResolveReference всегда возвращает новый экземпляр URL, даже если возвращенный URL идентичен базовому или ref. Если ref является абсолютным URL, ResolveReference игнорирует base и возвращает копию ref.
Пример использования метода ResolveReference
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/WGNUEkswSmY
Метод String
func (u *URL) String() string
String повторно собирает URL в допустимую строку URL-адреса. Общий вид результата - один из:
scheme:opaque?query#fragment
scheme://userinfo@host/path?query#fragment
Если u.Opaque не пусто, String использует первую форму; в противном случае используется вторая форма. Любые символы, отличные от ASCII, в host экранируются. Чтобы получить путь (path), 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 опускается.
Пример использования метода String
package main
import (
"fmt"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/trgWI4TlgAP
Метод UnmarshalBinary
func (u *URL) UnmarshalBinary(text []byte) error
Преобразует срез байтов и наполняет поля структуры URL, на которой был вызван. Возвращает ошибку в случае ее возникновения при анализе среза байтов.
Пример использования метода UnmarshalBinary
package main
import (
"fmt"
"log"
"net/url"
)
func main() {
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
Пример в песочнице https://play.golang.org/p/SyeYQ-6_Vy4
Тип Values
type Values map[string][]string
Values сопоставляет строковый ключ со списком значений. Обычно он используется для параметров запроса и значений формы. В отличие от карты http.Header, ключи в карте Values чувствительны к регистру.
Пример использования типа Values
package main
import (
"fmt"
"net/url"
)
func main() {
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"])
fmt.Println(v.Has("name"))
v.Del("name")
fmt.Println(v.Encode())
}
Вывод
friend=Jess&friend=Sarah&friend=Zoe&name=Ava
Ava
Jess
[Jess Sarah Zoe]
true
friend=Jess&friend=Sarah&friend=Zoe
Пример в песочнице https://play.golang.org/p/9Gvyq0Rnlx7
Функция ParseQuery
func ParseQuery(query string) (Values, error)
ParseQuery анализирует строку запроса в кодировке URL и возвращает карту, в которой перечислены значения, указанные для каждого ключа. ParseQuery всегда возвращает ненулевую карту, содержащую все найденные допустимые параметры запроса; err описывает первую обнаруженную ошибку декодирования, если таковая имеется.
Ожидается, что запрос будет списком настроек ключ = значение, разделенных амперсандами. Параметр без знака равенства интерпретируется как ключ, установленный на пустое значение. Параметры, содержащие точку с запятой без кодировки URL, считаются недействительными.
Пример использования функции ParseQuery
package main
import (
"encoding/json"
"fmt"
"log"
"net/url"
"strings"
)
func main() {
m, err := url.ParseQuery(`x=1&y=2&y=3`)
if err != nil {
log.Fatal(err)
}
fmt.Println(toJSON(m))
}
func toJSON(m interface{}) string {
js, err := json.Marshal(m)
if err != nil {
log.Fatal(err)
}
return strings.ReplaceAll(string(js), ",", ", ")
}
Вывод
{"x":["1"], "y":["2", "3"]}
Пример в песочнице https://play.golang.org/p/3ytJDMl5P5y
Методы типа Values
func (v Values) Add(key, value string)
Add добавляет значение к ключу. Он добавляется к любым существующим значениям, связанным с ключом.
func (v Values) Del(key string)
Del удаляет значения, связанные с ключом.
func (v Values) Encode() string
Encode кодирует значения в форму "закодированный URL" ("bar=baz&foo=quux"), отсортированные по ключу.
func (v Values) Get(key string) string
Get получает первое значение, связанное с данным ключом. Если с ключом не связаны никакие значения, Get возвращает пустую строку. Чтобы получить доступ к нескольким значениям, используйте карту напрямую.
func (v Values) Has(key string) bool
Has проверяет, установлен ли данный ключ.
func (v Values) Set(key, value string)
Set устанавливает значение ключа. Он заменяет любые существующие значения.
Читайте также:
- Веб-приложение на Go: введение в пакет net/http, пример веб-сервера на Go
- Пакет net/http, краткий обзор
- Разработка RESTful API с помощью Go и Gin
- Функции пакета net/http, примеры
Комментариев нет:
Отправить комментарий