Matteo
Matteo

Reputation: 2624

Transform http.Response into array of bytes

I am trying to develop a tcp proxy, in this tcp proxy I will have to manipulate both http and tcp requests.

At the moment for the incoming request I detect if it is an http or tcp request, if it is an http then I parse it into an http.Request:


func (s *TcpProxy) OnMessage(c *connection.Connection, ctx interface{}, data []byte) interface{} {
    reader := bytes.NewReader(data)
    newReader := bufio.NewReader(reader)
    req, err := http.ReadRequest(newReader)
    // This is an http request
}

Now I manipulate the request conveniently since I can use the methods exposed from that interface, then eventually I will send the response back from my proxy to the service that received the inbound request.


func (s *TcpProxy) OnMessage(c *connection.Connection, ctx interface{}, data []byte) interface{} {
    reader := bytes.NewReader(data)
    newReader := bufio.NewReader(reader)
    req, err := http.ReadRequest(newReader)
    // Manipulate http request
    // ...
    // Proxy the request
    proxyReq, err := http.NewRequest(req.Method, proxyUrl, req.Body)

    // Capture the duration while making a request to the destination service.
    res, err := httpClient.Do(proxyReq)
    
    buf := res.ToBuffer() // <= How can I achieve this
   
    c.Send(buf)

    c.Close()
    return nil
}

However I cannot find a way to convert back the response into an array of bytes or string, am I missing something?

Upvotes: 2

Views: 3343

Answers (1)

larsks
larsks

Reputation: 311750

An http.Request object has a Write method:

func (r *Request) Write(w io.Writer) error

Write writes an HTTP/1.1 request, which is the header and body, in wire format.

You can use this to write the bytes into a buffer object. For example:

package main

import (
    "bytes"
    "fmt"
    "net/http"
)

func main() {
    var buf bytes.Buffer

    req, err := http.NewRequest("GET", "http://google.com", nil)
    if err != nil {
        panic(err)
    }

    client := &http.Client{}
    res, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer res.Body.Close()

    if err := res.Write(&buf); err != nil {
        panic(err)
    }

    // ...do whatever you want with the buffer here...
    fmt.Println(buf.String())
}

A Buffer object has a Bytes method that will return a byte array, if that's what you want.

Upvotes: 3

Related Questions