2013-07-16 2 views
1

В HTTP-сервере Go Go я могу получить тело запроса POST. Go net/http package, кажется, удаляет тело запроса GET. Я знаю, что лучше не использовать http GET with request body, но мне нужно обработать http GET с телом запроса. Возможно ли это без изменения стандартной библиотеки? Пожалуйста, помогите, так как я не хочу возвращаться к C с libevent!Как разобрать http Получить запрос тела в Go http-сервера?

Когда клиент отправляет POST с телом запроса, ниже код отображает содержимое тела. Но когда клиент отправляет GET с телом запроса, в теле ничего нет.

func handler(w http.ResponseWriter, r *http.Request) { 
    defer r.Body.Close() 
    body, _ := ioutil.ReadAll(r.Body) 

    log.Printf("body: %v", string(body)) 
} 

func main() { 
    http.HandleFunc("/", handler) 
    http.ListenAndServe(":8080", nil) 
} 
+0

Вы «** нуждаетесь в ** для обработки http GET с телом запроса»? В самом деле ? Вероятно, в вашем дизайне есть проблема. –

+0

Я не могу изменить протокол. Мне бы хотелось, чтобы я мог. – gosharplite

+0

Можете ли вы опубликовать пример кода, который вы * хотите * реализовать? Трудно понять, что вы просите. – elithrar

ответ

3

Большая часть магии происходит в transfer.go. Вот что я обнаружил, что выглядит актуальным в fixLength FUNC:

if !isResponse && requestMethod == "GET" { 
    // RFC 2616 doesn't explicitly permit nor forbid an 
    // entity-body on a GET request so we permit one if 
    // declared, but we default to 0 here (not -1 below) 
    // if there's no mention of a body. 
    return 0, nil 
} 

Похоже, до тех пор, как ваш клиент окончание Content-Length заголовка, вы все хорошо. Если нет, библиотека предположит, что тела нет в запросе GET.

Вы находитесь на краю карты, так как ваш клиент делает довольно необычные/сломанные вещи. Если вы можете исправить клиента, это ваш лучший выбор.

При этом, если у вас есть клиент, вам нужно поддержать это, чтобы сделать это неправильно, вам придется самому катить вещи. Вам не нужно идти вплоть до C и libevent. Просто скопируйте net/http-пакет из стандартной библиотеки в свой проект и измените его. Затем измените свои операторы импорта, чтобы указать на вашу версию библиотеки.

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

+0

Вы правы. Когда GET не указывает Content-Length, r.Body является eofReader (eofReader - это non-nil io.ReadCloser, который всегда возвращает EOF). – gosharplite

Смежные вопросы