404 수정중
This commit is contained in:
parent
58b9fd6d82
commit
84ec23420d
23
main.go
23
main.go
|
@ -21,6 +21,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"amuz.es/go/mnemonics/middleware/logging"
|
"amuz.es/go/mnemonics/middleware/logging"
|
||||||
|
"amuz.es/go/mnemonics/middleware/recovery"
|
||||||
"amuz.es/go/mnemonics/middleware/secure"
|
"amuz.es/go/mnemonics/middleware/secure"
|
||||||
"amuz.es/go/mnemonics/middleware/session"
|
"amuz.es/go/mnemonics/middleware/session"
|
||||||
"amuz.es/go/mnemonics/middleware/static"
|
"amuz.es/go/mnemonics/middleware/static"
|
||||||
|
@ -41,29 +42,23 @@ func main() {
|
||||||
setMaxProcs()
|
setMaxProcs()
|
||||||
|
|
||||||
store := session.NewCookieStore([]byte(util.GetRandomString(128)))
|
store := session.NewCookieStore([]byte(util.GetRandomString(128)))
|
||||||
//gin.SetMode(gin.ReleaseMode)
|
gin.SetMode(gin.ReleaseMode)
|
||||||
r := gin.New()
|
r := gin.New()
|
||||||
// middleware settings
|
// middleware settings
|
||||||
|
|
||||||
r.Use(logging.Ginrus(time.RFC3339, true))
|
r.Use(logging.Ginrus(time.RFC3339, true))
|
||||||
|
// r.Use(recovery.Recovery())
|
||||||
r.Use(gin.Recovery())
|
|
||||||
|
|
||||||
// not found handler
|
// not found handler
|
||||||
r.NoRoute(func(c *gin.Context) {
|
r.NoRoute(recovery.RecoveryHttpError(http.StatusNotFound))
|
||||||
code := http.StatusNotFound
|
r.NoMethod(recovery.RecoveryHttpError(http.StatusMethodNotAllowed))
|
||||||
c.HTML(code, "page_404.html", template.Context{
|
|
||||||
"statusCode": code,
|
|
||||||
"statusMessage": http.StatusText(code),
|
|
||||||
"path": c.Request.URL.Path,
|
|
||||||
"method": c.Request.Method})
|
|
||||||
})
|
|
||||||
|
|
||||||
// suburl process
|
// suburl process
|
||||||
path := r.Group("/")
|
path := r.Group("/")
|
||||||
|
path.Use(recovery.RecoveryHTML())
|
||||||
// handlers
|
// handlers
|
||||||
api := path.Group("/api")
|
api := path.Group("/api")
|
||||||
|
api.Use(recovery.RecoveryJSON())
|
||||||
|
|
||||||
api.Use(secure.Secure(secure.Options{
|
api.Use(secure.Secure(secure.Options{
|
||||||
AllowedHosts: []string{},
|
AllowedHosts: []string{},
|
||||||
|
@ -78,9 +73,9 @@ func main() {
|
||||||
BrowserXssFilter: true,
|
BrowserXssFilter: true,
|
||||||
ContentSecurityPolicy: "default-src 'self'",
|
ContentSecurityPolicy: "default-src 'self'",
|
||||||
}))
|
}))
|
||||||
api.Use(session.Sessions("mysession", store))
|
api.Use(session.Sessions("mnemonics", store))
|
||||||
api.GET("", route.Me)
|
|
||||||
|
|
||||||
|
api.GET("/auth", route.Me)
|
||||||
path.GET("/self", route.Self)
|
path.GET("/self", route.Self)
|
||||||
path.GET("/metric", route.Metric)
|
path.GET("/metric", route.Metric)
|
||||||
path.GET("/health", func(c *gin.Context) {
|
path.GET("/health", func(c *gin.Context) {
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
package recovery
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httputil"
|
||||||
|
"runtime"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"amuz.es/go/mnemonics/middleware/template"
|
||||||
|
"amuz.es/go/mnemonics/util"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
dunno = []byte("???")
|
||||||
|
centerDot = []byte("·")
|
||||||
|
dot = []byte(".")
|
||||||
|
slash = []byte("/")
|
||||||
|
)
|
||||||
|
|
||||||
|
func recoveryInternal(code int, c *gin.Context, err error) map[string]interface{} {
|
||||||
|
logger := util.Log()
|
||||||
|
|
||||||
|
stack := stack(3)
|
||||||
|
httprequest, _ := httputil.DumpRequest(c.Request, false)
|
||||||
|
path := c.Request.URL.Path
|
||||||
|
|
||||||
|
info := map[string]interface{}{
|
||||||
|
"statusCode": code,
|
||||||
|
"statusMessage": fmt.Sprintf("%s : %s", http.StatusText(code), err),
|
||||||
|
"path": path}
|
||||||
|
|
||||||
|
detailInfo := map[string]interface{}{
|
||||||
|
"statusCode": code,
|
||||||
|
"statusMessage": fmt.Sprintf("%s : %s", http.StatusText(code), err),
|
||||||
|
"path": path,
|
||||||
|
"method": c.Request.Method,
|
||||||
|
"request": string(httprequest),
|
||||||
|
"stack": string(stack),
|
||||||
|
"error": string(err.(error).Error())}
|
||||||
|
|
||||||
|
logger.WithFields(logrus.Fields(detailInfo)).Error("[Recovery] panic recovered:\n")
|
||||||
|
return info
|
||||||
|
}
|
||||||
|
|
||||||
|
func recoveryError(code int, c *gin.Context) map[string]interface{} {
|
||||||
|
path := c.Request.URL.Path
|
||||||
|
return map[string]interface{}{
|
||||||
|
"statusCode": code,
|
||||||
|
"statusMessage": http.StatusText(code),
|
||||||
|
"path": path}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecoveryHttpError(code int) gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
info := recoveryError(code, c)
|
||||||
|
if strings.HasPrefix(c.Request.URL.Path, "/api") {
|
||||||
|
c.JSON(code, gin.H(info))
|
||||||
|
} else {
|
||||||
|
c.HTML(code, "page_404.html", template.Context(info))
|
||||||
|
}
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func RecoveryJSON() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
code := http.StatusInternalServerError
|
||||||
|
info := recoveryInternal(code, c, err.(error))
|
||||||
|
c.JSON(code, gin.H(info))
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func RecoveryHTML() gin.HandlerFunc {
|
||||||
|
return func(c *gin.Context) {
|
||||||
|
defer func() {
|
||||||
|
if err := recover(); err != nil {
|
||||||
|
code := http.StatusInternalServerError
|
||||||
|
info := recoveryInternal(code, c, err.(error))
|
||||||
|
c.HTML(code, "page_404.html", template.Context(info))
|
||||||
|
c.Abort()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
c.Next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// stack returns a nicely formated stack frame, skipping skip frames
|
||||||
|
func stack(skip int) []byte {
|
||||||
|
buf := new(bytes.Buffer) // the returned data
|
||||||
|
// As we loop, we open files and read them. These variables record the currently
|
||||||
|
// loaded file.
|
||||||
|
var lines [][]byte
|
||||||
|
var lastFile string
|
||||||
|
for i := skip; ; i++ { // Skip the expected number of frames
|
||||||
|
pc, file, line, ok := runtime.Caller(i)
|
||||||
|
if !ok {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
// Print this much at least. If we can't find the source, it won't show.
|
||||||
|
fmt.Fprintf(buf, "%s:%d (0x%x)\n", file, line, pc)
|
||||||
|
if file != lastFile {
|
||||||
|
data, err := ioutil.ReadFile(file)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
lines = bytes.Split(data, []byte{'\n'})
|
||||||
|
lastFile = file
|
||||||
|
}
|
||||||
|
fmt.Fprintf(buf, "\t%s: %s\n", function(pc), source(lines, line))
|
||||||
|
}
|
||||||
|
return buf.Bytes()
|
||||||
|
}
|
||||||
|
|
||||||
|
// source returns a space-trimmed slice of the n'th line.
|
||||||
|
func source(lines [][]byte, n int) []byte {
|
||||||
|
n-- // in stack trace, lines are 1-indexed but our array is 0-indexed
|
||||||
|
if n < 0 || n >= len(lines) {
|
||||||
|
return dunno
|
||||||
|
}
|
||||||
|
return bytes.TrimSpace(lines[n])
|
||||||
|
}
|
||||||
|
|
||||||
|
// function returns, if possible, the name of the function containing the PC.
|
||||||
|
func function(pc uintptr) []byte {
|
||||||
|
fn := runtime.FuncForPC(pc)
|
||||||
|
if fn == nil {
|
||||||
|
return dunno
|
||||||
|
}
|
||||||
|
name := []byte(fn.Name())
|
||||||
|
// The name includes the path name to the package, which is unnecessary
|
||||||
|
// since the file name is already included. Plus, it has center dots.
|
||||||
|
// That is, we see
|
||||||
|
// runtime/debug.*T·ptrmethod
|
||||||
|
// and want
|
||||||
|
// *T.ptrmethod
|
||||||
|
// Also the package path might contains dot (e.g. code.google.com/...),
|
||||||
|
// so first eliminate the path prefix
|
||||||
|
if lastslash := bytes.LastIndex(name, slash); lastslash >= 0 {
|
||||||
|
name = name[lastslash+1:]
|
||||||
|
}
|
||||||
|
if period := bytes.Index(name, dot); period >= 0 {
|
||||||
|
name = name[period+1:]
|
||||||
|
}
|
||||||
|
name = bytes.Replace(name, centerDot, dot, -1)
|
||||||
|
return name
|
||||||
|
}
|
|
@ -142,7 +142,6 @@ func (l ldapSource) Bind(uid string, password pwdStor) {
|
||||||
dn := fmt.Sprintf("%s=%s,%s", l.user.uniqueAttributeName, uid, l.user.dn)
|
dn := fmt.Sprintf("%s=%s,%s", l.user.uniqueAttributeName, uid, l.user.dn)
|
||||||
err := l.connection.Bind(dn, password.GetPlainPassword()).(*ldap.Error)
|
err := l.connection.Bind(dn, password.GetPlainPassword()).(*ldap.Error)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Log().Errorf("dddd %d", err.ResultCode)
|
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue