2019-02-02 16:18:25 +08:00
|
|
|
// Copyright 2017 gf Author(https://github.com/gogf/gf). All Rights Reserved.
|
2017-12-29 16:03:30 +08:00
|
|
|
//
|
|
|
|
// This Source Code Form is subject to the terms of the MIT License.
|
|
|
|
// If a copy of the MIT was not distributed with this file,
|
2019-02-02 16:18:25 +08:00
|
|
|
// You can obtain one at https://github.com/gogf/gf.
|
2017-12-31 18:19:58 +08:00
|
|
|
|
2017-12-07 14:57:16 +08:00
|
|
|
package ghttp
|
|
|
|
|
|
|
|
import (
|
2019-06-19 09:06:52 +08:00
|
|
|
"crypto/tls"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"strconv"
|
|
|
|
"time"
|
2019-07-28 11:50:12 +08:00
|
|
|
|
2019-09-13 20:49:16 +08:00
|
|
|
"github.com/gogf/gf/util/gconv"
|
|
|
|
|
2019-09-11 21:19:45 +08:00
|
|
|
"github.com/gogf/gf/os/gsession"
|
|
|
|
|
2019-08-16 00:29:14 +08:00
|
|
|
"github.com/gogf/gf/os/gview"
|
|
|
|
|
2019-07-29 21:01:19 +08:00
|
|
|
"github.com/gogf/gf/os/gfile"
|
|
|
|
"github.com/gogf/gf/os/glog"
|
2017-12-07 14:57:16 +08:00
|
|
|
)
|
|
|
|
|
2018-04-27 22:12:11 +08:00
|
|
|
const (
|
2019-11-28 23:19:37 +08:00
|
|
|
gDEFAULT_HTTP_ADDR = ":80" // Default listening port for HTTP.
|
|
|
|
gDEFAULT_HTTPS_ADDR = ":443" // Default listening port for HTTPS.
|
2019-12-01 14:07:36 +08:00
|
|
|
URI_TYPE_DEFAULT = 0 // Method name to URI converting type, which converts name to its lower case and joins the words using char '-'.
|
|
|
|
URI_TYPE_FULLNAME = 1 // Method name to URI converting type, which does no converting to the method name.
|
|
|
|
URI_TYPE_ALLLOWER = 2 // Method name to URI converting type, which converts name to its lower case.
|
|
|
|
URI_TYPE_CAMEL = 3 // Method name to URI converting type, which converts name to its camel case.
|
2018-04-27 22:12:11 +08:00
|
|
|
)
|
|
|
|
|
2019-11-07 16:40:34 +08:00
|
|
|
// HTTP Server configuration.
|
2017-12-07 14:57:16 +08:00
|
|
|
type ServerConfig struct {
|
2019-12-01 21:05:46 +08:00
|
|
|
Address string // Basic: Server listening address like ":port", multiple addresses joined using ','.
|
|
|
|
HTTPSAddr string // Basic: HTTPS addresses, multiple addresses joined using char ','.
|
|
|
|
HTTPSCertPath string // Basic: HTTPS certification file path.
|
|
|
|
HTTPSKeyPath string // Basic: HTTPS key file path.
|
|
|
|
TLSConfig *tls.Config // Basic: TLS configuration for use by ServeTLS and ListenAndServeTLS.
|
|
|
|
Handler http.Handler // Basic: Request handler.
|
|
|
|
ReadTimeout time.Duration // Basic: Maximum duration for reading the entire request, including the body.
|
|
|
|
WriteTimeout time.Duration // Basic: Maximum duration before timing out writes of the response.
|
|
|
|
IdleTimeout time.Duration // Basic: Maximum amount of time to wait for the next request when keep-alive is enabled.
|
|
|
|
MaxHeaderBytes int // Basic: Maximum number of bytes the server will read parsing the request header's keys and values, including the request line.
|
|
|
|
KeepAlive bool // Basic: Enable HTTP keep-alive.
|
|
|
|
ServerAgent string // Basic: Server agent information.
|
|
|
|
View *gview.View // Basic: View object for the server.
|
|
|
|
Rewrites map[string]string // Static: URI rewrite rules map.
|
|
|
|
IndexFiles []string // Static: The index files for static folder.
|
|
|
|
IndexFolder bool // Static: List sub-files when requesting folder; server responses HTTP status code 403 if false.
|
|
|
|
ServerRoot string // Static: The root directory for static service.
|
|
|
|
SearchPaths []string // Static: Additional searching directories for static service.
|
|
|
|
StaticPaths []staticPathItem // Static: URI to directory mapping array.
|
|
|
|
FileServerEnabled bool // Static: Switch for static service.
|
|
|
|
CookieMaxAge time.Duration // Cookie: Max TTL for cookie items.
|
|
|
|
CookiePath string // Cookie: Cookie Path(also affects the default storage for session id).
|
|
|
|
CookieDomain string // Cookie: Cookie Domain(also affects the default storage for session id).
|
|
|
|
SessionMaxAge time.Duration // Session: Max TTL for session items.
|
|
|
|
SessionIdName string // Session: Session id name.
|
|
|
|
SessionPath string // Session: Session Storage directory path for storing session files.
|
|
|
|
SessionStorage gsession.Storage // Session: Session Storage implementer.
|
|
|
|
Logger *glog.Logger // Logging: Logger for server.
|
|
|
|
LogPath string // Logging: Directory for storing logging files.
|
|
|
|
LogStdout bool // Logging: Printing logging content to stdout.
|
|
|
|
ErrorStack bool // Logging: Logging stack information when error.
|
|
|
|
ErrorLogEnabled bool // Logging: Enable error logging files.
|
|
|
|
ErrorLogPattern string // Logging: Error log file pattern like: error-{Ymd}.log
|
|
|
|
AccessLogEnabled bool // Logging: Enable access logging files.
|
|
|
|
AccessLogPattern string // Logging: Error log file pattern like: access-{Ymd}.log
|
|
|
|
PProfEnabled bool // PProf: Enable PProf feature.
|
|
|
|
PProfPattern string // PProf: PProf service pattern for router.
|
|
|
|
FormParsingMemory int64 // Other: Max memory in bytes which can be used for parsing multimedia form.
|
|
|
|
NameToUriType int // Other: Type for converting struct method name to URI when registering routes.
|
|
|
|
DumpRouteMap bool // Other: Whether automatically dump route map when server starts.
|
2017-12-07 14:57:16 +08:00
|
|
|
}
|
|
|
|
|
2019-12-01 14:07:36 +08:00
|
|
|
// defaultServerConfig is the default configuration object for server.
|
2019-06-19 09:06:52 +08:00
|
|
|
var defaultServerConfig = ServerConfig{
|
2019-11-07 11:32:25 +08:00
|
|
|
Address: "",
|
2019-09-11 21:19:45 +08:00
|
|
|
HTTPSAddr: "",
|
|
|
|
Handler: nil,
|
|
|
|
ReadTimeout: 60 * time.Second,
|
|
|
|
WriteTimeout: 60 * time.Second,
|
|
|
|
IdleTimeout: 60 * time.Second,
|
|
|
|
MaxHeaderBytes: 1024,
|
|
|
|
KeepAlive: true,
|
|
|
|
IndexFiles: []string{"index.html", "index.htm"},
|
|
|
|
IndexFolder: false,
|
2019-11-07 16:40:34 +08:00
|
|
|
ServerAgent: "GF HTTP Server",
|
2019-09-11 21:19:45 +08:00
|
|
|
ServerRoot: "",
|
|
|
|
StaticPaths: make([]staticPathItem, 0),
|
|
|
|
FileServerEnabled: false,
|
|
|
|
CookieMaxAge: time.Hour * 24 * 365,
|
|
|
|
CookiePath: "/",
|
|
|
|
CookieDomain: "",
|
|
|
|
SessionMaxAge: time.Hour * 24,
|
|
|
|
SessionIdName: "gfsessionid",
|
2019-11-07 20:36:33 +08:00
|
|
|
SessionPath: gsession.DefaultStorageFilePath,
|
2019-11-08 19:52:49 +08:00
|
|
|
Logger: glog.New(),
|
2019-09-11 21:19:45 +08:00
|
|
|
LogStdout: true,
|
2019-09-14 22:53:28 +08:00
|
|
|
ErrorStack: true,
|
2019-09-11 21:19:45 +08:00
|
|
|
ErrorLogEnabled: true,
|
2019-11-07 16:40:34 +08:00
|
|
|
ErrorLogPattern: "error-{Ymd}.log",
|
2019-09-11 21:19:45 +08:00
|
|
|
AccessLogEnabled: false,
|
2019-11-07 16:40:34 +08:00
|
|
|
AccessLogPattern: "access-{Ymd}.log",
|
2019-09-11 21:19:45 +08:00
|
|
|
DumpRouteMap: true,
|
2019-12-01 14:24:56 +08:00
|
|
|
FormParsingMemory: 100 * 1024 * 1024, // 100MB
|
2019-09-11 21:19:45 +08:00
|
|
|
Rewrites: make(map[string]string),
|
2017-12-07 14:57:16 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// Config returns the default ServerConfig object.
|
2018-09-14 13:02:13 +08:00
|
|
|
func Config() ServerConfig {
|
2019-06-19 09:06:52 +08:00
|
|
|
return defaultServerConfig
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// ConfigFromMap creates and returns a ServerConfig object with given map.
|
2019-11-07 11:32:25 +08:00
|
|
|
func ConfigFromMap(m map[string]interface{}) (ServerConfig, error) {
|
2019-09-13 20:49:16 +08:00
|
|
|
config := defaultServerConfig
|
2019-11-06 20:23:41 +08:00
|
|
|
if err := gconv.Struct(m, &config); err != nil {
|
2019-11-07 11:32:25 +08:00
|
|
|
return config, err
|
2019-11-06 20:23:41 +08:00
|
|
|
}
|
2019-11-07 11:32:25 +08:00
|
|
|
return config, nil
|
2019-09-13 20:49:16 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// Handler returns the request handler of the server.
|
|
|
|
func (s *Server) Handler() http.Handler {
|
|
|
|
return s.config.Handler
|
|
|
|
}
|
|
|
|
|
|
|
|
// SetConfig sets the configuration for the server.
|
2019-09-26 20:01:48 +08:00
|
|
|
func (s *Server) SetConfig(c ServerConfig) error {
|
2019-06-19 09:06:52 +08:00
|
|
|
s.config = c
|
2019-11-14 15:41:28 +08:00
|
|
|
// Static.
|
|
|
|
if c.ServerRoot != "" {
|
|
|
|
s.SetServerRoot(c.ServerRoot)
|
|
|
|
}
|
2019-11-07 16:40:34 +08:00
|
|
|
// HTTPS.
|
|
|
|
if c.TLSConfig == nil && c.HTTPSCertPath != "" {
|
|
|
|
s.EnableHTTPS(c.HTTPSCertPath, c.HTTPSKeyPath)
|
|
|
|
}
|
2019-09-26 20:01:48 +08:00
|
|
|
return nil
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetConfigWithMap sets the configuration for the server using map.
|
2019-11-07 11:32:25 +08:00
|
|
|
func (s *Server) SetConfigWithMap(m map[string]interface{}) error {
|
|
|
|
config, err := ConfigFromMap(m)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return s.SetConfig(config)
|
2019-09-13 20:49:16 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetAddr sets the listening address for the server.
|
|
|
|
// The address is like ':80', '0.0.0.0:80', '127.0.0.1:80', '180.18.99.10:80', etc.
|
2019-09-24 20:19:18 +08:00
|
|
|
func (s *Server) SetAddr(address string) {
|
2019-11-07 11:32:25 +08:00
|
|
|
s.config.Address = address
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetPort sets the listening ports for the server.
|
|
|
|
// The listening ports can be multiple.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetPort(port ...int) {
|
|
|
|
if len(port) > 0 {
|
2019-11-07 11:32:25 +08:00
|
|
|
s.config.Address = ""
|
2019-06-19 09:06:52 +08:00
|
|
|
for _, v := range port {
|
2019-11-07 11:32:25 +08:00
|
|
|
if len(s.config.Address) > 0 {
|
|
|
|
s.config.Address += ","
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
2019-11-07 11:32:25 +08:00
|
|
|
s.config.Address += ":" + strconv.Itoa(v)
|
2019-06-19 09:06:52 +08:00
|
|
|
}
|
|
|
|
}
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetHTTPSAddr sets the HTTPS listening ports for the server.
|
2019-09-24 20:19:18 +08:00
|
|
|
func (s *Server) SetHTTPSAddr(address string) {
|
|
|
|
s.config.HTTPSAddr = address
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetHTTPSPort sets the HTTPS listening ports for the server.
|
|
|
|
// The listening ports can be multiple.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetHTTPSPort(port ...int) {
|
|
|
|
if len(port) > 0 {
|
|
|
|
s.config.HTTPSAddr = ""
|
|
|
|
for _, v := range port {
|
|
|
|
if len(s.config.HTTPSAddr) > 0 {
|
|
|
|
s.config.HTTPSAddr += ","
|
|
|
|
}
|
|
|
|
s.config.HTTPSAddr += ":" + strconv.Itoa(v)
|
|
|
|
}
|
|
|
|
}
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// EnableHTTPS enables HTTPS with given certification and key files for the server.
|
|
|
|
// The optional parameter <tlsConfig> specifies custom TLS configuration.
|
2019-11-07 16:40:34 +08:00
|
|
|
func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...*tls.Config) {
|
2019-06-19 09:06:52 +08:00
|
|
|
certFileRealPath := gfile.RealPath(certFile)
|
|
|
|
if certFileRealPath == "" {
|
|
|
|
certFileRealPath = gfile.RealPath(gfile.Pwd() + gfile.Separator + certFile)
|
|
|
|
if certFileRealPath == "" {
|
|
|
|
certFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + certFile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if certFileRealPath == "" {
|
|
|
|
glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: certFile "%s" does not exist`, certFile))
|
|
|
|
}
|
|
|
|
keyFileRealPath := gfile.RealPath(keyFile)
|
|
|
|
if keyFileRealPath == "" {
|
|
|
|
keyFileRealPath = gfile.RealPath(gfile.Pwd() + gfile.Separator + keyFile)
|
|
|
|
if keyFileRealPath == "" {
|
|
|
|
keyFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + keyFile)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if keyFileRealPath == "" {
|
|
|
|
glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: keyFile "%s" does not exist`, keyFile))
|
|
|
|
}
|
|
|
|
s.config.HTTPSCertPath = certFileRealPath
|
|
|
|
s.config.HTTPSKeyPath = keyFileRealPath
|
|
|
|
if len(tlsConfig) > 0 {
|
|
|
|
s.config.TLSConfig = tlsConfig[0]
|
|
|
|
}
|
2019-03-19 17:48:37 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetTLSConfig sets custom TLS configuration and enables HTTPS feature for the server.
|
2019-11-07 16:40:34 +08:00
|
|
|
func (s *Server) SetTLSConfig(tlsConfig *tls.Config) {
|
2019-06-19 09:06:52 +08:00
|
|
|
s.config.TLSConfig = tlsConfig
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetReadTimeout sets the ReadTimeout for the server.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetReadTimeout(t time.Duration) {
|
|
|
|
s.config.ReadTimeout = t
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetWriteTimeout sets the WriteTimeout for the server.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetWriteTimeout(t time.Duration) {
|
|
|
|
s.config.WriteTimeout = t
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetIdleTimeout sets the IdleTimeout for the server.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetIdleTimeout(t time.Duration) {
|
|
|
|
s.config.IdleTimeout = t
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetMaxHeaderBytes sets the MaxHeaderBytes for the server.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetMaxHeaderBytes(b int) {
|
|
|
|
s.config.MaxHeaderBytes = b
|
2018-08-12 12:22:02 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetServerAgent sets the ServerAgent for the server.
|
2019-06-19 09:06:52 +08:00
|
|
|
func (s *Server) SetServerAgent(agent string) {
|
|
|
|
s.config.ServerAgent = agent
|
2018-11-23 09:20:45 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetKeepAlive sets the KeepAlive for the server.
|
2019-06-02 22:19:52 +08:00
|
|
|
func (s *Server) SetKeepAlive(enabled bool) {
|
2019-06-19 09:06:52 +08:00
|
|
|
s.config.KeepAlive = enabled
|
2019-06-02 22:19:52 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// SetView sets the View for the server.
|
2019-08-16 00:29:14 +08:00
|
|
|
func (s *Server) SetView(view *gview.View) {
|
|
|
|
s.config.View = view
|
|
|
|
}
|
|
|
|
|
2019-11-28 23:19:37 +08:00
|
|
|
// GetName returns the name of the server.
|
2018-08-12 12:22:02 +08:00
|
|
|
func (s *Server) GetName() string {
|
2019-06-19 09:06:52 +08:00
|
|
|
return s.name
|
|
|
|
}
|