http.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  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 http.ResponseWriter, contentType string) {
  38. w.Header().Set(`Content-Type`, contentType)
  39. w.Header().Set(`X-Powered-By`, LibName+`/`+LibVersion)
  40. w.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 http.ResponseWriter, 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. func newRequest(method, uri, certPath, keyPath string, header map[string]string, body io.Reader) (res *http.Response, err error) {
  122. t := &http.Transport{
  123. Dial: func(netw, addr string) (net.Conn, error) {
  124. conn, err := net.DialTimeout(netw, addr, time.Second*RequestTimeOut)
  125. if err != nil {
  126. return nil, err
  127. }
  128. conn.SetDeadline(time.Now().Add(time.Second * RequestTimeOut))
  129. return conn, nil
  130. },
  131. ResponseHeaderTimeout: time.Second * RequestTimeOut,
  132. }
  133. if certPath != "" {
  134. cert, e := tls.LoadX509KeyPair(certPath, keyPath)
  135. if e != nil {
  136. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
  137. } else {
  138. pool := x509.NewCertPool()
  139. t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true, Certificates: []tls.Certificate{cert}, RootCAs: pool}
  140. }
  141. }
  142. client := &http.Client{Transport: t}
  143. var (
  144. req *http.Request
  145. )
  146. if body != nil {
  147. req, err = http.NewRequest(method, uri, body)
  148. } else {
  149. req, err = http.NewRequest(method, uri, nil)
  150. }
  151. if err != nil {
  152. return
  153. }
  154. for k := range header {
  155. req.Header.Add(k, header[k])
  156. }
  157. res, err = client.Do(req)
  158. return
  159. }
  160. func readBody(res *http.Response) (msg Message, err error) {
  161. var (
  162. body []byte
  163. reader io.Reader
  164. )
  165. encoding := res.Header.Get("Content-Encoding")
  166. switch encoding {
  167. case "gzip":
  168. reader, err = gzip.NewReader(res.Body)
  169. if err == nil {
  170. body, err = ioutil.ReadAll(reader)
  171. }
  172. default:
  173. body, err = ioutil.ReadAll(res.Body)
  174. }
  175. if err != nil {
  176. return
  177. }
  178. msg.StatusCode = res.StatusCode
  179. msg.Header = res.Header
  180. msg.Body = body
  181. return
  182. }
  183. // Post HTTP request POST
  184. func Post(uri, certPath, keyPath string, header map[string]string, data io.Reader) (msg Message, err error) {
  185. var res *http.Response
  186. if res, err = newRequest("POST", uri, certPath, keyPath, header, data); err != nil {
  187. return
  188. }
  189. defer res.Body.Close()
  190. msg, err = readBody(res)
  191. msg.Cookies = res.Cookies()
  192. return
  193. }
  194. // Get HTTP request GET
  195. func Get(uri, certPath, keyPath string, header map[string]string) (msg Message, err error) {
  196. var res *http.Response
  197. if res, err = newRequest("GET", uri, certPath, keyPath, header, nil); err != nil {
  198. return
  199. }
  200. defer res.Body.Close()
  201. msg, err = readBody(res)
  202. msg.Cookies = res.Cookies()
  203. return
  204. }
  205. // SetCookie set http cookie
  206. func SetCookie(w http.ResponseWriter, name, value, path string, maxAge int) {
  207. cookie := &http.Cookie{
  208. Name: name,
  209. Value: value,
  210. Path: path,
  211. HttpOnly: false,
  212. MaxAge: maxAge}
  213. http.SetCookie(w, cookie)
  214. }