// Error is an error/panic handler middleware. // Any error/panic is recovered and logged and the error response is returned to the user (auto-generated if none was set). func Error(ctx *neptulon.ReqCtx) error { errored := false if err := ctx.Next(); err != nil { errored = true log.Printf("mw: error: error handling response: %v", err) } if err := recover(); err != nil { errored = true const size = 64 << 10 buf := make([]byte, size) buf = buf[:runtime.Stack(buf, false)] log.Printf("mw: error: panic handling response: %v\nstack trace: %s", err, buf) } if errored { if ctx.Err == nil { ctx.Err = &neptulon.ResError{ Code: 500, Message: "Internal server error.", } } return ctx.Next() } return nil }
// Echo sends incoming messages back as is. func Echo(ctx *neptulon.ReqCtx) error { // unmarshall incoming message into response directly if err := ctx.Params(&ctx.Res); err != nil { return err } return ctx.Next() }
// Middleware is the Neptulon middleware method. func (r *Router) Middleware(ctx *neptulon.ReqCtx) error { if handler, ok := r.routes[ctx.Method]; ok { return handler(ctx) } return ctx.Next() }
// Logger is an incoming/outgoing message logger. func Logger(ctx *neptulon.ReqCtx) error { var v interface{} ctx.Params(&v) err := ctx.Next() var res interface{} if res = ctx.Session.Get(CustResLogDataKey); res == nil { res = ctx.Res if res == nil { res = ctx.Err } } log.Printf("mw: logger: %v: %v, in: \"%v\", out: \"%#v\"", ctx.ID, ctx.Method, v, res) return err }
// CertAtuh is TLS client-certificate authentication. // If successful, certificate common name will stored with the key "userid" in session. // If unsuccessful, connection will be closed right away. func CertAtuh(ctx *neptulon.ReqCtx) error { if _, ok := ctx.Session.GetOk("userid"); ok { return ctx.Next() } // if provided, client certificate is verified by the TLS listener so the peerCerts list in the connection is trusted // connState, _ := ctx.Conn.ConnectionState() // certs := connState.PeerCertificates // if len(certs) == 0 { // log.Println("Invalid client-certificate authentication attempt:", ctx.Conn.RemoteAddr()) // ctx.Conn.Close() // return nil // } // // userID := certs[0].Subject.CommonName // ctx.Session.Set("userid", userID) // log.Printf("Client authenticated. TLS/IP: %v, User ID: %v, Conn ID: %v\n", ctx.Conn.RemoteAddr(), userID, ctx.Conn.ID) return ctx.Next() }
// Middleware registers a queue middleware to register user/connection IDs // for connecting users (upon their first incoming-message). func (q *Queue) Middleware(ctx *neptulon.ReqCtx) error { q.SetConn(ctx.Conn.Session.Get("userid").(string), ctx.Conn.ID) return ctx.Next() }
// Middleware registers a queue middleware to register user/connection IDs // for connecting users (upon their first incoming-message). func (q *Queue) Middleware(ctx *neptulon.ReqCtx) error { q.middlewareChan <- middlewareChan{userID: ctx.Conn.Session.Get("userid").(string), connID: ctx.Conn.ID} return ctx.Next() }