change tls and http2 library

gnutls_nghttp2
fangdingjun 6 years ago
parent 15d3e5d050
commit d83d751789

@ -2,13 +2,14 @@ package main
import ( import (
"fmt" "fmt"
auth "github.com/fangdingjun/go-http-auth"
"io" "io"
"log" "log"
"net" "net"
"net/http" "net/http"
"strings" "strings"
"time" "time"
auth "github.com/fangdingjun/go-http-auth"
) )
// handler process the proxy request first(if enabled) // handler process the proxy request first(if enabled)
@ -121,21 +122,11 @@ func (h *handler) handleHTTP(w http.ResponseWriter, r *http.Request) {
io.Copy(w, resp.Body) io.Copy(w, resp.Body)
} }
type flushWriter struct {
w io.Writer
}
func (fw flushWriter) Write(buf []byte) (int, error) {
n, err := fw.w.Write(buf)
fw.w.(http.Flusher).Flush()
return n, err
}
func (h *handler) handleCONNECT(w http.ResponseWriter, r *http.Request) { func (h *handler) handleCONNECT(w http.ResponseWriter, r *http.Request) {
host := r.RequestURI host := r.RequestURI
if r.ProtoMajor == 2 { if r.ProtoMajor == 2 {
host = r.URL.Host host = r.Host
} }
if !strings.Contains(host, ":") { if !strings.Contains(host, ":") {
@ -176,7 +167,7 @@ func (h *handler) handleCONNECT(w http.ResponseWriter, r *http.Request) {
defer conn.Close() defer conn.Close()
w.WriteHeader(http.StatusOK) w.WriteHeader(http.StatusOK)
w.(http.Flusher).Flush() //w.(http.Flusher).Flush()
ch := make(chan int, 2) ch := make(chan int, 2)
go func() { go func() {
@ -185,7 +176,7 @@ func (h *handler) handleCONNECT(w http.ResponseWriter, r *http.Request) {
}() }()
go func() { go func() {
io.Copy(flushWriter{w}, conn) io.Copy(w, conn)
ch <- 1 ch <- 1
}() }()

@ -1,12 +1,7 @@
package main package main
import ( import (
"crypto/tls"
"fmt" "fmt"
auth "github.com/fangdingjun/go-http-auth"
"github.com/fangdingjun/gofast"
loghandler "github.com/gorilla/handlers"
"github.com/gorilla/mux"
"io" "io"
"log" "log"
"net" "net"
@ -15,9 +10,15 @@ import (
"net/url" "net/url"
"os" "os"
"regexp" "regexp"
"sync"
//"path/filepath"
"strings" "strings"
"sync"
"github.com/fangdingjun/gnutls"
auth "github.com/fangdingjun/go-http-auth"
"github.com/fangdingjun/gofast"
nghttp2 "github.com/fangdingjun/nghttp2-go"
loghandler "github.com/gorilla/handlers"
"github.com/gorilla/mux"
) )
type logwriter struct { type logwriter struct {
@ -49,7 +50,7 @@ func initRouters(cfg conf) {
for _, l := range cfg { for _, l := range cfg {
router := mux.NewRouter() router := mux.NewRouter()
domains := []string{} domains := []string{}
certs := []tls.Certificate{} certs := []*gnutls.Certificate{}
// initial virtual host // initial virtual host
for _, h := range l.Vhost { for _, h := range l.Vhost {
@ -59,7 +60,7 @@ func initRouters(cfg conf) {
} }
domains = append(domains, h2) domains = append(domains, h2)
if h.Cert != "" && h.Key != "" { if h.Cert != "" && h.Key != "" {
if cert, err := tls.LoadX509KeyPair(h.Cert, h.Key); err == nil { if cert, err := gnutls.LoadX509KeyPair(h.Cert, h.Key); err == nil {
certs = append(certs, cert) certs = append(certs, cert)
} else { } else {
log.Fatal(err) log.Fatal(err)
@ -128,21 +129,28 @@ func initRouters(cfg conf) {
} }
if len(certs) > 0 { if len(certs) > 0 {
tlsconfig := &tls.Config{ tlsconfig := &gnutls.Config{
Certificates: certs, Certificates: certs,
NextProtos: []string{"h2", "http/1.1"},
} }
listener, err := gnutls.Listen("tcp", addr, tlsconfig)
tlsconfig.BuildNameToCertificate() if err != nil {
log.Fatal(err)
srv := http.Server{
Addr: addr,
TLSConfig: tlsconfig,
Handler: loghandler.CombinedLoggingHandler(w, hdlr),
} }
handler := loghandler.CombinedLoggingHandler(w, hdlr)
log.Printf("listen https on %s", addr) log.Printf("listen https on %s", addr)
if err := srv.ListenAndServeTLS("", ""); err != nil { go func() {
log.Fatal(err) defer listener.Close()
for {
conn, err := listener.Accept()
if err != nil {
log.Println(err)
break
} }
go handleHttpClient(conn, handler)
}
}()
} else { } else {
log.Printf("listen http on %s", addr) log.Printf("listen http on %s", addr)
@ -260,3 +268,28 @@ func (m myURLMatch) match(r *http.Request, route *mux.RouteMatch) bool {
ret := m.re.MatchString(r.URL.Path) ret := m.re.MatchString(r.URL.Path)
return ret return ret
} }
func handleHttpClient(c net.Conn, handler http.Handler) {
tlsconn := c.(*gnutls.Conn)
if err := tlsconn.Handshake(); err != nil {
log.Println(err)
return
}
state := tlsconn.ConnectionState()
if state.NegotiatedProtocol == "h2" {
h2conn, err := nghttp2.NewServerConn(tlsconn, handler)
if err != nil {
log.Println(err)
}
h2conn.Run()
return
}
defer c.Close()
resp := &http.Response{
StatusCode: http.StatusHTTPVersionNotSupported,
Status: http.StatusText(http.StatusHTTPVersionNotSupported),
ProtoMajor: 1,
ProtoMinor: 1,
}
resp.Write(tlsconn)
}

Loading…
Cancel
Save