github.com/profzone/eden-framework@v1.0.10/pkg/courier/transport_http/request.go (about)

     1  package transport_http
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net"
     8  	"net/http"
     9  	"strings"
    10  	"time"
    11  
    12  	"github.com/sirupsen/logrus"
    13  
    14  	"github.com/profzone/eden-framework/pkg/courier"
    15  	"github.com/profzone/eden-framework/pkg/courier/httpx"
    16  	"github.com/profzone/eden-framework/pkg/courier/status_error"
    17  	"github.com/profzone/eden-framework/pkg/courier/transport_http/transform"
    18  	"github.com/profzone/eden-framework/pkg/duration"
    19  )
    20  
    21  type TransportWrapper func(rt http.RoundTripper) http.RoundTripper
    22  
    23  type HttpRequest struct {
    24  	BaseURL       string
    25  	Method        string
    26  	URI           string
    27  	ID            string
    28  	Metadata      courier.Metadata
    29  	Timeout       time.Duration
    30  	Req           interface{}
    31  	WrapTransport TransportWrapper
    32  }
    33  
    34  func (httpRequest *HttpRequest) Do() (result courier.Result) {
    35  	result = courier.Result{}
    36  	request, err := transform.NewRequest(httpRequest.Method, httpRequest.BaseURL+httpRequest.URI, httpRequest.Req, httpRequest.Metadata)
    37  	if err != nil {
    38  		result.Err = status_error.InvalidRequestParams.StatusError().WithDesc(err.Error())
    39  		return
    40  	}
    41  
    42  	d := duration.NewDuration()
    43  	defer func() {
    44  		logger := d.ToLogger().WithFields(logrus.Fields{
    45  			"request":  httpRequest.ID,
    46  			"method":   httpRequest.Method,
    47  			"url":      request.URL.String(),
    48  			"metadata": httpRequest.Metadata,
    49  		})
    50  
    51  		if result.Err == nil {
    52  			logger.Debugf("success")
    53  		} else {
    54  			logger.Warnf("do http request failed %s", result.Err)
    55  		}
    56  	}()
    57  
    58  	httpClient := GetShortConnClient(httpRequest.Timeout)
    59  
    60  	if httpRequest.WrapTransport != nil {
    61  		httpClient.Transport = httpRequest.WrapTransport(httpClient.Transport)
    62  	}
    63  
    64  	resp, err := httpClient.Do(request)
    65  	if err != nil {
    66  		result.Err = status_error.HttpRequestFailed.StatusError().WithDesc(err.Error())
    67  		return
    68  	}
    69  	defer resp.Body.Close()
    70  
    71  	data, err := ioutil.ReadAll(resp.Body)
    72  
    73  	result.Data = data
    74  	result.Meta = courier.Metadata(resp.Header)
    75  
    76  	contentType := resp.Header.Get(httpx.HeaderContentType)
    77  
    78  	if strings.Contains(contentType, httpx.MIME_JSON) {
    79  		result.Unmarshal = json.Unmarshal
    80  		// todo add more structUnmarshal
    81  	}
    82  
    83  	if !HttpStatusOK(resp.StatusCode) {
    84  		statusError := &status_error.StatusError{}
    85  		err := json.Unmarshal(result.Data, statusError)
    86  		if err != nil {
    87  			msg := fmt.Sprintf("[%d] %s %s", resp.StatusCode, request.Method, request.URL)
    88  			result.Err = status_error.HttpRequestFailed.StatusError().WithDesc(msg)
    89  			return
    90  		}
    91  		result.Err = statusError
    92  	}
    93  	return
    94  }
    95  
    96  func HttpStatusOK(code int) bool {
    97  	return code >= http.StatusOK && code < http.StatusMultipleChoices
    98  }
    99  
   100  func GetShortConnClient(timeout time.Duration) *http.Client {
   101  	return &http.Client{
   102  		Timeout: timeout,
   103  		Transport: &http.Transport{
   104  			Dial: (&net.Dialer{
   105  				Timeout:   timeout,
   106  				KeepAlive: 0,
   107  			}).Dial,
   108  			DisableKeepAlives: true,
   109  		},
   110  	}
   111  }
   112  
   113  func GetLongConnClient(timeout time.Duration) *http.Client {
   114  	return &http.Client{
   115  		Timeout: timeout,
   116  		Transport: &http.Transport{
   117  			Dial: (&net.Dialer{
   118  				Timeout:   timeout,
   119  				KeepAlive: 0,
   120  			}).Dial,
   121  			DisableKeepAlives: false,
   122  		},
   123  	}
   124  }