新建curl包,加入两个文件 request.go 和 response.go文件
request.go
package curl
import (
"bytes"
"encoding/json"
"errors"
"io"
"log"
"net"
"net/http"
"time"
)
// Request Type
type Request struct {
cli *http.Client
req *http.Request
Raw *http.Request
Method string
Url string
dialTimeout time.Duration
responseTimeOut time.Duration
Headers map[string]string
Cookies map[string]string
Queries map[string]string
BodyData map[string]interface{}
}
func NewRequest() *Request {
r := &Request{}
r.dialTimeout = 5
r.responseTimeOut = 5
return r
}
func (r *Request) SetMethod(method string) *Request {
r.Method = method
return r
}
func (r *Request) SetUrl(url string) *Request {
r.Url = url
return r
}
func (r *Request) SetHeaders(headers map[string]string) *Request {
r.Headers = headers
return r
}
func (r *Request) setHeaders() error {
for k, v := range r.Headers {
r.req.Header.Set(k, v)
}
return nil
}
func (r *Request) SetCookies(cookies map[string]string) *Request {
r.Cookies = cookies
return r
}
func (r *Request) setCookies() error {
for k, v := range r.Cookies {
r.req.AddCookie(&http.Cookie{
Name: k,
Value: v,
})
}
return nil
}
// set url query param
func (r *Request) SetQueries(queries map[string]string) *Request {
r.Queries = queries
return r
}
func (r *Request) setQueries() error {
q := r.req.URL.Query()
for k, v := range r.Queries {
q.Add(k, v)
}
r.req.URL.RawQuery = q.Encode()
return nil
}
type BodyData map[string]interface{}
// set BodyData param data
func (r *Request) SetBodyData(bodyData BodyData) *Request {
r.BodyData = bodyData
return r
}
// get request
func (r *Request) Get() (*Response, error) {
return r.Send(r.Url, http.MethodGet)
}
// post request
func (r *Request) Post() (*Response, error) {
return r.Send(r.Url, http.MethodPost)
}
// put request
func (r *Request) Put() (*Response, error) {
return r.Send(r.Url, http.MethodPut)
}
// delete request
func (r *Request) Delete() (*Response, error) {
return r.Send(r.Url, http.MethodDelete)
}
// Patch request
func (r *Request) Patch() (*Response, error) {
return r.Send(r.Url, http.MethodPatch)
}
// SetDialTimeOut
func (r *Request) SetDialTimeOut(TimeOutSecond int) {
r.dialTimeout = time.Duration(TimeOutSecond)
}
// SetResponseTimeOut
func (r *Request) SetResponseTimeOut(TimeOutSecond int) {
r.responseTimeOut = time.Duration(TimeOutSecond)
}
// send request
func (r *Request) Send(url string, method string) (*Response, error) {
// check url
if url == "" {
return nil, errors.New("Lack of request url")
}
// check method
if method == "" {
return nil, errors.New("Lack of request method")
}
// init response
response := NewResponse()
r.cli = &http.Client{
Transport: &http.Transport{
Dial: func(netw, addr string) (net.Conn, error) {
conn, err := net.DialTimeout(netw, addr, time.Second*r.dialTimeout)
if err != nil {
return nil, err
}
conn.SetDeadline(time.Now().Add(time.Second * r.dialTimeout))
return conn, nil
},
ResponseHeaderTimeout: time.Second * r.responseTimeOut,
},
}
// load post data to http.Request
var payload io.Reader
if r.BodyData != nil {
if jData, err := json.Marshal(r.BodyData); err != nil {
return nil, err
} else {
payload = bytes.NewReader(jData)
}
} else {
payload = nil
}
log.Println("method:" + method)
log.Println("url:" + url)
if req, err := http.NewRequest(method, url, payload); err != nil {
return nil, err
} else {
r.req = req
}
r.setHeaders()
r.setCookies()
r.setQueries()
r.Raw = r.req
if resp, err := r.cli.Do(r.req); err != nil {
return nil, err
} else {
response.Raw = resp
}
defer response.Raw.Body.Close()
response.parseHeaders()
response.parseBody()
return response, nil
}
response.go
package curl
import (
"io/ioutil"
"net/http"
)
type Response struct {
Raw *http.Response
Headers map[string]string
Body string
}
func NewResponse() *Response {
return &Response{}
}
func (this *Response) IsOk() bool {
return this.Raw.StatusCode == 200
}
func (this *Response) parseHeaders() error {
headers := map[string]string{}
for k, v := range this.Raw.Header {
headers[k] = v[0]
}
this.Headers = headers
return nil
}
func (this *Response) parseBody() error {
if body, err := ioutil.ReadAll(this.Raw.Body); err != nil {
panic(err)
} else {
this.Body = string(body)
}
return nil
}
调用
测试
package test
import (
//"xxxxx/model"
"xxxxx/flags"
"xxxxx/response"
"xxxxx/services"
"xxxxx/util"
"xxxxx/curl"
"encoding/json"
"log"
"testing"
)
type TestHandleTagDetailResp struct {
Success bool `json:"success"`
Error services.ErrorContext `json:"error"`
Results []response.TagDetail `json:"results,omitempty"`
}
var testHandleTagDetailResp TestHandleTagDetailResp = TestHandleTagDetailResp{}
type TestHandleTagsResp struct {
Success bool `json:"success"`
Error services.ErrorContext `json:"error"`
Results response.Tags `json:"results,omitempty"`
}
var testHandleTagsResp TestHandleTagsResp = TestHandleTagsResp{}
type TestHandleTagsSimpleResp struct {
Success bool `json:"success"`
Error services.ErrorContext `json:"error"`
Results interface{} `json:"results,omitempty"`
}
var testHandleTagsSimpleResp TestHandleTagsSimpleResp = TestHandleTagsSimpleResp{}
func TestTagsHandle(t *testing.T) {
testTagsHandleInit()
testHandleV1TagsPost(t)
testHandleV1TagsTagIdDelete(t)
testHandleV1TagsTagIdPut(t)
testHandleV1TagsAllGet(t)
testHandleV1TagsActiveGet(t)
}
func testTagsHandleInit() {
}
func testHandleV1TagsPost(t *testing.T) {
url := getTestBaseUrl() + "v1/tags"
headers := map[string]string{
"Authorization": getAuthorization(),
"Content-Type": "application/json",
}
bodyData := curl.BodyData{
"name": util.GetRandString(15),
"type": "type test",
"author_id": getTestUserId(),
}
// curl
req := curl.NewRequest()
resp, err := req.
SetUrl(url).
SetHeaders(headers).
SetBodyData(bodyData).
Post()
if err != nil {
log.Println(err)
t.Fatal(err)
}
if !resp.IsOk() {
log.Println(resp.Raw)
t.Fatal(resp.Raw)
}
json.Unmarshal([]byte(resp.Body), &testHandleTagsResp)
// check return status
if testHandleTagsResp.Success != true {
t.Fatal(resp.Body)
}
}
func testHandleV1TagsTagIdDelete(t *testing.T) {
tagId := testHandleTagsResp.Results.ID
log.Println("tagId:" + tagId)
//tagId := "1065797634779779072"
url := getTestBaseUrl() + "v1/tags/" + tagId
headers := map[string]string{
"Authorization": getAuthorization(),
"Content-Type": "application/json",
}
// curl
req := curl.NewRequest()
resp, err := req.
SetUrl(url).
SetHeaders(headers).
Delete()
if err != nil {
log.Println(err)
t.Fatal(err)
}
if !resp.IsOk() {
log.Println(resp.Raw)
t.Fatal(resp.Raw)
}
json.Unmarshal([]byte(resp.Body), &testHandleTagsSimpleResp)
// check return status
if testHandleTagsSimpleResp.Success != true {
t.Fatal(resp.Body)
}
}
func testHandleV1TagsTagIdPut(t *testing.T) {
tagId := testHandleTagsResp.Results.ID
//tagId := "1065797634779779072"
url := getTestBaseUrl() + "v1/tags/" + tagId
headers := map[string]string{
"Authorization": getAuthorization(),
"Content-Type": "application/json",
}
// curl
req := curl.NewRequest()
resp, err := req.
SetUrl(url).
SetHeaders(headers).
Put()
if err != nil {
log.Println(err)
t.Fatal(err)
}
if !resp.IsOk() {
log.Println(resp.Raw)
t.Fatal(resp.Raw)
}
json.Unmarshal([]byte(resp.Body), &testHandleTagsSimpleResp)
// check return status
if testHandleTagsSimpleResp.Success != true {
t.Fatal(resp.Body)
}
}
func testHandleV1TagsAllGet(t *testing.T) {
url := getTestBaseUrl() + "v1/tags/all"
headers := map[string]string{
"Authorization": getAuthorization(),
"Content-Type": "application/json",
}
// curl
req := curl.NewRequest()
resp, err := req.
SetUrl(url).
SetHeaders(headers).
Get()
if err != nil {
log.Println(err)
t.Fatal(err)
}
if !resp.IsOk() {
log.Println(resp.Raw)
t.Fatal(resp.Raw)
}
json.Unmarshal([]byte(resp.Body), &testHandleTagDetailResp)
// check return status
if testHandleTagDetailResp.Success != true {
t.Fatal(resp.Body)
}
}
func testHandleV1TagsActiveGet(t *testing.T) {
url := getTestBaseUrl() + "v1/tags/active"
headers := map[string]string{
"Authorization": getAuthorization(),
"Content-Type": "application/json",
}
// curl
req := curl.NewRequest()
resp, err := req.
SetUrl(url).
SetHeaders(headers).
Get()
if err != nil {
log.Println(err)
t.Fatal(err)
}
if !resp.IsOk() {
log.Println(resp.Raw)
t.Fatal(resp.Raw)
}
json.Unmarshal([]byte(resp.Body), &testHandleTagDetailResp)
// check return status
if testHandleTagDetailResp.Success != true {
t.Fatal(resp.Body)
}
// check data status
status := flags.TAGS_ACTIVIED_STATUS
for _, tagDetail := range testHandleTagDetailResp.Results {
if tagDetail.Status != status {
t.Fatal("[testHandleV1TagsActiveGet]: tagDetail.Status expected result is ", status, ", but got", tagDetail.Status)
}
}
}