Пустой HTTP-ответ с использованием http.Client.Do в Golang

Я использую Go, чтобы сделать HTTP-запрос GET к внешней веб-службе. По какой-то причине тело ответа всегда пусто; длина содержимого всегда равна нулю байтов. Однако код состояния ответа всегда равен 200, и вызов Client.Do не возвращает ошибки. Для запроса требуется заголовок авторизации, поэтому я использую шаблон http.NewRequest/http.Client.Do для отправки запроса, как вы увидите ниже. Я делал подобные запросы в прошлом, но никогда не использовал GET, требующий заголовка. Кажется маловероятным, что это причина, но мне интересно, может ли это быть связано. Если кто-то может обнаружить какие-либо потенциальные проблемы с используемым шаблоном или, возможно, имел подобный опыт, я был бы очень признателен за любую помощь.

Спасибо.

if req, err := http.NewRequest("GET", "https://api.molt.in/v1/orders/11111111/items", nil); err != nil {
    return nil, err
} else {
    client := &http.Client{}
    req.Header.Add("Authorization", "secretToken")

    if resp, err := client.Do(req); err != nil {
        return nil, err
    } else {
        defer resp.Body.Close()
        return readBody(resp.Body)
    }
}

person s.napier    schedule 21.03.2017    source источник
comment
Если ошибки нет, а ответ 200, в чем проблема? Нет требования, чтобы ответ имел тело. Кстати, вы обычно хотите избежать вложенных if-else, когда у вас есть возможность вернуться раньше; большинство людей написали бы это так: play.golang.org/p/q0x8cNvrYw   -  person JimB    schedule 21.03.2017
comment
Вы проверили resp.ContentLength? Что делает readBody?   -  person Ainar-G    schedule 21.03.2017
comment
Каков результат, когда вы выполняете тот же запрос с помощью curl?   -  person Zoyd    schedule 21.03.2017
comment
Вам нужно указать тип авторизации, которую вы пытаетесь выполнить Bearer в этом случае я думаю, что это может быть проблемой, поэтому заголовок будет Authorization: Bearer MY_SUPER_SECRET_TOKEN   -  person zot24    schedule 21.03.2017
comment
Извините, я не привел вам полный правильный пример в моем последнем комментарии, что-то вроде: ``` req.Header.Add(Authorization, fmt.Sprintf(Bearer %s, secretToken)) ```   -  person zot24    schedule 21.03.2017
comment
@JimB, вы правы, однако в этом конкретном случае я ожидаю ответа. Вывод аналогичного вызова, выполненного с использованием cURL, возвращает данные, показанные здесь. Что касается общего соглашения, я ценю поддержку Go встроенного объявления переменной с условием. Это делает код чуть более лаконичным.   -  person s.napier    schedule 22.03.2017
comment
@Ainar-G resp.ContentLength постоянно равен 0. readyBody использует bufio.NewScanner для извлечения содержимого ответа, в конечном итоге создающего с ним структуру.   -  person s.napier    schedule 22.03.2017
comment
Спасибо @ZoT. Я полагаю, что вы можете что-то понять, но разве плохой заголовок авторизации обычно не приводит к статусу ответа 400/401? Я попробую ваше предложение и обновлю вас.   -  person s.napier    schedule 22.03.2017
comment
@ZoT Я попытался обновить заголовок авторизации, как вы предложили. Изменение не повлияло на приложение. Интересно, что это также не повлияло на использование cURL. Похоже, что сервер обрабатывает заголовок одинаково, независимо от того, включен термин Bearer или нет.   -  person s.napier    schedule 22.03.2017
comment
Исправление к исходному сообщению: длина содержимого ответа на самом деле равна -1, а не 0, как сообщалось изначально.   -  person s.napier    schedule 22.03.2017


Ответы (1)


Наконец-то я обнаружил источник проблемы. Это не имело ничего общего с сделанным запросом или полученным ответом. Это было связано с разбором ответа.

Я использовал bufio.NewScanner.Text, чтобы попытаться преобразовать тело ответа в строку. Замена этого вызова вызовом ioutil.ReadAll выводит строку, которую я изначально ожидал.

Спасибо за всю вашу помощь, и извините за вводящий в заблуждение вопрос.

person s.napier    schedule 24.03.2017