Skip to content

Commit

Permalink
feat(httereq): support response tool
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuigo committed Jul 15, 2024
1 parent 4d36734 commit 88c856b
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 1 deletion.
28 changes: 28 additions & 0 deletions demo/httpreq/res_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package httpreq

import (
"bytes"
"io"
"net/http"
"testing"

"github.com/ahuigo/gohttptool/httpreq"
)

func TestResponse(t *testing.T) {
response := http.Response{
StatusCode: 200,
Status: "200 OK",
Proto: "HTTP/1.0",
ProtoMajor: 1,
Body: io.NopCloser(bytes.NewBuffer([]byte(`{"name":"ahuigo"}`))),
}
user := struct {
Name string `json:"name"`
}{}
res := httpreq.BuildResponse(&response)
res.Json(&user)
if user.Name != "ahuigo" {
t.Fatalf("json parse error: %v", user)
}
}
179 changes: 179 additions & 0 deletions httpreq/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
package httpreq

import (
"bytes"
"compress/gzip"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/http/httputil"
"net/url"
"os"
)

type httpRes struct {
R *http.Response
Attempt int
body []byte
doNotCloseBody bool
URL *url.URL
client *http.Client
isdebugBody bool
dumpCurl string
dumpResponse string
}

func BuildResponse(response *http.Response) *httpRes {
r := &httpRes{
R: response,
}
// resp.R.Body = ioutil.NopCloser(bytes.NewBuffer(resp.Body())) // important!!
// r._DumpResponse(true)
// r.Body()
return r
}

func (resp *httpRes) SetDoNotCloseBody() *httpRes {
resp.doNotCloseBody = true
return resp
}

func (resp *httpRes) SetClientReq(url *url.URL, client *http.Client) *httpRes {
resp.client = client
resp.URL = url
return resp
}

func (resp *httpRes) ResponseDebug() {
fmt.Println("===========ResponseDebug ============")
err := resp._DumpResponse(resp.isdebugBody)
if err != nil {
return
}
fmt.Println(resp.dumpResponse)
fmt.Println("========== ResponseDebug(end) ============")
}

func (resp *httpRes) _DumpResponse(isdebugBody bool) error {
message, err := httputil.DumpResponse(resp.R, isdebugBody)
resp.dumpResponse = string(message)
return err
}

func (resp *httpRes) GetDumpCurl() string {
return resp.dumpCurl
}
func (resp *httpRes) GetDumpResponse() string {
if resp.dumpResponse == "" {
if resp.R.Body == nil {
resp.R.Body = io.NopCloser(bytes.NewBuffer(resp.Body())) // important!!
}
resp._DumpResponse(true)
}
return resp.dumpResponse
}

func (resp *httpRes) Body() []byte {
var err error
if resp.body != nil {
return resp.body
}
resp.body = []byte{}
if !resp.doNotCloseBody {
defer resp.R.Body.Close()
}

var Body = resp.R.Body
if resp.R.Header.Get("Content-Encoding") == "gzip" {
reader, err := gzip.NewReader(Body)
if err != nil {
return nil
}
Body = reader
}

resp.body, err = io.ReadAll(Body)
if err != nil {
return nil
}

return resp.body
}

func (resp *httpRes) Text() string {
return string(resp.body)
}

func (resp *httpRes) Size() int {
return len(resp.body)
}

func (resp *httpRes) RaiseForStatus() (code int, err error) {
code = resp.R.StatusCode
if resp.R.StatusCode >= 400 && resp.R.StatusCode != 401 {
err = errors.New(resp.Text())
}
return
}

func (resp *httpRes) StatusCode() (code int) {
return resp.R.StatusCode
}

func (resp *httpRes) Header() http.Header {
return resp.R.Header
}

func (resp *httpRes) SaveFile(filename string) error {
if resp.body == nil {
resp.Body()
}
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()

_, err = f.Write(resp.body)
f.Sync()

return err
}

func (resp *httpRes) Json(v interface{}) error {
if resp.body == nil {
resp.Body()
}
return json.Unmarshal(resp.body, v)
}

func (resp *httpRes) Cookies() (cookies []*http.Cookie) {
client := resp.client

if resp.URL == nil || client == nil {
return resp.R.Cookies()
}
// cookies's type is `[]*http.Cookies`
cookies = client.Jar.Cookies(resp.URL)
return cookies
}

func (resp *httpRes) GetCookie(key string) (val string) {
cookies := map[string]string{}
for _, c := range resp.Cookies() {
cookies[c.Name] = c.Value
}
val = cookies[key]
return val
}

func (resp *httpRes) HasCookie(key string) (exists bool) {
cookies := map[string]string{}
for _, c := range resp.Cookies() {
cookies[c.Name] = c.Value
}
_, exists = cookies[key]
return exists
}
3 changes: 3 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,6 @@
[![Contributors](https://img.shields.io/github/contributors/ahuigo/gohttptool)](https://github.com/ahuigo/gohttptool/graphs/contributors)
[![License](https://img.shields.io/github/license/ahuigo/gohttptool)](./LICENSE)

## Features
- [x] Build http request in golang
- [x] Generate curl command for http request
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.0.2
v0.0.3

0 comments on commit 88c856b

Please sign in to comment.