add TLSConfig support for ghttp.Server

This commit is contained in:
John
2019-03-19 17:48:37 +08:00
parent 4e3d735b90
commit 80e0eae6b0
7 changed files with 57 additions and 18 deletions

View File

@ -79,6 +79,11 @@ func NewUnsafe(value...interface{}) *Json {
return New(nil, true)
}
// 识别当前给定内容是否为JSON格式
func Valid (v interface{}) bool {
return json.Valid(gconv.Bytes(v))
}
// 编码go变量为json字符串并返回json字符串指针
func Encode (v interface{}) ([]byte, error) {
return json.Marshal(v)

View File

@ -9,6 +9,7 @@
package ghttp
import (
"encoding/json"
"github.com/gogf/gf/g/text/gregex"
"time"
"bytes"
@ -117,6 +118,7 @@ func (c *Client) Post(url string, data...string) (*ClientResponse, error) {
}
req := (*http.Request)(nil)
if strings.Contains(param, "@file:") {
// 文件上传
buffer := new(bytes.Buffer)
writer := multipart.NewWriter(buffer)
for _, item := range strings.Split(param, "&") {
@ -150,11 +152,17 @@ func (c *Client) Post(url string, data...string) (*ClientResponse, error) {
req.Header.Set("Content-Type", writer.FormDataContentType())
}
} else {
if r, err := http.NewRequest("POST", url, bytes.NewReader([]byte(param))); err != nil {
// 识别提交数据格式
paramBytes := []byte(param)
if r, err := http.NewRequest("POST", url, bytes.NewReader(paramBytes)); err != nil {
return nil, err
} else {
req = r
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if json.Valid(paramBytes) {
req.Header.Set("Content-Type", "application/json")
} else {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
}
}
}
// 自定义header

View File

@ -398,7 +398,8 @@ func Wait() {
// 开启底层Web Server执行
func (s *Server) startServer(fdMap listenerFdMap) {
var httpsEnabled bool
if len(s.config.HTTPSCertPath) > 0 && len(s.config.HTTPSKeyPath) > 0 {
// 判断是否启用HTTPS
if len(s.config.TLSConfig.Certificates) > 0 || (len(s.config.HTTPSCertPath) > 0 && len(s.config.HTTPSKeyPath) > 0) {
// ================
// HTTPS
// ================
@ -479,7 +480,7 @@ func (s *Server) startServer(fdMap listenerFdMap) {
s.serverCount.Add(1)
err := (error)(nil)
if server.isHttps {
err = server.ListenAndServeTLS(s.config.HTTPSCertPath, s.config.HTTPSKeyPath)
err = server.ListenAndServeTLS(s.config.HTTPSCertPath, s.config.HTTPSKeyPath, &s.config.TLSConfig)
} else {
err = server.ListenAndServe()
}

View File

@ -7,6 +7,7 @@
package ghttp
import (
"crypto/tls"
"fmt"
"github.com/gogf/gf/g/os/gfile"
"github.com/gogf/gf/g/os/glog"
@ -44,6 +45,7 @@ type ServerConfig struct {
WriteTimeout time.Duration // 写入超时
IdleTimeout time.Duration // 等待超时
MaxHeaderBytes int // 最大的header长度
TLSConfig tls.Config
// 静态文件配置
IndexFiles []string // 默认访问的文件列表
@ -191,28 +193,46 @@ func (s *Server)SetHTTPSPort(port...int) {
}
}
// 开启HTTPS支持但是必须提供Cert和Key文件
func (s *Server)EnableHTTPS(certFile, keyFile string) {
// 开启HTTPS支持但是必须提供Cert和Key文件tlsConfig为可选项
func (s *Server)EnableHTTPS(certFile, keyFile string, tlsConfig...tls.Config) {
if s.Status() == SERVER_STATUS_RUNNING {
glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
return
}
certFileRealPath := gfile.RealPath(certFile)
if certFileRealPath == "" {
certFileRealPath = gfile.RealPath(gfile.MainPkgPath() + gfile.Separator + 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.MainPkgPath() + gfile.Separator + 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]
}
}
// 设置TLS配置对象
func (s *Server)SetTLSConfig(tlsConfig tls.Config) {
if s.Status() == SERVER_STATUS_RUNNING {
glog.Error(gCHANGE_CONFIG_WHILE_RUNNING_ERROR)
return
}
s.config.TLSConfig = tlsConfig
}
// 设置http server参数 - ReadTimeout

View File

@ -84,18 +84,22 @@ func (s *gracefulServer) setFd(fd int) {
}
// 执行HTTPS监听
func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string) error {
func (s *gracefulServer) ListenAndServeTLS(certFile, keyFile string, tlsConfig...*tls.Config) error {
addr := s.httpServer.Addr
config := &tls.Config{}
if s.httpServer.TLSConfig != nil {
config := (*tls.Config)(nil)
if len(tlsConfig) > 0 {
config = tlsConfig[0]
} else if s.httpServer.TLSConfig != nil {
*config = *s.httpServer.TLSConfig
}
if config.NextProtos == nil {
config.NextProtos = []string{"http/1.1"}
}
err := error(nil)
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
if len(config.Certificates) == 0 {
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile)
}
if err != nil {
return errors.New(fmt.Sprintf(`open cert file "%s","%s" failed: %s`, certFile, keyFile, err.Error()))
}

View File

@ -79,10 +79,11 @@ func Bytes(i interface{}) []byte {
if i == nil {
return nil
}
if r, ok := i.([]byte); ok {
return r
} else {
return gbinary.Encode(i)
switch value := i.(type) {
case string: return []byte(value)
case []byte: return value
default:
return gbinary.Encode(i)
}
}

View File

@ -9,7 +9,7 @@ func main() {
s.BindHandler("/", func(r *ghttp.Request){
r.Response.Writeln("来自于HTTPS的哈喽世界")
})
s.EnableHTTPS("/home/john/temp/server.crt", "/home/john/temp/server.key")
s.EnableHTTPS("./server.crt", "./server.key")
s.SetPort(8199)
s.Run()
}