Почему request.URL.Host и Scheme пусты на сервере разработки?

Я новичок в Go. Сначала попробовал этот hello, world из документации и захотел прочитать Host и Scheme. из запроса:

package hello

import (
    "fmt"
    "http"
)

func init() {
    http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
    fmt.Fprint(w, "Host: " + r.URL.Host + " Scheme: " + r.URL.Scheme)
}

Но их значения оба пусты. Почему?


person moraes    schedule 01.08.2011    source источник


Ответы (1)


По сути, поскольку вы обращаетесь к HTTP-серверу не через HTTP-прокси, браузер может выдать относительный HTTP-запрос, например:

GET / HTTP/1.1
Host: localhost:8080

(Учитывая, конечно, что сервер прослушивает локальный порт 8080).

Теперь, если вы обращались к указанному серверу с помощью прокси-сервера, прокси-сервер может использовать абсолютный URL-адрес:

GET http://localhost:8080/ HTTP/1.1
Host: localhost:8080

В обоих случаях вы получаете от Go http.Request.URL необработанный URL-адрес (проанализированный библиотекой). В случае, если вы получаете доступ к URL-адресу по относительному пути, отсюда и отсутствие хоста или схемы в объекте URL-адреса.

Если вы хотите получить HTTP-хост, вы можете получить доступ к атрибуту Host структуры http.Request. См. http://golang.org/pkg/http/#Request.

Вы можете проверить это, используя netcat и соответствующим образом отформатированный HTTP-запрос (вы можете скопировать вышеуказанные блоки, убедитесь, что в вашем файле есть пустая строка). Чтобы попробовать:

cat my-http-request-file | nc localhost 8080

Кроме того, вы можете проверить на сервере/обработчике, получаете ли вы относительный или абсолютный URL-адрес в запросе, вызвав метод IsAbs():

isAbsoluteURL := r.URL.IsAbs()
person jmibanez    schedule 02.08.2011
comment
Интересный. Спасибо, что так подробно. Тем не менее, немного странно, что их нет при использовании сервера разработки (я предполагаю, что сервер разработки настроит какую-то хост-среду для выполнения запроса). request.Host работал, но для использования URL.Scheme мне нужно будет условно проверить, используется ли сервер разработки или нет. - person moraes; 02.08.2011
comment
Спасибо за ответ! Не могли бы вы рассказать, как предотвратить такое поведение (головная боль при разборе URL)? Потому что я даже не могу получить схему из объекта Request :( Это нормально? - person Timur Fayzrakhmanov; 17.02.2015
comment
Стоит отметить, что иногда таким образом можно обнаружить ботов (они используют полный URL-адрес при запросе страницы). - person Xeoncross; 28.11.2016
comment
Вы можете отличить https от http, используя атрибут r.TLS. Если это http, r.TLS == nil будет ложным, а в https — истинным. Источник: 01happy.com/golang-get-full-url - person navigaid; 31.07.2017
comment
Это не совсем так. Я использую запрос с абсолютным путем, включая схему (ws://). И поле Scheme тоже пустое. @navigaid Это также будет верно в случае схемы wss, поэтому недостаточно соответствовать только запросам https, - person Emrys Myrooin; 19.09.2017