http.go 5.3 KB

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