mirror of
https://github.com/kataras/iris.git
synced 2025-01-23 02:31:04 +01:00
Add HTTP/2 Example and Websocket wss:// too in the same time :)
Former-commit-id: fd4c12043d6ed739770236e014ccd2f0f4f5a84c
This commit is contained in:
parent
5055546a38
commit
48b470f5da
|
@ -11,7 +11,8 @@ Users already notified for some breaking-changes, this section will help you
|
|||
to adapt the new changes to your application, it contains an overview of the new features too.
|
||||
|
||||
- Shutdown with `app.Shutdown(context.Context) error`, no need for any third-parties, with `EventPolicy.Interrupted` and Go's 1.8 Gracefully Shutdown feature you're ready to go!
|
||||
- HTTP/2 Go 1.8 `context.Push(target string, opts *http.PushOptions) error` is supported
|
||||
- HTTP/2 Go 1.8 `context.Push(target string, opts *http.PushOptions) error` is supported, example can be found [here](https://github.com/kataras/iris.v6/blob/master/adaptors/websocket/_examples/webocket_secure/main.go)
|
||||
|
||||
- Router (two lines to add, new features)
|
||||
- Template engines (two lines to add, same features as before, except their easier configuration)
|
||||
- Basic middleware, that have been written by me, are transfared to the main repository[/middleware](https://github.com/kataras/iris/tree/master/middleware) with a lot of improvements to the `recover middleware` (see the next)
|
||||
|
|
197
adaptors/websocket/_examples/websocket_secure/main.go
Normal file
197
adaptors/websocket/_examples/websocket_secure/main.go
Normal file
|
@ -0,0 +1,197 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt" // optional
|
||||
"io/ioutil" // optional
|
||||
"os" // optional
|
||||
"time" // optional
|
||||
|
||||
"gopkg.in/kataras/iris.v6"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/httprouter"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/view"
|
||||
"gopkg.in/kataras/iris.v6/adaptors/websocket"
|
||||
)
|
||||
|
||||
type clientPage struct {
|
||||
Title string
|
||||
Host string
|
||||
}
|
||||
|
||||
func main() {
|
||||
app := iris.New()
|
||||
app.Adapt(iris.DevLogger()) // enable all (error) logs
|
||||
app.Adapt(httprouter.New()) // select the httprouter as the servemux
|
||||
app.Adapt(view.HTML("./templates", ".html")) // select the html engine to serve templates
|
||||
|
||||
ws := websocket.New(websocket.Config{
|
||||
// the path which the websocket client should listen/registed to,
|
||||
Endpoint: "/my_endpoint",
|
||||
// the client-side javascript static file path
|
||||
// which will be served by Iris.
|
||||
// default is /iris-ws.js
|
||||
// if you change that you have to change the bottom of templates/client.html
|
||||
// script tag:
|
||||
ClientSourcePath: "/iris-ws.js",
|
||||
//
|
||||
// Set the timeouts, 0 means no timeout
|
||||
// websocket has more configuration, go to ../../config.go for more:
|
||||
// WriteTimeout: 0,
|
||||
// ReadTimeout: 0,
|
||||
// by-default all origins are accepted, you can change this behavior by setting:
|
||||
// CheckOrigin: (r *http.Request ) bool {},
|
||||
//
|
||||
//
|
||||
// IDGenerator used to create (and later on, set)
|
||||
// an ID for each incoming websocket connections (clients).
|
||||
// The request is an argument which you can use to generate the ID (from headers for example).
|
||||
// If empty then the ID is generated by DefaultIDGenerator: randomString(64):
|
||||
// IDGenerator func(ctx *iris.Context) string {},
|
||||
})
|
||||
|
||||
app.Adapt(ws) // adapt the websocket server, you can adapt more than one with different Endpoint
|
||||
|
||||
app.StaticWeb("/js", "./static/js") // static route to serve our javascript files
|
||||
|
||||
app.Get("/", func(ctx *iris.Context) {
|
||||
// send our custom javascript source file before client really asks for that
|
||||
// using the new go v1.8's HTTP/2 Push.
|
||||
// Note that you have to listen using ListenTLS/ListenLETSENCRYPT in order this to work.
|
||||
if err := ctx.ResponseWriter.Push("/js/chat.js", nil); err != nil {
|
||||
app.Log(iris.DevMode, err.Error())
|
||||
}
|
||||
ctx.Render("client.html", clientPage{"Client Page", ctx.Host()})
|
||||
})
|
||||
|
||||
var myChatRoom = "room1"
|
||||
|
||||
ws.OnConnection(func(c websocket.Connection) {
|
||||
// Context returns the (upgraded) *iris.Context of this connection
|
||||
// avoid using it, you normally don't need it,
|
||||
// websocket has everything you need to authenticate the user BUT if it's necessary
|
||||
// then you use it to receive user information, for example: from headers.
|
||||
|
||||
// ctx := c.Context()
|
||||
|
||||
// join to a room (optional)
|
||||
c.Join(myChatRoom)
|
||||
|
||||
c.On("chat", func(message string) {
|
||||
if message == "leave" {
|
||||
c.Leave(myChatRoom)
|
||||
c.To(myChatRoom).Emit("chat", "Client with ID: "+c.ID()+" left from the room and cannot send or receive message to/from this room.")
|
||||
c.Emit("chat", "You have left from the room: "+myChatRoom+" you cannot send or receive any messages from others inside that room.")
|
||||
return
|
||||
}
|
||||
// to all except this connection ->
|
||||
// c.To(websocket.Broadcast).Emit("chat", "Message from: "+c.ID()+"-> "+message)
|
||||
// to all connected clients: c.To(websocket.All)
|
||||
|
||||
// to the client itself ->
|
||||
//c.Emit("chat", "Message from myself: "+message)
|
||||
|
||||
//send the message to the whole room,
|
||||
//all connections are inside this room will receive this message
|
||||
c.To(myChatRoom).Emit("chat", "From: "+c.ID()+": "+message)
|
||||
})
|
||||
|
||||
// or create a new leave event
|
||||
// c.On("leave", func() {
|
||||
// c.Leave(myChatRoom)
|
||||
// })
|
||||
|
||||
c.OnDisconnect(func() {
|
||||
fmt.Printf("Connection with ID: %s has been disconnected!\n", c.ID())
|
||||
})
|
||||
})
|
||||
|
||||
listenTLS(app)
|
||||
|
||||
}
|
||||
|
||||
// a test listenTLS for our localhost
|
||||
func listenTLS(app *iris.Framework) {
|
||||
|
||||
const (
|
||||
testTLSCert = `-----BEGIN CERTIFICATE-----
|
||||
MIIDBTCCAe2gAwIBAgIJAOYzROngkH6NMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
|
||||
BAMMDmxvY2FsaG9zdDo4MDgwMB4XDTE3MDIxNzAzNDM1NFoXDTI3MDIxNTAzNDM1
|
||||
NFowGTEXMBUGA1UEAwwObG9jYWxob3N0OjgwODAwggEiMA0GCSqGSIb3DQEBAQUA
|
||||
A4IBDwAwggEKAoIBAQCfsiVHO14FpKsi0pvBv68oApQm2MO+dCvq87sDU4E0QJhG
|
||||
KV1RCUmQVypChEqdLlUQsopcXSyKwbWoyg1/KNHYO3DHMfePb4bC1UD2HENq7Ph2
|
||||
8QJTEi/CJvUB9hqke/YCoWYdjFiI3h3Hw8q5whGO5XR3R23z69vr5XxoNlcF2R+O
|
||||
TdkzArd0CWTZS27vbgdnyi9v3Waydh/rl+QRtPUgEoCEqOOkMSMldXO6Z9GlUk9b
|
||||
FQHwIuEnlSoVFB5ot5cqebEjJnWMLLP83KOCQekJeHZOyjeTe8W0Fy1DGu5fvFNh
|
||||
xde9e/7XlFE//00vT7nBmJAUV/2CXC8U5lsjLEqdAgMBAAGjUDBOMB0GA1UdDgQW
|
||||
BBQOfENuLn/t0Z4ZY1+RPWaz7RBH+TAfBgNVHSMEGDAWgBQOfENuLn/t0Z4ZY1+R
|
||||
PWaz7RBH+TAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQBG7AEEuIq6
|
||||
rWCE5I2t4IXz0jN7MilqEhUWDbUajl1paYf6Ikx5QhMsFx21p6WEWYIYcnWAKZe2
|
||||
chAgnnGojuxdx0qjiaH4N4xWGHsWhaesnIF1xJepLlX3kJZQURvRxM4wlljlQPIb
|
||||
9tqzKP131K1HDqplAtp7nWQ72m3J0ZfzH0mYIUxuaS/uQIVtgKqdilwy/VE5dRZ9
|
||||
QFIb4G9TnNThXMqgTLjfNr33jVbTuv6fzKHYNbCkP3L10ydEs/ddlREmtsn9nE8Q
|
||||
XCTIYXzA2kr5kWk7d3LkUiSvu3g2S1Ol1YaIKaOQyRveseCGwR4xohLT+dPUW9dL
|
||||
3hDVLlwE3mB3
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
`
|
||||
testTLSKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEogIBAAKCAQEAn7IlRzteBaSrItKbwb+vKAKUJtjDvnQr6vO7A1OBNECYRild
|
||||
UQlJkFcqQoRKnS5VELKKXF0sisG1qMoNfyjR2DtwxzH3j2+GwtVA9hxDauz4dvEC
|
||||
UxIvwib1AfYapHv2AqFmHYxYiN4dx8PKucIRjuV0d0dt8+vb6+V8aDZXBdkfjk3Z
|
||||
MwK3dAlk2Utu724HZ8ovb91msnYf65fkEbT1IBKAhKjjpDEjJXVzumfRpVJPWxUB
|
||||
8CLhJ5UqFRQeaLeXKnmxIyZ1jCyz/NyjgkHpCXh2Tso3k3vFtBctQxruX7xTYcXX
|
||||
vXv+15RRP/9NL0+5wZiQFFf9glwvFOZbIyxKnQIDAQABAoIBAEzBx4ExW8PCni8i
|
||||
o5LAm2PTuXniflMwa1uGwsCahmOjGI3AnAWzPRSPkNRf2a0q8+AOsMosTphy+umi
|
||||
FFKmQBZ6m35i2earaE6FSbABbbYbKGGi/ccH2sSrDOBgdfXRTzF8eiSBrJw8hnvZ
|
||||
87rNOLtCNnSOdJ7lItODfgRo+fLo4uQenJ8VONYwtwm1ejn8qLXq8O5zF66IYUD6
|
||||
gAzqOiAWumgZL0tEmndeQ+noe4STpJZlOjiCsA12NiJaKDDeDIn5A/pXce+bYNfJ
|
||||
k4yoroyq/JXBkhyuZDvX9vYp5AA+Q68h8/KmsKkifUgSGSHun5/80lYyT/f60TLX
|
||||
PxT9GYECgYEA0s8qck7L29nBBTQ6IPF3GHGmqiRdfH+qhP/Jn4NtoW3XuVe4A15i
|
||||
REq1L8WAiOUIBnBaD8HzbeioqJJYx1pu7x9h/GCNDhdBfwhTjnBe+JjfLqvJKnc0
|
||||
HUT5wj4DVqattxKzUW8kTRBSWtVremzeffDo+EL6dnR7Bc02Ibs4WpUCgYEAwe34
|
||||
Uqhie+/EFr4HjYRUNZSNgYNAJkKHVxk4qGzG5VhvjPafnHUbo+Kk/0QW7eIB+kvR
|
||||
FDO8oKh9wTBrWZEcLJP4jDIKh4y8hZTo9B8EjxFONXVxZlOSYuGjheL8AiLzE7L9
|
||||
C1spaKMM/MyxAXDRHpG/NeEgXM7Kn6kUGwJdNekCgYAshLNiEGHcu8+XWcAs1NFh
|
||||
yB56L9PORuerzpi1pvuv65JzAaNKktQNt/krbXoHbtaTBYb/bOYLf+aeMsmsz9w9
|
||||
g1MeCQXAxAiA2zFKE1D7Ds2S/ZQt8559z+MusgnicrCcyMY1nFL+M0QxCoD4CaWy
|
||||
0v1f8EUUXuTcBMo5tV/hQQKBgDoBBW8jsiFDu7DZscSgOde00QZVzZAkAfsJLisi
|
||||
LfNXGjZdZawUUuoX1iYLpZgNK25D0wtp1hdvjf2Ej/dAMd8bexHjvcaBT7ncqjiq
|
||||
NmDcWjofIIXspTIyLwjStXGmJnJT7N/CqoYDjtTmHGND7Shpi3mAFn/r0isjFUJm
|
||||
2J5RAoGALuGXxzmSRWmkIp11F/Qr3PBFWBWkrRWaH2TRLMhrU/wO8kCsSyo4PmAZ
|
||||
ltOfD7InpDiCu43hcDPQ/29FUbDnmAhvMnmIQuHXGgPF/LhqEhbKPA/o/eZdQVCK
|
||||
QG+tmveBBIYMed5YbWstZu/95lIHF+u8Hl+Z6xgveozfE5yqiUA=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
|
||||
`
|
||||
)
|
||||
|
||||
// create the key and cert files on the fly, and delete them when this test finished
|
||||
certFile, ferr := ioutil.TempFile("", "cert")
|
||||
|
||||
if ferr != nil {
|
||||
panic(ferr)
|
||||
}
|
||||
|
||||
keyFile, ferr := ioutil.TempFile("", "key")
|
||||
if ferr != nil {
|
||||
panic(ferr)
|
||||
}
|
||||
|
||||
certFile.WriteString(testTLSCert)
|
||||
keyFile.WriteString(testTLSKey)
|
||||
|
||||
// add an event when control+C pressed, to remove the temp cert and key files.
|
||||
app.Adapt(iris.EventPolicy{
|
||||
Interrupted: func(*iris.Framework) {
|
||||
certFile.Close()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
os.Remove(certFile.Name())
|
||||
|
||||
keyFile.Close()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
os.Remove(keyFile.Name())
|
||||
},
|
||||
})
|
||||
|
||||
// https://localhost
|
||||
app.ListenTLS("localhost:443", certFile.Name(), keyFile.Name())
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
var messageTxt;
|
||||
var messages;
|
||||
|
||||
$(function () {
|
||||
|
||||
messageTxt = $("#messageTxt");
|
||||
messages = $("#messages");
|
||||
|
||||
/* secure wss because we ListenTLS */
|
||||
w = new Ws("wss://" + HOST + "/my_endpoint");
|
||||
w.OnConnect(function () {
|
||||
console.log("Websocket connection established");
|
||||
});
|
||||
|
||||
w.OnDisconnect(function () {
|
||||
appendMessage($("<div><center><h3>Disconnected</h3></center></div>"));
|
||||
});
|
||||
|
||||
w.On("chat", function (message) {
|
||||
appendMessage($("<div>" + message + "</div>"));
|
||||
});
|
||||
|
||||
$("#sendBtn").click(function () {
|
||||
w.Emit("chat", messageTxt.val().toString());
|
||||
messageTxt.val("");
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
|
||||
function appendMessage(messageDiv) {
|
||||
var theDiv = messages[0];
|
||||
var doScroll = theDiv.scrollTop == theDiv.scrollHeight - theDiv.clientHeight;
|
||||
messageDiv.appendTo(messages);
|
||||
if (doScroll) {
|
||||
theDiv.scrollTop = theDiv.scrollHeight - theDiv.clientHeight;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>{{ .Title}}</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="messages"
|
||||
style="border-width: 1px; border-style: solid; height: 400px; width: 375px;">
|
||||
|
||||
</div>
|
||||
<input type="text" id="messageTxt" />
|
||||
<button type="button" id="sendBtn">Send</button>
|
||||
<script type="text/javascript">
|
||||
var HOST = {{.Host}}
|
||||
</script>
|
||||
<script src="/js/vendor/jquery-2.2.3.min.js"></script>
|
||||
<!-- This is auto-serving by the Iris, you don't need to have this file in your disk-->
|
||||
<script src="/iris-ws.js"></script>
|
||||
<!-- -->
|
||||
<script src="/js/chat.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
123
iris.go
123
iris.go
|
@ -100,8 +100,6 @@ type Framework struct {
|
|||
// These are setted by user's call to .Adapt
|
||||
policies Policies
|
||||
|
||||
ln net.Listener // setted on Listten/Serve funcions, available after 'Boot'
|
||||
|
||||
// TLSNextProto optionally specifies a function to take over
|
||||
// ownership of the provided TLS connection when an NPN/ALPN
|
||||
// protocol upgrade has occurred. The map key is the protocol
|
||||
|
@ -210,19 +208,15 @@ func New(setters ...OptionSetter) *Framework {
|
|||
s.Adapt(EventPolicy{Boot: func(s *Framework) {
|
||||
// set the host and scheme
|
||||
if s.Config.VHost == "" { // if not setted by Listen functions
|
||||
if s.ln != nil { // but user called .Serve
|
||||
// then take the listener's addr
|
||||
s.Config.VHost = s.ln.Addr().String()
|
||||
} else {
|
||||
// if no .Serve or .Listen called, then the user should set the VHost manually,
|
||||
// however set it to a default value here for any case
|
||||
s.Config.VHost = DefaultServerAddr
|
||||
}
|
||||
s.Config.VHost = DefaultServerAddr
|
||||
}
|
||||
// if user didn't specified a scheme then get it from the VHost, which is already setted at before statements
|
||||
// if user didn't specified a scheme then get it from the VHost,
|
||||
// which is already setted at before statements
|
||||
if s.Config.VScheme == "" {
|
||||
// if :443 or :https then returns https:// otherwise http://
|
||||
s.Config.VScheme = ParseScheme(s.Config.VHost)
|
||||
}
|
||||
|
||||
}})
|
||||
|
||||
{
|
||||
|
@ -436,28 +430,21 @@ func (s *Framework) Boot() (firstTime bool) {
|
|||
return
|
||||
}
|
||||
|
||||
// Serve serves incoming connections from the given listener.
|
||||
//
|
||||
// Serve blocks until the given listener returns permanent error.
|
||||
func (s *Framework) Serve(ln net.Listener) error {
|
||||
if s.ln != nil {
|
||||
return errors.New("server is already started and listening")
|
||||
}
|
||||
|
||||
s.ln = ln
|
||||
func (s *Framework) setupServe() (srv *http.Server, deferFn func()) {
|
||||
s.closedManually = false
|
||||
|
||||
s.Boot()
|
||||
|
||||
// post any panics to the user defined logger.
|
||||
defer func() {
|
||||
deferFn = func() {
|
||||
// post any panics to the user defined logger.
|
||||
if rerr := recover(); rerr != nil {
|
||||
if err, ok := rerr.(error); ok {
|
||||
s.handlePanic(err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
srv = &http.Server{
|
||||
ReadTimeout: s.Config.ReadTimeout,
|
||||
WriteTimeout: s.Config.WriteTimeout,
|
||||
MaxHeaderBytes: s.Config.MaxHeaderBytes,
|
||||
|
@ -467,21 +454,38 @@ func (s *Framework) Serve(ln net.Listener) error {
|
|||
ErrorLog: s.policies.LoggerPolicy.ToLogger(log.LstdFlags),
|
||||
Handler: s.Router,
|
||||
}
|
||||
|
||||
// Set the grace shutdown, it's just a func no need to make things complicated
|
||||
// all are managed by net/http now.
|
||||
s.Shutdown = func(ctx context.Context) error {
|
||||
// order matters, look s.handlePanic
|
||||
s.closedManually = true
|
||||
err := srv.Shutdown(ctx)
|
||||
s.ln = nil
|
||||
return err
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Serve serves incoming connections from the given listener.
|
||||
//
|
||||
// Serve blocks until the given listener returns permanent error.
|
||||
func (s *Framework) Serve(ln net.Listener) error {
|
||||
if ln == nil {
|
||||
return errors.New("nil net.Listener on Serve")
|
||||
}
|
||||
|
||||
// if user called .Serve and doesn't uses any nginx-like balancers.
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = ParseHost(ln.Addr().String())
|
||||
} // Scheme will be checked from Boot state.
|
||||
|
||||
srv, fn := s.setupServe()
|
||||
defer fn()
|
||||
|
||||
// print the banner and wait for system channel interrupt
|
||||
go s.postServe()
|
||||
// finally return the error or block here, remember,
|
||||
// until go1.8 these are our best options.
|
||||
return srv.Serve(s.ln)
|
||||
return srv.Serve(ln)
|
||||
}
|
||||
|
||||
func (s *Framework) postServe() {
|
||||
|
@ -507,14 +511,15 @@ func (s *Framework) postServe() {
|
|||
// If you need to manually monitor any error please use `.Serve` instead.
|
||||
func (s *Framework) Listen(addr string) {
|
||||
addr = ParseHost(addr)
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr
|
||||
// this will be set as the front-end listening addr
|
||||
}
|
||||
// only here, other Listen functions should throw an error if port is missing.
|
||||
// User should know how to fix them on ListenUNIX/ListenTLS/ListenLETSENCRYPT/Serve,
|
||||
// they are used by more 'advanced' devs, mostly.
|
||||
|
||||
// if .Listen called normally and VHost is not setted,
|
||||
// so it's Host is the Real listening addr and user-given
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr // as it is
|
||||
// this will be set as the front-end listening addr
|
||||
} // VScheme will be checked on Boot.
|
||||
|
||||
// this check, only here, other Listen functions should throw an error if port is missing.
|
||||
if portIdx := strings.IndexByte(addr, ':'); portIdx < 0 {
|
||||
// missing port part, add it
|
||||
addr = addr + ":80"
|
||||
|
@ -538,16 +543,27 @@ func (s *Framework) Listen(addr string) {
|
|||
// If you need to manually monitor any error please use `.Serve` instead.
|
||||
func (s *Framework) ListenTLS(addr string, certFile, keyFile string) {
|
||||
addr = ParseHost(addr)
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr
|
||||
// this will be set as the front-end listening addr
|
||||
|
||||
{
|
||||
// set it before Boot, be-careful VHost and VScheme are used by nginx users too
|
||||
// we don't want to alt them.
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr
|
||||
// this will be set as the front-end listening addr
|
||||
}
|
||||
if s.Config.VScheme == "" {
|
||||
s.Config.VScheme = SchemeHTTPS
|
||||
}
|
||||
}
|
||||
|
||||
ln, err := TLS(addr, certFile, keyFile)
|
||||
if err != nil {
|
||||
s.handlePanic(err)
|
||||
}
|
||||
s.Must(s.Serve(ln))
|
||||
srv, fn := s.setupServe()
|
||||
// We are doing the same parts as .Serve does but instead we run srv.ListenAndServeTLS
|
||||
// because of un-exported net/http.server.go:setupHTTP2_ListenAndServeTLS function which
|
||||
// broke our previous flow but no problem :)
|
||||
defer fn()
|
||||
// print the banner and wait for system channel interrupt
|
||||
go s.postServe()
|
||||
s.Must(srv.ListenAndServeTLS(certFile, keyFile))
|
||||
}
|
||||
|
||||
// ListenLETSENCRYPT starts a server listening at the specific nat address
|
||||
|
@ -557,16 +573,25 @@ func (s *Framework) ListenTLS(addr string, certFile, keyFile string) {
|
|||
// if you skip the second parameter then the cache file is "./letsencrypt.cache"
|
||||
// if you want to disable cache then simple pass as second argument an empty empty string ""
|
||||
//
|
||||
// example: https://github.com/iris-contrib/examples/blob/master/letsencrypt/main.go
|
||||
// Note: HTTP/2 Push is not working with LETSENCRYPT, you have to use ListenTLS to enable HTTP/2
|
||||
// Because net/http's author didn't exported the functions to tell the server that is using HTTP/2...
|
||||
//
|
||||
// supports localhost domains for testing,
|
||||
// NOTE: if you are ready for production then use `$app.Serve(iris.LETSENCRYPTPROD("mydomain.com"))` instead
|
||||
// example: https://github.com/iris-contrib/examples/blob/master/letsencrypt/main.go
|
||||
func (s *Framework) ListenLETSENCRYPT(addr string, cacheFileOptional ...string) {
|
||||
addr = ParseHost(addr)
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr
|
||||
// this will be set as the front-end listening addr
|
||||
|
||||
{
|
||||
// set it before Boot, be-careful VHost and VScheme are used by nginx users too
|
||||
// we don't want to alt them.
|
||||
if s.Config.VHost == "" {
|
||||
s.Config.VHost = addr
|
||||
// this will be set as the front-end listening addr
|
||||
}
|
||||
if s.Config.VScheme == "" {
|
||||
s.Config.VScheme = SchemeHTTPS
|
||||
}
|
||||
}
|
||||
|
||||
ln, err := LETSENCRYPT(addr, cacheFileOptional...)
|
||||
if err != nil {
|
||||
s.handlePanic(err)
|
||||
|
|
22
router.go
22
router.go
|
@ -607,9 +607,9 @@ func (router *Router) StaticHandler(reqPath string, systemPath string, showList
|
|||
// second parameter: the system directory
|
||||
// third OPTIONAL parameter: the exception routes
|
||||
// (= give priority to these routes instead of the static handler)
|
||||
// for more options look iris.StaticHandler.
|
||||
// for more options look router.StaticHandler.
|
||||
//
|
||||
// iris.StaticWeb("/static", "./static")
|
||||
// router.StaticWeb("/static", "./static")
|
||||
//
|
||||
// As a special case, the returned file server redirects any request
|
||||
// ending in "/index.html" to the same path, without the final
|
||||
|
@ -618,8 +618,22 @@ func (router *Router) StaticHandler(reqPath string, systemPath string, showList
|
|||
// StaticWeb calls the StaticHandler(reqPath, systemPath, listingDirectories: false, gzip: false ).
|
||||
func (router *Router) StaticWeb(reqPath string, systemPath string, exceptRoutes ...RouteInfo) RouteInfo {
|
||||
h := router.StaticHandler(reqPath, systemPath, false, false, exceptRoutes...)
|
||||
routePath := validateWildcard(reqPath, "file")
|
||||
return router.registerResourceRoute(routePath, h)
|
||||
paramName := "file"
|
||||
routePath := validateWildcard(reqPath, paramName)
|
||||
handler := func(ctx *Context) {
|
||||
h(ctx)
|
||||
if fname := ctx.Param(paramName); fname != "" {
|
||||
cType := fs.TypeByExtension(fname)
|
||||
if cType != contentBinary && !strings.Contains(cType, "charset") {
|
||||
cType += "; charset=" + ctx.framework.Config.Charset
|
||||
}
|
||||
|
||||
ctx.SetContentType(cType)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return router.registerResourceRoute(routePath, handler)
|
||||
}
|
||||
|
||||
// Layout oerrides the parent template layout with a more specific layout for this Party
|
||||
|
|
Loading…
Reference in New Issue
Block a user