http.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package util
  2. import (
  3. "compress/gzip"
  4. "context"
  5. "crypto/x509"
  6. "encoding/json"
  7. "encoding/xml"
  8. "fmt"
  9. "io"
  10. "io/ioutil"
  11. "log"
  12. "net"
  13. "net/http"
  14. "os"
  15. "os/signal"
  16. "syscall"
  17. "time"
  18. "crypto/tls"
  19. )
  20. const (
  21. // RequestTimeOut http request timeout (second)
  22. RequestTimeOut = 30
  23. )
  24. // RouterHandler hander
  25. type RouterHandler struct {
  26. Method string
  27. Router string
  28. Hander http.Handler
  29. }
  30. // Message HTTP response
  31. type Message struct {
  32. StatusCode int
  33. Body []byte
  34. Header http.Header
  35. Cookies []*http.Cookie
  36. }
  37. func header(w io.Writer, contentType string) {
  38. w.(http.ResponseWriter).Header().Set(`Content-Type`, contentType)
  39. w.(http.ResponseWriter).Header().Set(`X-Powered-By`, LibName+`/`+LibVersion)
  40. w.(http.ResponseWriter).WriteHeader(http.StatusOK)
  41. }
  42. // Redirect redirect
  43. func Redirect(w http.ResponseWriter, url string) {
  44. w.Header().Set(`Location`, url)
  45. w.WriteHeader(http.StatusFound)
  46. }
  47. // GetRealIP get real IP from Request
  48. func GetRealIP(req *http.Request) (ip string) {
  49. if ips := req.Header["X-Real-Ip"]; ips != nil {
  50. ip = ips[0]
  51. }
  52. return
  53. }
  54. // WriteJSON response JSON data.
  55. func WriteJSON(w io.Writer, response interface{}) error {
  56. header(w, `application/json; charset=utf-8`)
  57. return json.NewEncoder(w).Encode(response)
  58. }
  59. // WriteXML response XML data.
  60. func WriteXML(w http.ResponseWriter, response interface{}) error {
  61. header(w, `application/xml; charset=utf-8`)
  62. return xml.NewEncoder(w).Encode(response)
  63. }
  64. // WriteBytes response bytes
  65. func WriteBytes(w http.ResponseWriter, response interface{}) error {
  66. header(w, `text/html; charset=utf-8`)
  67. w.Write(response.([]byte))
  68. return nil
  69. }
  70. // WriteBytesContentType response bytes and Content-Type
  71. func WriteBytesContentType(w http.ResponseWriter, response interface{}, contentType string) error {
  72. header(w, contentType)
  73. w.Write(response.([]byte))
  74. return nil
  75. }
  76. // WriteCtxJSON response JSON data.
  77. func WriteCtxJSON(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  78. return WriteJSON(w, response)
  79. }
  80. // WriteCtxXML response XML data.
  81. func WriteCtxXML(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  82. return WriteXML(w, response)
  83. }
  84. // WriteCtxBytes response text data.
  85. func WriteCtxBytes(ctx context.Context, w http.ResponseWriter, response interface{}) error {
  86. return WriteBytes(w, response)
  87. }
  88. // ResponseJSON reply JSON
  89. func ResponseJSON(reply *ReplyData, err error, req *http.Request, w http.ResponseWriter) error {
  90. if err != nil {
  91. return WriteJSON(w, ErrReplyData(ErrException, err.Error()))
  92. }
  93. return WriteJSON(w, reply)
  94. }
  95. // HTTPListenAndServe new server and start
  96. func HTTPListenAndServe(addr string, router http.Handler) {
  97. server := &http.Server{
  98. Addr: addr,
  99. Handler: router,
  100. ReadTimeout: 30 * time.Second,
  101. WriteTimeout: 30 * time.Second,
  102. MaxHeaderBytes: 1 << 20,
  103. }
  104. // Interrupt handler.
  105. errc := make(chan error)
  106. go func() {
  107. c := make(chan os.Signal)
  108. signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
  109. errc <- fmt.Errorf("%s", <-c)
  110. }()
  111. // HTTP transport.
  112. go func() {
  113. log.Println("HTTP Server listen on", addr)
  114. //logger.Log("Protocol", "HTTP", "addr", addr)
  115. errc <- server.ListenAndServe()
  116. log.Println("Exit HTTP server", "Quit")
  117. }()
  118. // Run!
  119. log.Println("Exit", <-errc)
  120. }
  121. // newHTTPRequest http request
  122. func newHTTPRequest(method, uri, certPath, keyPath string, header map[string]string, cookies []*http.Cookie, body io.Reader) (res *http.Response, err error) {
  123. t := &http.Transport{
  124. Dial: func(netw, addr string) (net.Conn, error) {
  125. conn, err := net.DialTimeout(netw, addr, time.Second*RequestTimeOut)
  126. if err != nil {
  127. return nil, err
  128. }
  129. conn.SetDeadline(time.Now().Add(time.Second * RequestTimeOut))
  130. return conn, nil
  131. },
  132. ResponseHeaderTimeout: time.Second * RequestTimeOut,
  133. }
  134. if certPath != "" {
  135. cert, e := tls.LoadX509KeyPair(certPath, keyPath)
  136. if e != nil {
  137. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
  138. } else {
  139. pool := x509.NewCertPool()
  140. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true, Certificates: []tls.Certificate{cert}, RootCAs: pool}
  141. }
  142. }
  143. client := &http.Client{Transport: t}
  144. var (
  145. req *http.Request
  146. )
  147. if cookies != nil {
  148. }
  149. if body != nil {
  150. req, err = http.NewRequest(method, uri, body)
  151. } else {
  152. req, err = http.NewRequest(method, uri, nil)
  153. }
  154. if err != nil {
  155. return
  156. }
  157. for k := range header {
  158. req.Header.Add(k, header[k])
  159. }
  160. res, err = client.Do(req)
  161. return
  162. }
  163. func readBody(res *http.Response) (msg Message, err error) {
  164. var (
  165. body []byte
  166. reader io.Reader
  167. )
  168. encoding := res.Header.Get("Content-Encoding")
  169. switch encoding {
  170. case "gzip":
  171. reader, err = gzip.NewReader(res.Body)
  172. if err == nil {
  173. body, err = ioutil.ReadAll(reader)
  174. }
  175. default:
  176. body, err = ioutil.ReadAll(res.Body)
  177. }
  178. if err != nil {
  179. return
  180. }
  181. msg.StatusCode = res.StatusCode
  182. msg.Header = res.Header
  183. msg.Body = body
  184. return
  185. }
  186. // Post HTTP request POST
  187. func Post(uri, certPath, keyPath string, header map[string]string, data io.Reader) (msg Message, err error) {
  188. var res *http.Response
  189. if res, err = newHTTPRequest("POST", uri, certPath, keyPath, header, nil, data); err != nil {
  190. return
  191. }
  192. defer res.Body.Close()
  193. msg, err = readBody(res)
  194. msg.Cookies = res.Cookies()
  195. return
  196. }
  197. // Get HTTP request GET
  198. func Get(uri, certPath, keyPath string, header map[string]string) (msg Message, err error) {
  199. var res *http.Response
  200. if res, err = newHTTPRequest("GET", uri, certPath, keyPath, header, nil, nil); err != nil {
  201. return
  202. }
  203. defer res.Body.Close()
  204. msg, err = readBody(res)
  205. msg.Cookies = res.Cookies()
  206. return
  207. }
  208. // SetCookie set http cookie
  209. func SetCookie(w http.ResponseWriter, name, value, path string, maxAge int) {
  210. cookie := &http.Cookie{
  211. Name: name,
  212. Value: value,
  213. Path: path,
  214. HttpOnly: false,
  215. MaxAge: maxAge}
  216. http.SetCookie(w, cookie)
  217. }