http.go 5.5 KB

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