Длина контента в Голанге - PullRequest
0 голосов
/ 21 ноября 2018

Я не смог найти ничего полезного в сети на этом.

Я пишу REST API и хочу записать размер тела запроса в байтах для метрик.Go net / http API не предоставляет этого напрямую.В http.Request есть поле Content-Length, но это поле может быть пустым или клиент может отправить ложные данные.

Есть ли способ получить это на уровне промежуточного программного обеспечения?Метод грубой силы будет читать полное тело и проверять размер.Но если я сделаю это в промежуточном программном обеспечении, у обработчика не будет доступа к телу, потому что он был бы прочитан и закрыт.

Ответы [ 3 ]

0 голосов
/ 21 ноября 2018

Зачем вам здесь середина?
Простой способ: b, err = io.Copy(anyWriterOrMultiwriter, r.Body)
b - общая длина содержимого запроса, когда err == nil
Используйте тело запроса по своему усмотрению.Также b, err = io.Copy(ioutil.Discard, r.Body)

0 голосов
/ 11 июля 2019

Вы можете просто прочитать тело, вычислить размер, затем распаковать в структуру, чтобы она стала:

    b, _ := ioutil.ReadAll(r.Body)

    size := len(b) // can be nil so check err in your app

    if err := json.Unmarshal(b, &input); err != nil {
        s.BadReq(w, errors.New("error reading body"))
        return
    }

0 голосов
/ 21 ноября 2018

Вы можете написать пользовательский ReadCloser, который проксирует существующий и подсчитывает байты по мере поступления.Что-то вроде:

type LengthReader struct {
    Source io.ReadCloser
    Length int
}

func (r *LengthReader) Read(b []byte) (int, error) {
    n, err := r.Source.Read(b)
    r.Length += n
    return n, err
}

func (r *LengthReader) Close() error {
    var buf [32]byte
    var n int
    var err error
    for err == nil {
        n, err = r.Source.Read(buf[:])
        r.Length += n
    }
    closeerr := r.Source.Close()
    if err != nil && err != io.EOF {
        return err
    }
    return closeerr
}

Это будет подсчитывать байты, когда вы читаете их из потока, а когда оно закрыто, оно будет потреблять и считать все оставшиеся непрочитанные байты в первую очередь.После того как вы закончили с потоком, вы можете получить доступ к длине.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...