github.com/zhongdalu/gf@v1.0.0/g/net/ghttp/ghttp_server_config.go (about)

     1  // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/zhongdalu/gf.
     6  
     7  package ghttp
     8  
     9  import (
    10  	"crypto/tls"
    11  	"fmt"
    12  	"net/http"
    13  	"strconv"
    14  	"time"
    15  
    16  	"github.com/zhongdalu/gf/g/os/gfile"
    17  	"github.com/zhongdalu/gf/g/os/glog"
    18  )
    19  
    20  const (
    21  	gDEFAULT_HTTP_ADDR                 = ":80"         // 默认HTTP监听地址
    22  	gDEFAULT_HTTPS_ADDR                = ":443"        // 默认HTTPS监听地址
    23  	NAME_TO_URI_TYPE_DEFAULT           = 0             // 服务注册时对象和方法名称转换为URI时,全部转为小写,单词以'-'连接符号连接
    24  	NAME_TO_URI_TYPE_FULLNAME          = 1             // 不处理名称,以原有名称构建成URI
    25  	NAME_TO_URI_TYPE_ALLLOWER          = 2             // 仅转为小写,单词间不使用连接符号
    26  	NAME_TO_URI_TYPE_CAMEL             = 3             // 采用驼峰命名方式
    27  	gDEFAULT_COOKIE_PATH               = "/"           // 默认path
    28  	gDEFAULT_COOKIE_MAX_AGE            = 86400 * 365   // 默认cookie有效期(一年)
    29  	gDEFAULT_SESSION_MAX_AGE           = 86400         // 默认session有效期(一天)
    30  	gDEFAULT_SESSION_ID_NAME           = "gfsessionid" // 默认存放Cookie中的SessionId名称
    31  	gCHANGE_CONFIG_WHILE_RUNNING_ERROR = "cannot be changed while running"
    32  )
    33  
    34  // 自定义日志处理方法类型
    35  type LogHandler func(r *Request, error ...interface{})
    36  
    37  // HTTP Server 设置结构体,静态配置
    38  type ServerConfig struct {
    39  	// 底层http对象配置
    40  	Addr           string        // 监听IP和端口,监听本地所有IP使用":端口"(支持多个地址,使用","号分隔)
    41  	HTTPSAddr      string        // HTTPS服务监听地址(支持多个地址,使用","号分隔)
    42  	HTTPSCertPath  string        // HTTPS证书文件路径
    43  	HTTPSKeyPath   string        // HTTPS签名文件路径
    44  	Handler        http.Handler  // 默认的处理函数
    45  	ReadTimeout    time.Duration // 读取超时
    46  	WriteTimeout   time.Duration // 写入超时
    47  	IdleTimeout    time.Duration // 等待超时
    48  	MaxHeaderBytes int           // 最大的header长度
    49  	TLSConfig      tls.Config
    50  	KeepAlive      bool
    51  
    52  	// 静态文件配置
    53  	IndexFiles        []string         // 默认访问的文件列表
    54  	IndexFolder       bool             // 如果访问目录是否显示目录列表
    55  	ServerAgent       string           // Server Agent
    56  	ServerRoot        string           // 服务器服务的本地目录根路径(检索优先级比StaticPaths低)
    57  	SearchPaths       []string         // 静态文件搜索目录(包含ServerRoot,按照优先级进行排序)
    58  	StaticPaths       []staticPathItem // 静态文件目录映射(按照优先级进行排序)
    59  	FileServerEnabled bool             // 是否允许静态文件服务(通过静态文件服务方法调用自动识别)
    60  
    61  	// COOKIE
    62  	CookieMaxAge int    // Cookie有效期
    63  	CookiePath   string // Cookie有效Path(注意同时也会影响SessionID)
    64  	CookieDomain string // Cookie有效Domain(注意同时也会影响SessionID)
    65  
    66  	// SESSION
    67  	SessionMaxAge int    // Session有效期
    68  	SessionIdName string // SessionId名称
    69  
    70  	// IP访问控制
    71  	DenyIps  []string // 不允许访问的ip列表,支持ip前缀过滤,如: 10 将不允许10开头的ip访问
    72  	AllowIps []string // 仅允许访问的ip列表,支持ip前缀过滤,如: 10 将仅允许10开头的ip访问
    73  
    74  	// 路由访问控制
    75  	DenyRoutes []string          // 不允许访问的路由规则列表
    76  	Rewrites   map[string]string // URI Rewrite重写配置
    77  
    78  	// 日志配置
    79  	LogPath          string     // 存放日志的目录路径(默认为空,表示不写文件)
    80  	LogHandler       LogHandler // 自定义日志处理回调方法(默认为空)
    81  	LogStdout        bool       // 是否打印日志到终端(默认开启)
    82  	ErrorLogEnabled  bool       // 是否开启error log(默认开启)
    83  	AccessLogEnabled bool       // 是否开启access log(默认关闭)
    84  
    85  	// 其他设置
    86  	NameToUriType     int      // 服务注册时对象和方法名称转换为URI时的规则
    87  	GzipContentTypes  []string // 允许进行gzip压缩的文件类型
    88  	DumpRouteMap      bool     // 是否在程序启动时默认打印路由表信息
    89  	RouterCacheExpire int      // 路由检索缓存过期时间(秒)
    90  }
    91  
    92  // 默认HTTP Server配置
    93  var defaultServerConfig = ServerConfig{
    94  	Addr:           "",
    95  	HTTPSAddr:      "",
    96  	Handler:        nil,
    97  	ReadTimeout:    60 * time.Second,
    98  	WriteTimeout:   60 * time.Second,
    99  	IdleTimeout:    60 * time.Second,
   100  	MaxHeaderBytes: 1024,
   101  	KeepAlive:      true,
   102  
   103  	IndexFiles:        []string{"index.html", "index.htm"},
   104  	IndexFolder:       false,
   105  	ServerAgent:       "gf",
   106  	ServerRoot:        "",
   107  	StaticPaths:       make([]staticPathItem, 0),
   108  	FileServerEnabled: false,
   109  
   110  	CookieMaxAge: gDEFAULT_COOKIE_MAX_AGE,
   111  	CookiePath:   gDEFAULT_COOKIE_PATH,
   112  	CookieDomain: "",
   113  
   114  	SessionMaxAge: gDEFAULT_SESSION_MAX_AGE,
   115  	SessionIdName: gDEFAULT_SESSION_ID_NAME,
   116  
   117  	LogStdout:         true,
   118  	ErrorLogEnabled:   true,
   119  	AccessLogEnabled:  false,
   120  	GzipContentTypes:  defaultGzipContentTypes,
   121  	DumpRouteMap:      true,
   122  	RouterCacheExpire: 60,
   123  	Rewrites:          make(map[string]string),
   124  }
   125  
   126  // 获取默认的http server设置
   127  func Config() ServerConfig {
   128  	return defaultServerConfig
   129  }
   130  
   131  // http server setting设置
   132  // 注意使用该方法进行http server配置时,需要配置所有的配置项,否则没有配置的属性将会默认变量为空
   133  func (s *Server) SetConfig(c ServerConfig) {
   134  	if s.Status() == SERVER_STATUS_RUNNING {
   135  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   136  		return
   137  	}
   138  	if c.Handler == nil {
   139  		c.Handler = http.HandlerFunc(s.defaultHttpHandle)
   140  	}
   141  	s.config = c
   142  
   143  	if c.LogPath != "" {
   144  		s.logger.SetPath(c.LogPath)
   145  	}
   146  }
   147  
   148  // 设置http server参数 - Addr
   149  func (s *Server) SetAddr(addr string) {
   150  	if s.Status() == SERVER_STATUS_RUNNING {
   151  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   152  		return
   153  	}
   154  	s.config.Addr = addr
   155  }
   156  
   157  // 设置http server参数 - Port
   158  func (s *Server) SetPort(port ...int) {
   159  	if s.Status() == SERVER_STATUS_RUNNING {
   160  		glog.Error("config cannot be changed while running")
   161  	}
   162  	if len(port) > 0 {
   163  		s.config.Addr = ""
   164  		for _, v := range port {
   165  			if len(s.config.Addr) > 0 {
   166  				s.config.Addr += ","
   167  			}
   168  			s.config.Addr += ":" + strconv.Itoa(v)
   169  		}
   170  	}
   171  }
   172  
   173  // 设置http server参数 - HTTPS Addr
   174  func (s *Server) SetHTTPSAddr(addr string) {
   175  	if s.Status() == SERVER_STATUS_RUNNING {
   176  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   177  		return
   178  	}
   179  	s.config.HTTPSAddr = addr
   180  }
   181  
   182  // 设置http server参数 - HTTPS Port
   183  func (s *Server) SetHTTPSPort(port ...int) {
   184  	if s.Status() == SERVER_STATUS_RUNNING {
   185  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   186  		return
   187  	}
   188  	if len(port) > 0 {
   189  		s.config.HTTPSAddr = ""
   190  		for _, v := range port {
   191  			if len(s.config.HTTPSAddr) > 0 {
   192  				s.config.HTTPSAddr += ","
   193  			}
   194  			s.config.HTTPSAddr += ":" + strconv.Itoa(v)
   195  		}
   196  	}
   197  }
   198  
   199  // 开启HTTPS支持,但是必须提供Cert和Key文件,tlsConfig为可选项
   200  func (s *Server) EnableHTTPS(certFile, keyFile string, tlsConfig ...tls.Config) {
   201  	if s.Status() == SERVER_STATUS_RUNNING {
   202  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   203  		return
   204  	}
   205  	certFileRealPath := gfile.RealPath(certFile)
   206  	if certFileRealPath == "" {
   207  		certFileRealPath = gfile.RealPath(gfile.Pwd() + gfile.Separator + certFile)
   208  		if certFileRealPath == "" {
   209  			certFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + certFile)
   210  		}
   211  	}
   212  	if certFileRealPath == "" {
   213  		glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: certFile "%s" does not exist`, certFile))
   214  	}
   215  	keyFileRealPath := gfile.RealPath(keyFile)
   216  	if keyFileRealPath == "" {
   217  		keyFileRealPath = gfile.RealPath(gfile.Pwd() + gfile.Separator + keyFile)
   218  		if keyFileRealPath == "" {
   219  			keyFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + keyFile)
   220  		}
   221  	}
   222  	if keyFileRealPath == "" {
   223  		glog.Fatal(fmt.Sprintf(`[ghttp] EnableHTTPS failed: keyFile "%s" does not exist`, keyFile))
   224  	}
   225  	s.config.HTTPSCertPath = certFileRealPath
   226  	s.config.HTTPSKeyPath = keyFileRealPath
   227  	if len(tlsConfig) > 0 {
   228  		s.config.TLSConfig = tlsConfig[0]
   229  	}
   230  }
   231  
   232  // 设置TLS配置对象
   233  func (s *Server) SetTLSConfig(tlsConfig tls.Config) {
   234  	if s.Status() == SERVER_STATUS_RUNNING {
   235  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   236  		return
   237  	}
   238  	s.config.TLSConfig = tlsConfig
   239  }
   240  
   241  // 设置http server参数 - ReadTimeout
   242  func (s *Server) SetReadTimeout(t time.Duration) {
   243  	if s.Status() == SERVER_STATUS_RUNNING {
   244  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   245  		return
   246  	}
   247  	s.config.ReadTimeout = t
   248  }
   249  
   250  // 设置http server参数 - WriteTimeout
   251  func (s *Server) SetWriteTimeout(t time.Duration) {
   252  	if s.Status() == SERVER_STATUS_RUNNING {
   253  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   254  		return
   255  	}
   256  	s.config.WriteTimeout = t
   257  }
   258  
   259  // 设置http server参数 - IdleTimeout
   260  func (s *Server) SetIdleTimeout(t time.Duration) {
   261  	if s.Status() == SERVER_STATUS_RUNNING {
   262  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   263  		return
   264  	}
   265  	s.config.IdleTimeout = t
   266  }
   267  
   268  // 设置http server参数 - MaxHeaderBytes
   269  func (s *Server) SetMaxHeaderBytes(b int) {
   270  	if s.Status() == SERVER_STATUS_RUNNING {
   271  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   272  		return
   273  	}
   274  	s.config.MaxHeaderBytes = b
   275  
   276  }
   277  
   278  // 设置http server参数 - ServerAgent
   279  func (s *Server) SetServerAgent(agent string) {
   280  	if s.Status() == SERVER_STATUS_RUNNING {
   281  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   282  		return
   283  	}
   284  	s.config.ServerAgent = agent
   285  }
   286  
   287  func (s *Server) SetGzipContentTypes(types []string) {
   288  	if s.Status() == SERVER_STATUS_RUNNING {
   289  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   290  		return
   291  	}
   292  	s.config.GzipContentTypes = types
   293  }
   294  
   295  // 服务注册时对象和方法名称转换为URI时的规则
   296  func (s *Server) SetNameToUriType(t int) {
   297  	if s.Status() == SERVER_STATUS_RUNNING {
   298  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   299  		return
   300  	}
   301  	s.config.NameToUriType = t
   302  }
   303  
   304  // 是否在程序启动时打印路由表信息
   305  func (s *Server) SetDumpRouteMap(enabled bool) {
   306  	if s.Status() == SERVER_STATUS_RUNNING {
   307  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   308  		return
   309  	}
   310  	s.config.DumpRouteMap = enabled
   311  }
   312  
   313  // 设置路由缓存过期时间(秒)
   314  func (s *Server) SetRouterCacheExpire(expire int) {
   315  	if s.Status() == SERVER_STATUS_RUNNING {
   316  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   317  		return
   318  	}
   319  	s.config.RouterCacheExpire = expire
   320  }
   321  
   322  // 设置KeepAlive
   323  func (s *Server) SetKeepAlive(enabled bool) {
   324  	if s.Status() == SERVER_STATUS_RUNNING {
   325  		glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
   326  		return
   327  	}
   328  	s.config.KeepAlive = enabled
   329  }
   330  
   331  // 获取WebServer名称
   332  func (s *Server) GetName() string {
   333  	return s.name
   334  }