티스토리 뷰

반응형

개요

 

원문링크: https://medium.com/@xoen/golang-read-from-an-io-readwriter-without-loosing-its-content-2c6911805361

* 음… 이건 거의 원문 번역이 되어 버리는 합니다

 

이런 상황을 가정해보자

 

1) HTTP Request 를 받았다.

2) Request 의 body 내용을 보고  이런저런 처리를 한 다음에

3) 본격적인 처리를 하는 Controller 에게 Request body 를 넘겨주고 싶다.

 

 

시도와 낭패

 

Request body byte string 으로 읽어내려면 ioutil.ReadAll() 쓰면 된다.

 

var bodyBytes []byte

if body != nil {

  bodyBytes, _ = ioutil.ReadAll(c.Request.Body)

}

bodyString := string(bodyBytes)

 

그런데 다시 한 번, c.Request.Body 의 내용을 읽으려 하면 아무것도 없다는 것에 당황하게 된다.

Request.Body 는 io.ReadCloser type 이며 이 타입은 마치 물을 담은 생수통과 같다.

 

1) ioutil.ReadAll() 이라는 밸브로 일단 물을 뽑아내고 나면

2) 생수통은 텅텅 비게 되는 것이다.

 

 

해법

 

해법을 알면 간단하다.

 

1) 일단 ioutil.ReadAll() 사용하면 Reqeust.Body 라는 생수통은 텅텅 비게 된다.

2) 텅텅 생수통인 c.Reqeust.Body

- 방금 받은 물인 bodyBytes bytes.NewBuffer() 이용하여  새로운 버퍼를 생성한 다음

- ioutil.NopCloser() ReadCloser 만들어 넣어주면 된다.

3) 그리곤 남아있는, 받아놓은 물이 bodyBytes 하고픈 일을 하면 된다.

 

 

// Read the content

var bodyBytes []byte

if c.Request.Body != nil {

  bodyBytes, _ = ioutil.ReadAll(c.Request.Body)

}

// Restore the io.ReadCloser to its original state

c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(bodyBytes))

// Use the content

bodyString := string(bodyBytes)

 

(참고)

NewBuffer creates and initializes a new Buffer using buf as its initial contents. The new Buffer takes ownership of buf, and the caller should not use buf after this call. NewBuffer is intended to prepare a Buffer to read existing data. It can also be used to size the internal buffer for writing. To do that, buf should have the desired capacity but a length of zero.

In most cases, new(Buffer) (or just declaring a Buffer variable) is sufficient to initialize a Buffer.

 

 

실전 예시

 

원문 포스팅을 구글링으로 찾게 코드이다.

 

1) req.Body 내용을 ioutil.ReadAll() 읽어낸 다음

2) 비어 있는 req.Body ioutil.NopCloser(bytes.NewBuffer()) 채워놓고

3) 덩그러니 남은 bodyBytes 원하는 작업을 하고 있다.

 

 


반응형
댓글
댓글쓰기 폼