From b425a5b4bf6d3a4adbe74c96866ee56044546141 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:43:28 +0100 Subject: [PATCH 01/15] v1.8.34 --- .travis.yml | 6 +- app.go | 70 +++---- consts.go | 547 ++++++++++++++++++++++++++++++++++++++++++++++++++ context.go | 31 +-- deprecated.go | 115 +++++++++++ group.go | 55 ++--- router.go | 51 ----- utils.go | 448 +---------------------------------------- 8 files changed, 726 insertions(+), 597 deletions(-) create mode 100644 consts.go create mode 100644 deprecated.go diff --git a/.travis.yml b/.travis.yml index 31edb442..c3865ad5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,11 +1,15 @@ language: go +sudo: false os: - linux - windows - osx go: - - 1.11.x + - go: 1.11.x + - go: 1.12.x + - go: 1.13.x + - go: 1.14.x env: - GO111MODULE=on install: diff --git a/app.go b/app.go index 46db178c..5a925f69 100644 --- a/app.go +++ b/app.go @@ -8,7 +8,6 @@ import ( "bufio" "crypto/tls" "fmt" - "io/ioutil" "log" "net" "net/http" @@ -176,55 +175,55 @@ func (app *App) Use(args ...interface{}) *App { // Connect : https://fiber.wiki/application#http-methods func (app *App) Connect(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodConnect, path, handlers...) + app.registerMethod(fasthttp.MethodConnect, path, handlers...) return app } // Put : https://fiber.wiki/application#http-methods func (app *App) Put(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodPut, path, handlers...) + app.registerMethod(fasthttp.MethodPut, path, handlers...) return app } // Post : https://fiber.wiki/application#http-methods func (app *App) Post(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodPost, path, handlers...) + app.registerMethod(fasthttp.MethodPost, path, handlers...) return app } // Delete : https://fiber.wiki/application#http-methods func (app *App) Delete(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodDelete, path, handlers...) + app.registerMethod(fasthttp.MethodDelete, path, handlers...) return app } // Head : https://fiber.wiki/application#http-methods func (app *App) Head(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodHead, path, handlers...) + app.registerMethod(fasthttp.MethodHead, path, handlers...) return app } // Patch : https://fiber.wiki/application#http-methods func (app *App) Patch(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodPatch, path, handlers...) + app.registerMethod(fasthttp.MethodPatch, path, handlers...) return app } // Options : https://fiber.wiki/application#http-methods func (app *App) Options(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodOptions, path, handlers...) + app.registerMethod(fasthttp.MethodOptions, path, handlers...) return app } // Trace : https://fiber.wiki/application#http-methods func (app *App) Trace(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodTrace, path, handlers...) + app.registerMethod(fasthttp.MethodTrace, path, handlers...) return app } // Get : https://fiber.wiki/application#http-methods func (app *App) Get(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(http.MethodGet, path, handlers...) + app.registerMethod(fasthttp.MethodGet, path, handlers...) return app } @@ -240,21 +239,6 @@ func (app *App) All(path string, handlers ...func(*Ctx)) *App { return app } -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/websocket -func (app *App) WebSocket(path string, handle func(*Ctx)) *App { - log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") - app.registerWebSocket(http.MethodGet, path, handle) - return app -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/recover -func (app *App) Recover(handler func(*Ctx)) { - log.Println("Warning: app.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") - app.recover = handler -} - // Listen : https://fiber.wiki/application#listen func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error { addr, ok := address.(string) @@ -305,18 +289,17 @@ func (app *App) Shutdown() error { // Test : https://fiber.wiki/application#test func (app *App) Test(request *http.Request) (*http.Response, error) { - // Get raw http request - reqRaw, err := httputil.DumpRequest(request, true) + // Dump raw http request + dump, err := httputil.DumpRequest(request, true) if err != nil { return nil, err } - // Setup a fiber server struct + // Setup server app.server = app.newServer() - // Create fake connection - conn := &testConn{} - // Pass HTTP request to conn - _, err = conn.r.Write(reqRaw) - if err != nil { + // Create conn + conn := new(testConn) + // Write raw http request + if _, err = conn.r.Write(dump); err != nil { return nil, err } // Serve conn to server @@ -330,19 +313,12 @@ func (app *App) Test(request *http.Request) (*http.Response, error) { if err != nil { return nil, err } - // Throw timeout error after 200ms case <-time.After(200 * time.Millisecond): - return nil, fmt.Errorf("timeout") + return nil, fmt.Errorf("Timeout error") } - // Get raw HTTP response - respRaw, err := ioutil.ReadAll(&conn.w) - if err != nil { - return nil, err - } - // Create buffer - reader := strings.NewReader(getString(respRaw)) - buffer := bufio.NewReader(reader) - // Convert raw HTTP response to http.Response + // Read response + buffer := bufio.NewReader(&conn.w) + // Convert raw http response to *http.Response resp, err := http.ReadResponse(buffer, request) if err != nil { return nil, err @@ -393,9 +369,9 @@ func (app *App) prefork(address string) (ln net.Listener, err error) { return ln, err } -type disableLogger struct{} +type customLogger struct{} -func (dl *disableLogger) Printf(format string, args ...interface{}) { +func (cl *customLogger) Printf(format string, args ...interface{}) { // fmt.Println(fmt.Sprintf(format, args...)) } @@ -405,7 +381,7 @@ func (app *App) newServer() *fasthttp.Server { Name: app.Settings.ServerHeader, MaxRequestBodySize: app.Settings.BodyLimit, NoDefaultServerHeader: app.Settings.ServerHeader == "", - Logger: &disableLogger{}, + Logger: &customLogger{}, LogAllErrors: false, ErrorHandler: func(ctx *fasthttp.RequestCtx, err error) { if err.Error() == "body size exceeds the given limit" { diff --git a/consts.go b/consts.go new file mode 100644 index 00000000..c8b58113 --- /dev/null +++ b/consts.go @@ -0,0 +1,547 @@ +// 🚀 Fiber is an Express inspired web framework written in Go with 💖 +// 📌 API Documentation: https://fiber.wiki +// 📝 Github Repository: https://github.com/gofiber/fiber + +package fiber + +// HTTP status codes were copied from net/http. +var statusMessages = map[int]string{ + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required", +} + +// MIME types were copied from labstack/echo +const ( + MIMETextXML = "text/xml" + MIMETextHTML = "text/html" + MIMETextPlain = "text/plain" + + MIMEApplicationJSON = "application/json" + MIMEApplicationJavaScript = "application/javascript" + MIMEApplicationXML = "application/xml" + MIMEApplicationForm = "application/x-www-form-urlencoded" + + MIMEMultipartForm = "multipart/form-data" + + MIMEOctetStream = "application/octet-stream" +) + +// MIME types were copied from nginx/mime.types. +var extensionMIME = map[string]string{ + // without dot + "html": "text/html", + "htm": "text/html", + "shtml": "text/html", + "css": "text/css", + "gif": "image/gif", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "xml": "application/xml", + "js": "application/javascript", + "atom": "application/atom+xml", + "rss": "application/rss+xml", + "mml": "text/mathml", + "txt": "text/plain", + "jad": "text/vnd.sun.j2me.app-descriptor", + "wml": "text/vnd.wap.wml", + "htc": "text/x-component", + "png": "image/png", + "svg": "image/svg+xml", + "svgz": "image/svg+xml", + "tif": "image/tiff", + "tiff": "image/tiff", + "wbmp": "image/vnd.wap.wbmp", + "webp": "image/webp", + "ico": "image/x-icon", + "jng": "image/x-jng", + "bmp": "image/x-ms-bmp", + "woff": "font/woff", + "woff2": "font/woff2", + "jar": "application/java-archive", + "war": "application/java-archive", + "ear": "application/java-archive", + "json": "application/json", + "hqx": "application/mac-binhex40", + "doc": "application/msword", + "pdf": "application/pdf", + "ps": "application/postscript", + "eps": "application/postscript", + "ai": "application/postscript", + "rtf": "application/rtf", + "m3u8": "application/vnd.apple.mpegurl", + "kml": "application/vnd.google-earth.kml+xml", + "kmz": "application/vnd.google-earth.kmz", + "xls": "application/vnd.ms-excel", + "eot": "application/vnd.ms-fontobject", + "ppt": "application/vnd.ms-powerpoint", + "odg": "application/vnd.oasis.opendocument.graphics", + "odp": "application/vnd.oasis.opendocument.presentation", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "odt": "application/vnd.oasis.opendocument.text", + "wmlc": "application/vnd.wap.wmlc", + "7z": "application/x-7z-compressed", + "cco": "application/x-cocoa", + "jardiff": "application/x-java-archive-diff", + "jnlp": "application/x-java-jnlp-file", + "run": "application/x-makeself", + "pl": "application/x-perl", + "pm": "application/x-perl", + "prc": "application/x-pilot", + "pdb": "application/x-pilot", + "rar": "application/x-rar-compressed", + "rpm": "application/x-redhat-package-manager", + "sea": "application/x-sea", + "swf": "application/x-shockwave-flash", + "sit": "application/x-stuffit", + "tcl": "application/x-tcl", + "tk": "application/x-tcl", + "der": "application/x-x509-ca-cert", + "pem": "application/x-x509-ca-cert", + "crt": "application/x-x509-ca-cert", + "xpi": "application/x-xpinstall", + "xhtml": "application/xhtml+xml", + "xspf": "application/xspf+xml", + "zip": "application/zip", + "bin": "application/octet-stream", + "exe": "application/octet-stream", + "dll": "application/octet-stream", + "deb": "application/octet-stream", + "dmg": "application/octet-stream", + "iso": "application/octet-stream", + "img": "application/octet-stream", + "msi": "application/octet-stream", + "msp": "application/octet-stream", + "msm": "application/octet-stream", + "mid": "audio/midi", + "midi": "audio/midi", + "kar": "audio/midi", + "mp3": "audio/mpeg", + "ogg": "audio/ogg", + "m4a": "audio/x-m4a", + "ra": "audio/x-realaudio", + "3gpp": "video/3gpp", + "3gp": "video/3gpp", + "ts": "video/mp2t", + "mp4": "video/mp4", + "mpeg": "video/mpeg", + "mpg": "video/mpeg", + "mov": "video/quicktime", + "webm": "video/webm", + "flv": "video/x-flv", + "m4v": "video/x-m4v", + "mng": "video/x-mng", + "asx": "video/x-ms-asf", + "asf": "video/x-ms-asf", + "wmv": "video/x-ms-wmv", + "avi": "video/x-msvideo", + + // with dot + ".html": "text/html", + ".htm": "text/html", + ".shtml": "text/html", + ".css": "text/css", + ".gif": "image/gif", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".xml": "application/xml", + ".js": "application/javascript", + ".atom": "application/atom+xml", + ".rss": "application/rss+xml", + ".mml": "text/mathml", + ".txt": "text/plain", + ".jad": "text/vnd.sun.j2me.app-descriptor", + ".wml": "text/vnd.wap.wml", + ".htc": "text/x-component", + ".png": "image/png", + ".svg": "image/svg+xml", + ".svgz": "image/svg+xml", + ".tif": "image/tiff", + ".tiff": "image/tiff", + ".wbmp": "image/vnd.wap.wbmp", + ".webp": "image/webp", + ".ico": "image/x-icon", + ".jng": "image/x-jng", + ".bmp": "image/x-ms-bmp", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".jar": "application/java-archive", + ".war": "application/java-archive", + ".ear": "application/java-archive", + ".json": "application/json", + ".hqx": "application/mac-binhex40", + ".doc": "application/msword", + ".pdf": "application/pdf", + ".ps": "application/postscript", + ".eps": "application/postscript", + ".ai": "application/postscript", + ".rtf": "application/rtf", + ".m3u8": "application/vnd.apple.mpegurl", + ".kml": "application/vnd.google-earth.kml+xml", + ".kmz": "application/vnd.google-earth.kmz", + ".xls": "application/vnd.ms-excel", + ".eot": "application/vnd.ms-fontobject", + ".ppt": "application/vnd.ms-powerpoint", + ".odg": "application/vnd.oasis.opendocument.graphics", + ".odp": "application/vnd.oasis.opendocument.presentation", + ".ods": "application/vnd.oasis.opendocument.spreadsheet", + ".odt": "application/vnd.oasis.opendocument.text", + ".wmlc": "application/vnd.wap.wmlc", + ".7z": "application/x-7z-compressed", + ".cco": "application/x-cocoa", + ".jardiff": "application/x-java-archive-diff", + ".jnlp": "application/x-java-jnlp-file", + ".run": "application/x-makeself", + ".pl": "application/x-perl", + ".pm": "application/x-perl", + ".prc": "application/x-pilot", + ".pdb": "application/x-pilot", + ".rar": "application/x-rar-compressed", + ".rpm": "application/x-redhat-package-manager", + ".sea": "application/x-sea", + ".swf": "application/x-shockwave-flash", + ".sit": "application/x-stuffit", + ".tcl": "application/x-tcl", + ".tk": "application/x-tcl", + ".der": "application/x-x509-ca-cert", + ".pem": "application/x-x509-ca-cert", + ".crt": "application/x-x509-ca-cert", + ".xpi": "application/x-xpinstall", + ".xhtml": "application/xhtml+xml", + ".xspf": "application/xspf+xml", + ".zip": "application/zip", + ".bin": "application/octet-stream", + ".exe": "application/octet-stream", + ".dll": "application/octet-stream", + ".deb": "application/octet-stream", + ".dmg": "application/octet-stream", + ".iso": "application/octet-stream", + ".img": "application/octet-stream", + ".msi": "application/octet-stream", + ".msp": "application/octet-stream", + ".msm": "application/octet-stream", + ".mid": "audio/midi", + ".midi": "audio/midi", + ".kar": "audio/midi", + ".mp3": "audio/mpeg", + ".ogg": "audio/ogg", + ".m4a": "audio/x-m4a", + ".ra": "audio/x-realaudio", + ".3gpp": "video/3gpp", + ".3gp": "video/3gpp", + ".ts": "video/mp2t", + ".mp4": "video/mp4", + ".mpeg": "video/mpeg", + ".mpg": "video/mpeg", + ".mov": "video/quicktime", + ".webm": "video/webm", + ".flv": "video/x-flv", + ".m4v": "video/x-m4v", + ".mng": "video/x-mng", + ".asx": "video/x-ms-asf", + ".asf": "video/x-ms-asf", + ".wmv": "video/x-ms-wmv", + ".avi": "video/x-msvideo", +} + +// HTTP methods were copied from net/http. +const ( + MethodGet = "GET" // RFC 7231, 4.3.1 + MethodHead = "HEAD" // RFC 7231, 4.3.2 + MethodPost = "POST" // RFC 7231, 4.3.3 + MethodPut = "PUT" // RFC 7231, 4.3.4 + MethodPatch = "PATCH" // RFC 5789 + MethodDelete = "DELETE" // RFC 7231, 4.3.5 + MethodConnect = "CONNECT" // RFC 7231, 4.3.6 + MethodOptions = "OPTIONS" // RFC 7231, 4.3.7 + MethodTrace = "TRACE" // RFC 7231, 4.3.8 +) + +// HTTP Headers were copied from net/http. +const ( + // Authentication + HeaderAuthorization = "Authorization" + HeaderProxyAuthenticate = "Proxy-Authenticate" + HeaderProxyAuthorization = "Proxy-Authorization" + HeaderWWWAuthenticate = "WWW-Authenticate" + + // Caching + HeaderAge = "Age" + HeaderCacheControl = "Cache-Control" + HeaderClearSiteData = "Clear-Site-Data" + HeaderExpires = "Expires" + HeaderPragma = "Pragma" + HeaderWarning = "Warning" + + // Client hints + HeaderAcceptCH = "Accept-CH" + HeaderAcceptCHLifetime = "Accept-CH-Lifetime" + HeaderContentDPR = "Content-DPR" + HeaderDPR = "DPR" + HeaderEarlyData = "Early-Data" + HeaderSaveData = "Save-Data" + HeaderViewportWidth = "Viewport-Width" + HeaderWidth = "Width" + + // Conditionals + HeaderETag = "ETag" + HeaderIfMatch = "If-Match" + HeaderIfModifiedSince = "If-Modified-Since" + HeaderIfNoneMatch = "If-None-Match" + HeaderIfUnmodifiedSince = "If-Unmodified-Since" + HeaderLastModified = "Last-Modified" + HeaderVary = "Vary" + + // Connection management + HeaderConnection = "Connection" + HeaderKeepAlive = "Keep-Alive" + + // Content negotiation + HeaderAccept = "Accept" + HeaderAcceptCharset = "Accept-Charset" + HeaderAcceptEncoding = "Accept-Encoding" + HeaderAcceptLanguage = "Accept-Language" + + // Controls + HeaderCookie = "Cookie" + HeaderExpect = "Expect" + HeaderMaxForwards = "Max-Forwards" + HeaderSetCookie = "Set-Cookie" + + // CORS + HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" + HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" + HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" + HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" + HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" + HeaderAccessControlMaxAge = "Access-Control-Max-Age" + HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" + HeaderAccessControlRequestMethod = "Access-Control-Request-Method" + HeaderOrigin = "Origin" + HeaderTimingAllowOrigin = "Timing-Allow-Origin" + HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" + + // Do Not Track + HeaderDNT = "DNT" + HeaderTk = "Tk" + + // Downloads + HeaderContentDisposition = "Content-Disposition" + + // Message body information + HeaderContentEncoding = "Content-Encoding" + HeaderContentLanguage = "Content-Language" + HeaderContentLength = "Content-Length" + HeaderContentLocation = "Content-Location" + HeaderContentType = "Content-Type" + + // Proxies + HeaderForwarded = "Forwarded" + HeaderVia = "Via" + HeaderXForwardedFor = "X-Forwarded-For" + HeaderXForwardedHost = "X-Forwarded-Host" + HeaderXForwardedProto = "X-Forwarded-Proto" + + // Redirects + HeaderLocation = "Location" + + // Request context + HeaderFrom = "From" + HeaderHost = "Host" + HeaderReferer = "Referer" + HeaderReferrerPolicy = "Referrer-Policy" + HeaderUserAgent = "User-Agent" + + // Response context + HeaderAllow = "Allow" + HeaderServer = "Server" + + // Range requests + HeaderAcceptRanges = "Accept-Ranges" + HeaderContentRange = "Content-Range" + HeaderIfRange = "If-Range" + HeaderRange = "Range" + + // Security + HeaderContentSecurityPolicy = "Content-Security-Policy" + HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" + HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" + HeaderExpectCT = "Expect-CT" + HeaderFeaturePolicy = "Feature-Policy" + HeaderPublicKeyPins = "Public-Key-Pins" + HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" + HeaderStrictTransportSecurity = "Strict-Transport-Security" + HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" + HeaderXContentTypeOptions = "X-Content-Type-Options" + HeaderXDownloadOptions = "X-Download-Options" + HeaderXFrameOptions = "X-Frame-Options" + HeaderXPoweredBy = "X-Powered-By" + HeaderXXSSProtection = "X-XSS-Protection" + + // Server-sent event + HeaderLastEventID = "Last-Event-ID" + HeaderNEL = "NEL" + HeaderPingFrom = "Ping-From" + HeaderPingTo = "Ping-To" + HeaderReportTo = "Report-To" + + // Transfer coding + HeaderTE = "TE" + HeaderTrailer = "Trailer" + HeaderTransferEncoding = "Transfer-Encoding" + + // WebSockets + HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" + HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" + HeaderSecWebSocketKey = "Sec-WebSocket-Key" + HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" + HeaderSecWebSocketVersion = "Sec-WebSocket-Version" + + // Other + HeaderAcceptPatch = "Accept-Patch" + HeaderAcceptPushPolicy = "Accept-Push-Policy" + HeaderAcceptSignature = "Accept-Signature" + HeaderAltSvc = "Alt-Svc" + HeaderDate = "Date" + HeaderIndex = "Index" + HeaderLargeAllocation = "Large-Allocation" + HeaderLink = "Link" + HeaderPushPolicy = "Push-Policy" + HeaderRetryAfter = "Retry-After" + HeaderServerTiming = "Server-Timing" + HeaderSignature = "Signature" + HeaderSignedHeaders = "Signed-Headers" + HeaderSourceMap = "SourceMap" + HeaderUpgrade = "Upgrade" + HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" + HeaderXPingback = "X-Pingback" + HeaderXRequestID = "X-Request-ID" + HeaderXRequestedWith = "X-Requested-With" + HeaderXRobotsTag = "X-Robots-Tag" + HeaderXUACompatible = "X-UA-Compatible" +) + +// HTTP status codes were copied from net/http. +const ( + StatusContinue = 100 // RFC 7231, 6.2.1 + StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 + StatusProcessing = 102 // RFC 2518, 10.1 + + StatusOK = 200 // RFC 7231, 6.3.1 + StatusCreated = 201 // RFC 7231, 6.3.2 + StatusAccepted = 202 // RFC 7231, 6.3.3 + StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 + StatusNoContent = 204 // RFC 7231, 6.3.5 + StatusResetContent = 205 // RFC 7231, 6.3.6 + StatusPartialContent = 206 // RFC 7233, 4.1 + StatusMultiStatus = 207 // RFC 4918, 11.1 + StatusAlreadyReported = 208 // RFC 5842, 7.1 + StatusIMUsed = 226 // RFC 3229, 10.4.1 + + StatusMultipleChoices = 300 // RFC 7231, 6.4.1 + StatusMovedPermanently = 301 // RFC 7231, 6.4.2 + StatusFound = 302 // RFC 7231, 6.4.3 + StatusSeeOther = 303 // RFC 7231, 6.4.4 + StatusNotModified = 304 // RFC 7232, 4.1 + StatusUseProxy = 305 // RFC 7231, 6.4.5 + + StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 + StatusPermanentRedirect = 308 // RFC 7538, 3 + + StatusBadRequest = 400 // RFC 7231, 6.5.1 + StatusUnauthorized = 401 // RFC 7235, 3.1 + StatusPaymentRequired = 402 // RFC 7231, 6.5.2 + StatusForbidden = 403 // RFC 7231, 6.5.3 + StatusNotFound = 404 // RFC 7231, 6.5.4 + StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 + StatusNotAcceptable = 406 // RFC 7231, 6.5.6 + StatusProxyAuthRequired = 407 // RFC 7235, 3.2 + StatusRequestTimeout = 408 // RFC 7231, 6.5.7 + StatusConflict = 409 // RFC 7231, 6.5.8 + StatusGone = 410 // RFC 7231, 6.5.9 + StatusLengthRequired = 411 // RFC 7231, 6.5.10 + StatusPreconditionFailed = 412 // RFC 7232, 4.2 + StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 + StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 + StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 + StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 + StatusExpectationFailed = 417 // RFC 7231, 6.5.14 + StatusTeapot = 418 // RFC 7168, 2.3.3 + StatusUnprocessableEntity = 422 // RFC 4918, 11.2 + StatusLocked = 423 // RFC 4918, 11.3 + StatusFailedDependency = 424 // RFC 4918, 11.4 + StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 + StatusPreconditionRequired = 428 // RFC 6585, 3 + StatusTooManyRequests = 429 // RFC 6585, 4 + StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 + StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 + + StatusInternalServerError = 500 // RFC 7231, 6.6.1 + StatusNotImplemented = 501 // RFC 7231, 6.6.2 + StatusBadGateway = 502 // RFC 7231, 6.6.3 + StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 + StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 + StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 + StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 + StatusInsufficientStorage = 507 // RFC 4918, 11.5 + StatusLoopDetected = 508 // RFC 5842, 7.2 + StatusNotExtended = 510 // RFC 2774, 7 + StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 +) diff --git a/context.go b/context.go index 91367d6e..d7621715 100644 --- a/context.go +++ b/context.go @@ -57,6 +57,7 @@ type Cookie struct { Expires time.Time Secure bool HTTPOnly bool + SameSite string } // Ctx pool @@ -125,7 +126,7 @@ func (ctx *Ctx) Accepts(offers ...string) (offer string) { specs := strings.Split(h, ",") for _, value := range offers { - mimetype := getType(value) + mimetype := getMIME(value) // if mimetype != "" { // mimetype = strings.Split(mimetype, ";")[0] // } else { @@ -343,16 +344,6 @@ func (ctx *Ctx) ClearCookie(key ...string) { }) } -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/compression -func (ctx *Ctx) Compress(enable ...bool) { - log.Println("Warning: c.Compress() is deprecated since v1.8.2, please use github.com/gofiber/compression instead.") - ctx.compress = true - if len(enable) > 0 { - ctx.compress = enable[0] - } -} - // Set cookie by passing a cookie struct // // https://fiber.wiki/context#cookie @@ -364,7 +355,23 @@ func (ctx *Ctx) Cookie(cookie *Cookie) { fcookie.SetDomain(cookie.Domain) fcookie.SetExpire(cookie.Expires) fcookie.SetSecure(cookie.Secure) + if cookie.Secure { + // Secure must be paired with SameSite=None + fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode) + } fcookie.SetHTTPOnly(cookie.HTTPOnly) + switch strings.ToLower(cookie.SameSite) { + case "lax": + fcookie.SetSameSite(fasthttp.CookieSameSiteLaxMode) + case "strict": + fcookie.SetSameSite(fasthttp.CookieSameSiteStrictMode) + case "none": + fcookie.SetSameSite(fasthttp.CookieSameSiteNoneMode) + // Secure must be paired with SameSite=None + fcookie.SetSecure(true) + default: + fcookie.SetSameSite(fasthttp.CookieSameSiteDisabled) + } ctx.Fasthttp.Response.Header.SetCookie(fcookie) } @@ -912,7 +919,7 @@ func (ctx *Ctx) Status(status int) *Ctx { // // https://fiber.wiki/context#type func (ctx *Ctx) Type(ext string) *Ctx { - ctx.Fasthttp.Response.Header.SetContentType(getType(ext)) + ctx.Fasthttp.Response.Header.SetContentType(getMIME(ext)) return ctx } diff --git a/deprecated.go b/deprecated.go new file mode 100644 index 00000000..0a291e02 --- /dev/null +++ b/deprecated.go @@ -0,0 +1,115 @@ +// 🚀 Fiber is an Express inspired web framework written in Go with 💖 +// 📌 API Documentation: https://fiber.wiki +// 📝 Github Repository: https://github.com/gofiber/fiber + +package fiber + +import ( + "log" + "regexp" + "strings" + + websocket "github.com/fasthttp/websocket" + fasthttp "github.com/valyala/fasthttp" +) + +// These variables are deprecated since v1.8.2! +var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression) +var websocketUpgrader = websocket.FastHTTPUpgrader{ + ReadBufferSize: 1024, + WriteBufferSize: 1024, + CheckOrigin: func(fctx *fasthttp.RequestCtx) bool { + return true + }, +} + +// This function is deprecated since v1.8.2! +// Please us github.com/gofiber/compression +func (ctx *Ctx) Compress(enable ...bool) { + log.Println("Warning: c.Compress() is deprecated since v1.8.2, please use github.com/gofiber/compression instead.") + ctx.compress = true + if len(enable) > 0 { + ctx.compress = enable[0] + } +} + +// This function is deprecated since v1.8.2! +// Please us github.com/gofiber/websocket +func (app *App) WebSocket(path string, handle func(*Ctx)) *App { + log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") + app.registerWebSocket(fasthttp.MethodGet, path, handle) + return app +} + +// This function is deprecated since v1.8.2! +// Please us github.com/gofiber/websocket +func (grp *Group) WebSocket(path string, handle func(*Ctx)) *Group { + log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") + grp.app.registerWebSocket(fasthttp.MethodGet, groupPaths(grp.prefix, path), handle) + return grp +} + +// This function is deprecated since v1.8.2! +// Please us github.com/gofiber/recover +func (app *App) Recover(handler func(*Ctx)) { + log.Println("Warning: app.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") + app.recover = handler +} + +// This function is deprecated since v1.8.2! +// Please us github.com/gofiber/recover +func (grp *Group) Recover(handler func(*Ctx)) { + log.Println("Warning: Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") + grp.app.recover = handler +} + +func (app *App) registerWebSocket(method, path string, handle func(*Ctx)) { + // Cannot have an empty path + if path == "" { + path = "/" + } + // Path always start with a '/' or '*' + if path[0] != '/' && path[0] != '*' { + path = "/" + path + } + // Store original path to strip case sensitive params + original := path + // Case sensitive routing, all to lowercase + if !app.Settings.CaseSensitive { + path = strings.ToLower(path) + } + // Strict routing, remove last `/` + if !app.Settings.StrictRouting && len(path) > 1 { + path = strings.TrimRight(path, "/") + } + + var isWebSocket = true + + var isStar = path == "*" || path == "/*" + var isSlash = path == "/" + var isRegex = false + // Route properties + var Params = getParams(original) + var Regexp *regexp.Regexp + // Params requires regex pattern + if len(Params) > 0 { + regex, err := getRegex(path) + if err != nil { + log.Fatal("Router: Invalid path pattern: " + path) + } + isRegex = true + Regexp = regex + } + app.routes = append(app.routes, &Route{ + isWebSocket: isWebSocket, + isStar: isStar, + isSlash: isSlash, + isRegex: isRegex, + + Method: method, + Path: path, + Params: Params, + Regexp: Regexp, + HandleCtx: handle, + }) +} diff --git a/group.go b/group.go index 43dcc144..96e5e2a2 100644 --- a/group.go +++ b/group.go @@ -6,8 +6,8 @@ package fiber import ( "log" - "net/http" - "reflect" + + fasthttp "github.com/valyala/fasthttp" ) // Group ... @@ -53,74 +53,64 @@ func (grp *Group) Use(args ...interface{}) *Group { case func(*Ctx): handlers = append(handlers, arg) default: - log.Fatalf("Invalid handler: %v", reflect.TypeOf(arg)) + log.Fatalf("Invalid Use() arguments, must be (prefix, handler) or (handler)") } } - path = groupPaths(grp.prefix, path) - grp.app.registerMethod("USE", path, handlers...) + grp.app.registerMethod("USE", groupPaths(grp.prefix, path), handlers...) return grp } // Connect : https://fiber.wiki/application#http-methods func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodConnect, path, handlers...) + grp.app.registerMethod(fasthttp.MethodConnect, groupPaths(grp.prefix, path), handlers...) return grp } // Put : https://fiber.wiki/application#http-methods func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodPut, path, handlers...) + grp.app.registerMethod(fasthttp.MethodPut, groupPaths(grp.prefix, path), handlers...) return grp } // Post : https://fiber.wiki/application#http-methods func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodPost, path, handlers...) + grp.app.registerMethod(fasthttp.MethodPost, groupPaths(grp.prefix, path), handlers...) return grp } // Delete : https://fiber.wiki/application#http-methods func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodDelete, path, handlers...) + grp.app.registerMethod(fasthttp.MethodDelete, groupPaths(grp.prefix, path), handlers...) return grp } // Head : https://fiber.wiki/application#http-methods func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodHead, path, handlers...) + grp.app.registerMethod(fasthttp.MethodHead, groupPaths(grp.prefix, path), handlers...) return grp } // Patch : https://fiber.wiki/application#http-methods func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodPatch, path, handlers...) + grp.app.registerMethod(fasthttp.MethodPatch, groupPaths(grp.prefix, path), handlers...) return grp } // Options : https://fiber.wiki/application#http-methods func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodOptions, path, handlers...) + grp.app.registerMethod(fasthttp.MethodOptions, groupPaths(grp.prefix, path), handlers...) return grp } // Trace : https://fiber.wiki/application#http-methods func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodTrace, path, handlers...) + grp.app.registerMethod(fasthttp.MethodTrace, groupPaths(grp.prefix, path), handlers...) return grp } // Get : https://fiber.wiki/application#http-methods func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod(http.MethodGet, path, handlers...) + grp.app.registerMethod(fasthttp.MethodGet, groupPaths(grp.prefix, path), handlers...) return grp } @@ -132,23 +122,6 @@ func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group { // // https://fiber.wiki/application#http-methods func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group { - path = groupPaths(grp.prefix, path) - grp.app.registerMethod("ALL", path, handlers...) + grp.app.registerMethod("ALL", groupPaths(grp.prefix, path), handlers...) return grp } - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/websocket -func (grp *Group) WebSocket(path string, handle func(*Ctx)) *Group { - log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") - path = groupPaths(grp.prefix, path) - grp.app.registerWebSocket(http.MethodGet, path, handle) - return grp -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/recover -func (grp *Group) Recover(handler func(*Ctx)) { - log.Println("Warning: Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") - grp.app.recover = handler -} diff --git a/router.go b/router.go index e1278fa1..b5bad1d2 100644 --- a/router.go +++ b/router.go @@ -206,57 +206,6 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) { } } -func (app *App) registerWebSocket(method, path string, handle func(*Ctx)) { - // Cannot have an empty path - if path == "" { - path = "/" - } - // Path always start with a '/' or '*' - if path[0] != '/' && path[0] != '*' { - path = "/" + path - } - // Store original path to strip case sensitive params - original := path - // Case sensitive routing, all to lowercase - if !app.Settings.CaseSensitive { - path = strings.ToLower(path) - } - // Strict routing, remove last `/` - if !app.Settings.StrictRouting && len(path) > 1 { - path = strings.TrimRight(path, "/") - } - - var isWebSocket = true - - var isStar = path == "*" || path == "/*" - var isSlash = path == "/" - var isRegex = false - // Route properties - var Params = getParams(original) - var Regexp *regexp.Regexp - // Params requires regex pattern - if len(Params) > 0 { - regex, err := getRegex(path) - if err != nil { - log.Fatal("Router: Invalid path pattern: " + path) - } - isRegex = true - Regexp = regex - } - app.routes = append(app.routes, &Route{ - isWebSocket: isWebSocket, - isStar: isStar, - isSlash: isSlash, - isRegex: isRegex, - - Method: method, - Path: path, - Params: Params, - Regexp: Regexp, - HandleCtx: handle, - }) -} - func (app *App) registerStatic(prefix, root string, config ...Static) { // Cannot have an empty prefix if prefix == "" { diff --git a/utils.go b/utils.go index b0e18a30..273d1333 100644 --- a/utils.go +++ b/utils.go @@ -15,20 +15,10 @@ import ( "time" "unsafe" - websocket "github.com/fasthttp/websocket" schema "github.com/gorilla/schema" - fasthttp "github.com/valyala/fasthttp" ) var schemaDecoder = schema.NewDecoder() -var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression) -var websocketUpgrader = websocket.FastHTTPUpgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(fctx *fasthttp.RequestCtx) bool { - return true - }, -} func groupPaths(prefix, path string) string { if path == "/" { @@ -39,15 +29,6 @@ func groupPaths(prefix, path string) string { return path } -// BenchmarkDefault 322504144 18.6 ns/op // string == string -// BenchmarkisEqual 353663168 17.0 ns/op // isEqual(string, string) -// func isEqual(a, b string) bool { -// if len(a) == len(b) { -// return a == b -// } -// return false -// } - func getParams(path string) (params []string) { if len(path) < 1 { return @@ -107,15 +88,11 @@ func getFiles(root string) (files []string, dir bool, err error) { return } -func getType(ext string) (mime string) { - if ext == "" { +func getMIME(extension string) (mime string) { + if extension == "" { return mime } - if ext[0] == '.' { - mime = extensionMIME[ext[1:]] - } else { - mime = extensionMIME[ext] - } + mime = extensionMIME[extension] if mime == "" { return MIMEOctetStream } @@ -156,422 +133,3 @@ func (c *testConn) Close() error { return nil } func (c *testConn) SetDeadline(t time.Time) error { return nil } func (c *testConn) SetReadDeadline(t time.Time) error { return nil } func (c *testConn) SetWriteDeadline(t time.Time) error { return nil } - -// MIME types -const ( - MIMEApplicationJSON = "application/json" - MIMEApplicationJavaScript = "application/javascript" - MIMEApplicationXML = "application/xml" - MIMETextXML = "text/xml" - MIMEApplicationForm = "application/x-www-form-urlencoded" - MIMEApplicationProtobuf = "application/protobuf" - MIMEApplicationMsgpack = "application/msgpack" - MIMETextHTML = "text/html" - MIMETextPlain = "text/plain" - MIMEMultipartForm = "multipart/form-data" - MIMEOctetStream = "application/octet-stream" -) - -// HTTP status codes with messages -var statusMessages = map[int]string{ - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi-Status", - 208: "Already Reported", - 226: "IM Used", - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 306: "Switch Proxy", - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required", -} - -// File extensions MIME types -var extensionMIME = map[string]string{ - "html": "text/html", - "htm": "text/html", - "shtml": "text/html", - "css": "text/css", - "gif": "image/gif", - "jpeg": "image/jpeg", - "jpg": "image/jpeg", - "xml": "application/xml", - "js": "application/javascript", - "atom": "application/atom+xml", - "rss": "application/rss+xml", - "mml": "text/mathml", - "txt": "text/plain", - "jad": "text/vnd.sun.j2me.app-descriptor", - "wml": "text/vnd.wap.wml", - "htc": "text/x-component", - "png": "image/png", - "svg": "image/svg+xml", - "svgz": "image/svg+xml", - "tif": "image/tiff", - "tiff": "image/tiff", - "wbmp": "image/vnd.wap.wbmp", - "webp": "image/webp", - "ico": "image/x-icon", - "jng": "image/x-jng", - "bmp": "image/x-ms-bmp", - "woff": "font/woff", - "woff2": "font/woff2", - "jar": "application/java-archive", - "war": "application/java-archive", - "ear": "application/java-archive", - "json": "application/json", - "hqx": "application/mac-binhex40", - "doc": "application/msword", - "pdf": "application/pdf", - "ps": "application/postscript", - "eps": "application/postscript", - "ai": "application/postscript", - "rtf": "application/rtf", - "m3u8": "application/vnd.apple.mpegurl", - "kml": "application/vnd.google-earth.kml+xml", - "kmz": "application/vnd.google-earth.kmz", - "xls": "application/vnd.ms-excel", - "eot": "application/vnd.ms-fontobject", - "ppt": "application/vnd.ms-powerpoint", - "odg": "application/vnd.oasis.opendocument.graphics", - "odp": "application/vnd.oasis.opendocument.presentation", - "ods": "application/vnd.oasis.opendocument.spreadsheet", - "odt": "application/vnd.oasis.opendocument.text", - "wmlc": "application/vnd.wap.wmlc", - "7z": "application/x-7z-compressed", - "cco": "application/x-cocoa", - "jardiff": "application/x-java-archive-diff", - "jnlp": "application/x-java-jnlp-file", - "run": "application/x-makeself", - "pl": "application/x-perl", - "pm": "application/x-perl", - "prc": "application/x-pilot", - "pdb": "application/x-pilot", - "rar": "application/x-rar-compressed", - "rpm": "application/x-redhat-package-manager", - "sea": "application/x-sea", - "swf": "application/x-shockwave-flash", - "sit": "application/x-stuffit", - "tcl": "application/x-tcl", - "tk": "application/x-tcl", - "der": "application/x-x509-ca-cert", - "pem": "application/x-x509-ca-cert", - "crt": "application/x-x509-ca-cert", - "xpi": "application/x-xpinstall", - "xhtml": "application/xhtml+xml", - "xspf": "application/xspf+xml", - "zip": "application/zip", - "bin": "application/octet-stream", - "exe": "application/octet-stream", - "dll": "application/octet-stream", - "deb": "application/octet-stream", - "dmg": "application/octet-stream", - "iso": "application/octet-stream", - "img": "application/octet-stream", - "msi": "application/octet-stream", - "msp": "application/octet-stream", - "msm": "application/octet-stream", - "mid": "audio/midi", - "midi": "audio/midi", - "kar": "audio/midi", - "mp3": "audio/mpeg", - "ogg": "audio/ogg", - "m4a": "audio/x-m4a", - "ra": "audio/x-realaudio", - "3gpp": "video/3gpp", - "3gp": "video/3gpp", - "ts": "video/mp2t", - "mp4": "video/mp4", - "mpeg": "video/mpeg", - "mpg": "video/mpeg", - "mov": "video/quicktime", - "webm": "video/webm", - "flv": "video/x-flv", - "m4v": "video/x-m4v", - "mng": "video/x-mng", - "asx": "video/x-ms-asf", - "asf": "video/x-ms-asf", - "wmv": "video/x-ms-wmv", - "avi": "video/x-msvideo", -} - -// HTTP Headers -const ( - // Authentication - HeaderAuthorization = "Authorization" - HeaderProxyAuthenticate = "Proxy-Authenticate" - HeaderProxyAuthorization = "Proxy-Authorization" - HeaderWWWAuthenticate = "WWW-Authenticate" - - // Caching - HeaderAge = "Age" - HeaderCacheControl = "Cache-Control" - HeaderClearSiteData = "Clear-Site-Data" - HeaderExpires = "Expires" - HeaderPragma = "Pragma" - HeaderWarning = "Warning" - - // Client hints - HeaderAcceptCH = "Accept-CH" - HeaderAcceptCHLifetime = "Accept-CH-Lifetime" - HeaderContentDPR = "Content-DPR" - HeaderDPR = "DPR" - HeaderEarlyData = "Early-Data" - HeaderSaveData = "Save-Data" - HeaderViewportWidth = "Viewport-Width" - HeaderWidth = "Width" - - // Conditionals - HeaderETag = "ETag" - HeaderIfMatch = "If-Match" - HeaderIfModifiedSince = "If-Modified-Since" - HeaderIfNoneMatch = "If-None-Match" - HeaderIfUnmodifiedSince = "If-Unmodified-Since" - HeaderLastModified = "Last-Modified" - HeaderVary = "Vary" - - // Connection management - HeaderConnection = "Connection" - HeaderKeepAlive = "Keep-Alive" - - // Content negotiation - HeaderAccept = "Accept" - HeaderAcceptCharset = "Accept-Charset" - HeaderAcceptEncoding = "Accept-Encoding" - HeaderAcceptLanguage = "Accept-Language" - - // Controls - HeaderCookie = "Cookie" - HeaderExpect = "Expect" - HeaderMaxForwards = "Max-Forwards" - HeaderSetCookie = "Set-Cookie" - - // CORS - HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" - HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" - HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" - HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" - HeaderAccessControlMaxAge = "Access-Control-Max-Age" - HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" - HeaderAccessControlRequestMethod = "Access-Control-Request-Method" - HeaderOrigin = "Origin" - HeaderTimingAllowOrigin = "Timing-Allow-Origin" - HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" - - // Do Not Track - HeaderDNT = "DNT" - HeaderTk = "Tk" - - // Downloads - HeaderContentDisposition = "Content-Disposition" - - // Message body information - HeaderContentEncoding = "Content-Encoding" - HeaderContentLanguage = "Content-Language" - HeaderContentLength = "Content-Length" - HeaderContentLocation = "Content-Location" - HeaderContentType = "Content-Type" - - // Proxies - HeaderForwarded = "Forwarded" - HeaderVia = "Via" - HeaderXForwardedFor = "X-Forwarded-For" - HeaderXForwardedHost = "X-Forwarded-Host" - HeaderXForwardedProto = "X-Forwarded-Proto" - - // Redirects - HeaderLocation = "Location" - - // Request context - HeaderFrom = "From" - HeaderHost = "Host" - HeaderReferer = "Referer" - HeaderReferrerPolicy = "Referrer-Policy" - HeaderUserAgent = "User-Agent" - - // Response context - HeaderAllow = "Allow" - HeaderServer = "Server" - - // Range requests - HeaderAcceptRanges = "Accept-Ranges" - HeaderContentRange = "Content-Range" - HeaderIfRange = "If-Range" - HeaderRange = "Range" - - // Security - HeaderContentSecurityPolicy = "Content-Security-Policy" - HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" - HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" - HeaderExpectCT = "Expect-CT" - HeaderFeaturePolicy = "Feature-Policy" - HeaderPublicKeyPins = "Public-Key-Pins" - HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" - HeaderStrictTransportSecurity = "Strict-Transport-Security" - HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" - HeaderXContentTypeOptions = "X-Content-Type-Options" - HeaderXDownloadOptions = "X-Download-Options" - HeaderXFrameOptions = "X-Frame-Options" - HeaderXPoweredBy = "X-Powered-By" - HeaderXXSSProtection = "X-XSS-Protection" - - // Server-sent event - HeaderLastEventID = "Last-Event-ID" - HeaderNEL = "NEL" - HeaderPingFrom = "Ping-From" - HeaderPingTo = "Ping-To" - HeaderReportTo = "Report-To" - - // Transfer coding - HeaderTE = "TE" - HeaderTrailer = "Trailer" - HeaderTransferEncoding = "Transfer-Encoding" - - // WebSockets - HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" - HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" - HeaderSecWebSocketKey = "Sec-WebSocket-Key" - HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" - HeaderSecWebSocketVersion = "Sec-WebSocket-Version" - - // Other - HeaderAcceptPatch = "Accept-Patch" - HeaderAcceptPushPolicy = "Accept-Push-Policy" - HeaderAcceptSignature = "Accept-Signature" - HeaderAltSvc = "Alt-Svc" - HeaderDate = "Date" - HeaderIndex = "Index" - HeaderLargeAllocation = "Large-Allocation" - HeaderLink = "Link" - HeaderPushPolicy = "Push-Policy" - HeaderRetryAfter = "Retry-After" - HeaderServerTiming = "Server-Timing" - HeaderSignature = "Signature" - HeaderSignedHeaders = "Signed-Headers" - HeaderSourceMap = "SourceMap" - HeaderUpgrade = "Upgrade" - HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" - HeaderXPingback = "X-Pingback" - HeaderXRequestID = "X-Request-ID" - HeaderXRequestedWith = "X-Requested-With" - HeaderXRobotsTag = "X-Robots-Tag" - HeaderXUACompatible = "X-UA-Compatible" -) - -const ( - StatusContinue = 100 // RFC 7231, 6.2.1 - StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 - StatusProcessing = 102 // RFC 2518, 10.1 - - StatusOK = 200 // RFC 7231, 6.3.1 - StatusCreated = 201 // RFC 7231, 6.3.2 - StatusAccepted = 202 // RFC 7231, 6.3.3 - StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 - StatusNoContent = 204 // RFC 7231, 6.3.5 - StatusResetContent = 205 // RFC 7231, 6.3.6 - StatusPartialContent = 206 // RFC 7233, 4.1 - StatusMultiStatus = 207 // RFC 4918, 11.1 - StatusAlreadyReported = 208 // RFC 5842, 7.1 - StatusIMUsed = 226 // RFC 3229, 10.4.1 - - StatusMultipleChoices = 300 // RFC 7231, 6.4.1 - StatusMovedPermanently = 301 // RFC 7231, 6.4.2 - StatusFound = 302 // RFC 7231, 6.4.3 - StatusSeeOther = 303 // RFC 7231, 6.4.4 - StatusNotModified = 304 // RFC 7232, 4.1 - StatusUseProxy = 305 // RFC 7231, 6.4.5 - - StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 - StatusPermanentRedirect = 308 // RFC 7538, 3 - - StatusBadRequest = 400 // RFC 7231, 6.5.1 - StatusUnauthorized = 401 // RFC 7235, 3.1 - StatusPaymentRequired = 402 // RFC 7231, 6.5.2 - StatusForbidden = 403 // RFC 7231, 6.5.3 - StatusNotFound = 404 // RFC 7231, 6.5.4 - StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 - StatusNotAcceptable = 406 // RFC 7231, 6.5.6 - StatusProxyAuthRequired = 407 // RFC 7235, 3.2 - StatusRequestTimeout = 408 // RFC 7231, 6.5.7 - StatusConflict = 409 // RFC 7231, 6.5.8 - StatusGone = 410 // RFC 7231, 6.5.9 - StatusLengthRequired = 411 // RFC 7231, 6.5.10 - StatusPreconditionFailed = 412 // RFC 7232, 4.2 - StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 - StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 - StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 - StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 - StatusExpectationFailed = 417 // RFC 7231, 6.5.14 - StatusTeapot = 418 // RFC 7168, 2.3.3 - StatusUnprocessableEntity = 422 // RFC 4918, 11.2 - StatusLocked = 423 // RFC 4918, 11.3 - StatusFailedDependency = 424 // RFC 4918, 11.4 - StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 - StatusPreconditionRequired = 428 // RFC 6585, 3 - StatusTooManyRequests = 429 // RFC 6585, 4 - StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 - StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 - - StatusInternalServerError = 500 // RFC 7231, 6.6.1 - StatusNotImplemented = 501 // RFC 7231, 6.6.2 - StatusBadGateway = 502 // RFC 7231, 6.6.3 - StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 - StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 - StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 - StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 - StatusInsufficientStorage = 507 // RFC 4918, 11.5 - StatusLoopDetected = 508 // RFC 5842, 7.2 - StatusNotExtended = 510 // RFC 2774, 7 - StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 -) From c5436a751927430144929b8b3af157a1cd8de381 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:49:46 +0100 Subject: [PATCH 02/15] Fix some consts --- app.go | 18 +++++++++--------- group.go | 20 +++++++++----------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app.go b/app.go index 5a925f69..0366beff 100644 --- a/app.go +++ b/app.go @@ -175,55 +175,55 @@ func (app *App) Use(args ...interface{}) *App { // Connect : https://fiber.wiki/application#http-methods func (app *App) Connect(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodConnect, path, handlers...) + app.registerMethod(MethodConnect, path, handlers...) return app } // Put : https://fiber.wiki/application#http-methods func (app *App) Put(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodPut, path, handlers...) + app.registerMethod(MethodPut, path, handlers...) return app } // Post : https://fiber.wiki/application#http-methods func (app *App) Post(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodPost, path, handlers...) + app.registerMethod(MethodPost, path, handlers...) return app } // Delete : https://fiber.wiki/application#http-methods func (app *App) Delete(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodDelete, path, handlers...) + app.registerMethod(MethodDelete, path, handlers...) return app } // Head : https://fiber.wiki/application#http-methods func (app *App) Head(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodHead, path, handlers...) + app.registerMethod(MethodHead, path, handlers...) return app } // Patch : https://fiber.wiki/application#http-methods func (app *App) Patch(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodPatch, path, handlers...) + app.registerMethod(MethodPatch, path, handlers...) return app } // Options : https://fiber.wiki/application#http-methods func (app *App) Options(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodOptions, path, handlers...) + app.registerMethod(MethodOptions, path, handlers...) return app } // Trace : https://fiber.wiki/application#http-methods func (app *App) Trace(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodTrace, path, handlers...) + app.registerMethod(MethodTrace, path, handlers...) return app } // Get : https://fiber.wiki/application#http-methods func (app *App) Get(path string, handlers ...func(*Ctx)) *App { - app.registerMethod(fasthttp.MethodGet, path, handlers...) + app.registerMethod(MethodGet, path, handlers...) return app } diff --git a/group.go b/group.go index 96e5e2a2..fd632e3d 100644 --- a/group.go +++ b/group.go @@ -6,8 +6,6 @@ package fiber import ( "log" - - fasthttp "github.com/valyala/fasthttp" ) // Group ... @@ -62,55 +60,55 @@ func (grp *Group) Use(args ...interface{}) *Group { // Connect : https://fiber.wiki/application#http-methods func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodConnect, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodConnect, groupPaths(grp.prefix, path), handlers...) return grp } // Put : https://fiber.wiki/application#http-methods func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodPut, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodPut, groupPaths(grp.prefix, path), handlers...) return grp } // Post : https://fiber.wiki/application#http-methods func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodPost, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodPost, groupPaths(grp.prefix, path), handlers...) return grp } // Delete : https://fiber.wiki/application#http-methods func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodDelete, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodDelete, groupPaths(grp.prefix, path), handlers...) return grp } // Head : https://fiber.wiki/application#http-methods func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodHead, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodHead, groupPaths(grp.prefix, path), handlers...) return grp } // Patch : https://fiber.wiki/application#http-methods func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodPatch, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodPatch, groupPaths(grp.prefix, path), handlers...) return grp } // Options : https://fiber.wiki/application#http-methods func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodOptions, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodOptions, groupPaths(grp.prefix, path), handlers...) return grp } // Trace : https://fiber.wiki/application#http-methods func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodTrace, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodTrace, groupPaths(grp.prefix, path), handlers...) return grp } // Get : https://fiber.wiki/application#http-methods func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(fasthttp.MethodGet, groupPaths(grp.prefix, path), handlers...) + grp.app.registerMethod(MethodGet, groupPaths(grp.prefix, path), handlers...) return grp } From e5208c62ff93c8e31764e3f591b7e0b0656e1753 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Fri, 20 Mar 2020 16:55:00 +0100 Subject: [PATCH 03/15] Fix travis --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c3865ad5..1327e8b1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,10 @@ os: - windows - osx go: - - go: 1.11.x - - go: 1.12.x - - go: 1.13.x - - go: 1.14.x + - 1.11.x + - 1.12.x + - 1.13.x + - 1.14.x env: - GO111MODULE=on install: From a3ba946b26550e9080fe71a60525d5495eefbd97 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sat, 21 Mar 2020 04:25:56 +0100 Subject: [PATCH 04/15] Update readme code examples --- .github/README.md | 65 +++++++------ .github/README_de.md | 171 ++++++++++++++++++++------------- .github/README_es.md | 171 ++++++++++++++++++++------------- .github/README_fr.md | 171 ++++++++++++++++++++------------- .github/README_id.md | 181 +++++++++++++++++++++-------------- .github/README_ja.md | 171 ++++++++++++++++++++------------- .github/README_ko.md | 171 ++++++++++++++++++++------------- .github/README_pt.md | 171 ++++++++++++++++++++------------- .github/README_ru.md | 203 +++++++++++++++++++++------------------- .github/README_tr.md | 171 ++++++++++++++++++++------------- .github/README_zh-CN.md | 171 ++++++++++++++++++++------------- 11 files changed, 1114 insertions(+), 703 deletions(-) diff --git a/.github/README.md b/.github/README.md index 1eaa464c..8209f81b 100644 --- a/.github/README.md +++ b/.github/README.md @@ -215,8 +215,8 @@ func main() { c.Next() }) - // POST /api/register - app.Post("/api/register", func(c *fiber.Ctx) { + // GET /api/register + app.Get("/api/list", func(c *fiber.Ctx) { fmt.Println("Last middleware") c.Send("Hello, World!") }) @@ -311,22 +311,22 @@ Example: ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) + // Logger with config + app.Use(logger.New(config)) - // ... + app.Listen(3000) } ``` @@ -336,25 +336,19 @@ Docs: - 📖 https://fiber.wiki/middleware#cors -> [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - Example: ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/cors" ) func main() { app := fiber.New() - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // CORS with default config + app.Use(cors.New()) app.Listen(3000) } @@ -432,38 +426,41 @@ func main() { } ``` -### WebSocket support +### WebSocket middleware Docs: -- 📖 https://fiber.wiki/application#websocket +- 📖 https://fiber.wiki/middleware#websocket Example: ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` @@ -478,20 +475,22 @@ Example: ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - })) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_de.md b/.github/README_de.md index 74918120..5a81d594 100644 --- a/.github/README_de.md +++ b/.github/README_de.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_es.md b/.github/README_es.md index a658c6ab..c30f0e11 100644 --- a/.github/README_es.md +++ b/.github/README_es.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_fr.md b/.github/README_fr.md index 37dacfa1..d0ef83c2 100644 --- a/.github/README_fr.md +++ b/.github/README_fr.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_id.md b/.github/README_id.md index 1b7363e9..b1751443 100644 --- a/.github/README_id.md +++ b/.github/README_id.md @@ -206,19 +206,25 @@ func main() { ```
- 📚 Perlihatkan contoh lainnya + 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render -Mendukung: +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render + +Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -245,8 +251,14 @@ func main() { } ``` -### Pengelompokan routes -https://fiber.wiki/application#group +### Grouping routes into chains + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -269,61 +281,72 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) adalah mekanisme yang menggunakan HTTP headers tambahan untuk memberitahu browser bahwa aplikasi/data kita hanya bisa diakses dari sumber (origin) tertentu, atau bisa juga diakses dari sumber berbeda. Aplikasi web memproses cross-origin HTTP request ketika request-nya berasal dari sumber berbeda (domain, protokol dan port). - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Setelah diaktifkan, bisa dicoba dengan cara memberi sumber/domain berbeda di header `Origin`: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 ``` -### Respon 404 +### Custom 404 response + +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: ```go func main() { @@ -341,15 +364,22 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) } ``` -### Respon JSON -https://fiber.wiki/context#json +### JSON Response + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -361,71 +391,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### Dukungan WebSocket -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_ja.md b/.github/README_ja.md index bf612cad..50fc4103 100644 --- a/.github/README_ja.md +++ b/.github/README_ja.md @@ -211,16 +211,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -248,7 +254,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -271,55 +283,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -327,6 +344,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -343,7 +366,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -351,7 +375,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -363,71 +393,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_ko.md b/.github/README_ko.md index 7a300be6..e1ec93e9 100644 --- a/.github/README_ko.md +++ b/.github/README_ko.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_pt.md b/.github/README_pt.md index 1ee27c1d..cb979b7e 100644 --- a/.github/README_pt.md +++ b/.github/README_pt.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_ru.md b/.github/README_ru.md index 53c92205..3128322b 100644 --- a/.github/README_ru.md +++ b/.github/README_ru.md @@ -224,16 +224,16 @@ func main() { ```
- 📚 Показать больше примеров кода + 📚 Show more code examples -### Работа с шаблонами +### Template engines -Документация: +Docs: - 📖 https://fiber.wiki/application#settings - 📖 https://fiber.wiki/context#render -Поддерживаемые движки шаблонов: +Supported engines: - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) @@ -241,138 +241,130 @@ func main() { - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) -Пример: +Example: ```go func main() { - // Вы можете настроить нужный движок для шаблонов - // перед инициализацией приложения: + // You can setup template engine before initiation app: app := fiber.New(&fiber.Settings{ TemplateEngine: "mustache", TemplateFolder: "./views", TemplateExtension: ".tmpl", }) - // ИЛИ уже после инициализации приложения, - // в любом удобном месте: + // OR after initiation app at any convenient location: app.Settings.TemplateEngine = "mustache" app.Settings.TemplateFolder = "./views" app.Settings.TemplateExtension = ".tmpl" - // Теперь, вы сможете вызывать шаблон `./views/home.tmpl` вот так: + // And now, you can call template `./views/home.tmpl` like this: app.Get("/", func(c *fiber.Ctx) { c.Render("home", fiber.Map{ "title": "Homepage", "year": 1999, }) }) - + // ... } ``` -### Группировка роутов в цепочки +### Grouping routes into chains -Документация: +Docs: - 📖 https://fiber.wiki/application#group -Пример: +Example: ```go func main() { app := fiber.New() - - // Корневой API роут + + // Root API route api := app.Group("/api", cors()) // /api - - // Роуты для API v1 + + // API v1 routes v1 := api.Group("/v1", mysql()) // /api/v1 v1.Get("/list", handler) // /api/v1/list v1.Get("/user", handler) // /api/v1/user - - // Роуты для API v2 + + // API v2 routes v2 := api.Group("/v2", mongodb()) // /api/v2 v2.Get("/list", handler) // /api/v2/list v2.Get("/user", handler) // /api/v2/user - + // ... } ``` -### Встроенный логгер +### Middleware logger -Документация: +Docs: - 📖 https://fiber.wiki/middleware#logger -Пример: +Example: ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // Если вы хотите изменить конфигурацию логгера по умолчанию - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware для логгера с кастомным конфигом - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) - -Документация: - -- 📖 https://fiber.wiki/middleware#cors - -> [CORS](https://developer.mozilla.org/ru/docs/Web/HTTP/CORS) — это механизм, использующий дополнительные HTTP-заголовки, чтобы дать возможность агенту пользователя получать разрешения на доступ к выбранным ресурсам с сервера на источнике (домене), отличном от того, что сайт использует в данный момент. - -Пример: - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Подключаем CORS для каждого роута в качестве middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Проверьте работу CORS, передав любой домен в заголовке `Origin`: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 ``` -### Обработка 404 ошибки +### Custom 404 response -Документация: +Docs: - 📖 https://fiber.wiki/application#http-methods -Пример: +Example: ```go func main() { @@ -390,102 +382,117 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) } ``` -### Ответ в формате JSON +### JSON Response -Документация: +Docs: - 📖 https://fiber.wiki/context#json -Пример: +Example: ```go +type User struct { + Name string `json:"name"` + Age int `json:"age"` +} + func main() { app := fiber.New() - type User struct { - Name string `json:"name"` - Age int `json:"age"` - } - - // Serialize JSON - app.Get("/json", func(c *fiber.Ctx) { + app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) // => {"name":"John", "age":20} }) + app.Get("/json", func(c *fiber.Ctx) { + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", + }) + // => {"success":true, "message":"Hi John!"} + }) + app.Listen(3000) } ``` -### Поддержка WebSocket +### WebSocket middleware -Документация: +Docs: -- 📖 https://fiber.wiki/application#websocket +- 📖 https://fiber.wiki/middleware#websocket -Пример: +Example: ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws/:name", func(c *fiber.Conn) { - log.Println(c.Params("name")) - + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Слушаем вебсокет по адресу ws://localhost:3000/ws/john app.Listen(3000) + // ws://localhost:3000/ws } ``` -### Восстановление работы после `panic` +### Recover middleware -Документация: +Docs: - 📖 https://fiber.wiki/middleware#recover -Пример: +Example: ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/recover" +) + func main() { app := fiber.New() - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } - app.Recover(func(c *fiber.Ctx) { - c.Status(500).Send(c.Error()) - // => 500 "Something went wrong!" - }) + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } ``` -
## 💬 Медиа diff --git a/.github/README_tr.md b/.github/README_tr.md index 1e54a5e5..adf13f58 100644 --- a/.github/README_tr.md +++ b/.github/README_tr.md @@ -207,16 +207,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -244,7 +250,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -267,55 +279,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -323,6 +340,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -339,7 +362,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -347,7 +371,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -359,71 +389,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } diff --git a/.github/README_zh-CN.md b/.github/README_zh-CN.md index 707b6c62..baad8084 100644 --- a/.github/README_zh-CN.md +++ b/.github/README_zh-CN.md @@ -206,16 +206,22 @@ func main() { 📚 Show more code examples ### Template engines -https://fiber.wiki/application#settings -https://fiber.wiki/context#render + +Docs: + +- 📖 https://fiber.wiki/application#settings +- 📖 https://fiber.wiki/context#render Supported engines: + - [html](https://golang.org/pkg/html/template/) - [amber](https://github.com/eknkc/amber) - [handlebars](https://github.com/aymerick/raymond) - [mustache](https://github.com/cbroglie/mustache) - [pug](https://github.com/Joker/jade) +Example: + ```go func main() { // You can setup template engine before initiation app: @@ -243,7 +249,13 @@ func main() { ``` ### Grouping routes into chains -https://fiber.wiki/application#group + +Docs: + +- 📖 https://fiber.wiki/application#group + +Example: + ```go func main() { app := fiber.New() @@ -266,55 +278,60 @@ func main() { ``` ### Middleware logger -https://fiber.wiki/middleware#logger + +Docs: + +- 📖 https://fiber.wiki/middleware#logger + +Example: + ```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/logger" ) func main() { app := fiber.New() - - // If you want to change default Logger config - loggerConfig := middleware.LoggerConfig{ + + // Optional logger config + config := logger.LoggerConfig{ Format: "${time} - ${method} ${path}\n", TimeFormat: "Mon, 2 Jan 2006 15:04:05 MST", } - // Middleware for Logger with config - app.Use(middleware.Logger(loggerConfig)) - - // ... -} -``` - -### Cross-Origin Resource Sharing (CORS) -https://fiber.wiki/middleware#cors - -[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) is a mechanism that uses additional HTTP headers to tell browsers to give a web application running at one origin, access to selected resources from a different origin. A web application executes a cross-origin HTTP request when it requests a resource that has a different origin (domain, protocol, or port) from its own. - -```go -import ( - "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" -) - -func main() { - app := fiber.New() - - // Connect CORS for each route as middleware - app.Use(middleware.CORS()) - - app.Get("/", func(c *fiber.Ctx) { - c.Send("CORS is enabled!") - }) + // Logger with config + app.Use(logger.New(config)) app.Listen(3000) } ``` -Check CORS by passing any domain in `Origin` header: +### Cross-Origin Resource Sharing (CORS) + +Docs: + +- 📖 https://fiber.wiki/middleware#cors + +Example: + +```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/cors" +) + +func main() { + app := fiber.New() + + // CORS with default config + app.Use(cors.New()) + + app.Listen(3000) +} +``` + +Check CORS by passing any domain in `Origin` header: ```bash curl -H "Origin: http://example.com" --verbose http://localhost:3000 @@ -322,6 +339,12 @@ curl -H "Origin: http://example.com" --verbose http://localhost:3000 ### Custom 404 response +Docs: + +- 📖 https://fiber.wiki/application#http-methods + +Example: + ```go func main() { app := fiber.New() @@ -338,7 +361,8 @@ func main() { // Last middleware to match anything app.Use(func(c *fiber.Ctx) { - c.SendStatus(404) // => 404 "Not Found" + c.SendStatus(404) + // => 404 "Not Found" }) app.Listen(3000) @@ -346,7 +370,13 @@ func main() { ``` ### JSON Response -https://fiber.wiki/context#json + +Docs: + +- 📖 https://fiber.wiki/context#json + +Example: + ```go type User struct { Name string `json:"name"` @@ -358,71 +388,86 @@ func main() { app.Get("/user", func(c *fiber.Ctx) { c.JSON(&User{"John", 20}) - // {"name":"John", "age":20} + // => {"name":"John", "age":20} }) app.Get("/json", func(c *fiber.Ctx) { - c.JSON(&fiber.Map{ - "success": true, - "message": "Hi John!", + c.JSON(fiber.Map{ + "success": true, + "message": "Hi John!", }) - // {"success":true, "message":"Hi John!"} + // => {"success":true, "message":"Hi John!"} }) app.Listen(3000) } ``` -### WebSocket support -https://fiber.wiki/application#websocket +### WebSocket middleware + +Docs: + +- 📖 https://fiber.wiki/middleware#websocket + +Example: + ```go +import ( + "github.com/gofiber/fiber" + "github.com/gofiber/websocket" +) + func main() { app := fiber.New() - app.WebSocket("/ws", func(c *fiber.Conn) { + app.Get("/ws", websocket.New(func(c *websocket.Conn) { for { mt, msg, err := c.ReadMessage() if err != nil { log.Println("read:", err) break } - - log.Printf("recovery: %s", msg) - + log.Printf("recv: %s", msg) err = c.WriteMessage(mt, msg) if err != nil { log.Println("write:", err) break } } - }) + })) - // Listen on ws://localhost:3000/ws app.Listen(3000) + // ws://localhost:3000/ws } ``` ### Recover middleware -https://fiber.wiki/middleware#recover -```go -package main +Docs: + +- 📖 https://fiber.wiki/middleware#recover + +Example: + +```go import ( "github.com/gofiber/fiber" - "github.com/gofiber/fiber/middleware" + "github.com/gofiber/recover" ) func main() { app := fiber.New() - app.Use(middleware.Recover(func(c *fiber.Ctx, err error) { - log.Println(err) // "Something went wrong!" - c.SendStatus(500) // Internal Server Error - }))) - - app.Get("/", func(c *fiber.Ctx) { - panic("Something went wrong!") - }) + // Optional recover config + config := recover.LoggerConfig{ + Handler: func(c *fiber.Ctx, err error) { + c.SendString(err.Error()) + c.SendStatus(500) + }, + } + + // Logger with custom config + app.Use(recover.New(config)) app.Listen(3000) } From f40d786caae8407b06750f9fc06196c4922ed687 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 01:51:53 +0100 Subject: [PATCH 05/15] v1.8.4 - Remove middleware folder - Extend travis testing --- .travis.yml | 15 +- app.go => application.go | 126 ++++++- app_test.go => application_test.go | 0 consts.go | 547 ----------------------------- context.go | 28 -- context_test.go | 1 - deprecated.go | 115 ------ go.mod | 3 - go.sum | 39 ++ group.go | 125 ------- middleware/basic_auth.go | 80 ----- middleware/cors.go | 174 --------- middleware/helmet.go | 109 ------ middleware/limiter.go | 143 -------- middleware/logger.go | 140 -------- middleware/recover.go | 34 -- middleware/request_id.go | 65 ---- router.go | 31 +- utils.go | 542 ++++++++++++++++++++++++++++ 19 files changed, 714 insertions(+), 1603 deletions(-) rename app.go => application.go (74%) rename app_test.go => application_test.go (100%) delete mode 100644 consts.go delete mode 100644 deprecated.go create mode 100644 go.sum delete mode 100644 group.go delete mode 100644 middleware/basic_auth.go delete mode 100644 middleware/cors.go delete mode 100644 middleware/helmet.go delete mode 100644 middleware/limiter.go delete mode 100644 middleware/logger.go delete mode 100644 middleware/recover.go delete mode 100644 middleware/request_id.go diff --git a/.travis.yml b/.travis.yml index 1327e8b1..a6f74d85 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,18 +1,25 @@ language: go sudo: false - +dist: bionic os: - linux - windows - osx go: + - 1.9.x + - 1.10.x - 1.11.x - 1.12.x - 1.13.x - 1.14.x env: - GO111MODULE=on -install: - #- go get -v golang.org/x/lint/golint script: - - go test + # build test for supported platforms + - GOOS=linux go build + - GOOS=darwin go build + - GOOS=freebsd go build + - GOOS=windows go build + - GOARCH=386 go build + - go test -v + - go test -race -v diff --git a/app.go b/application.go similarity index 74% rename from app.go rename to application.go index 0366beff..7ec5e641 100644 --- a/app.go +++ b/application.go @@ -24,7 +24,7 @@ import ( ) // Version of Fiber -const Version = "1.8.33" +const Version = "1.8.4" type ( // App denotes the Fiber application. @@ -32,7 +32,6 @@ type ( server *fasthttp.Server // Fasthttp server settings routes []*Route // Route stack child bool // If current process is a child ( for prefork ) - recover func(*Ctx) // Deprecated, use middleware.Recover Settings *Settings // Fiber settings } // Map defines a generic map of type `map[string]interface{}`. @@ -49,8 +48,6 @@ type ( ServerHeader string `default:""` // Enables handler values to be immutable even if you return from handler Immutable bool `default:"false"` - // Deprecated v1.8.2 - Compression bool `default:"false"` // Max body size that the server accepts BodyLimit int `default:"4 * 1024 * 1024"` // Folder containing template files @@ -62,6 +59,12 @@ type ( } ) +// Group struct +type Group struct { + prefix string + app *App +} + // This method creates a new Fiber named instance. // You can pass optional settings when creating a new instance. // @@ -98,11 +101,6 @@ func New(settings ...*Settings) *App { getBytes = func(s string) []byte { return []byte(s) } } } - // This function is deprecated since v1.8.2! - // Please us github.com/gofiber/compression - if app.Settings.Compression { - log.Println("Warning: Settings.Compression is deprecated since v1.8.2, please use github.com/gofiber/compression instead.") - } return app } @@ -239,6 +237,116 @@ func (app *App) All(path string, handlers ...func(*Ctx)) *App { return app } +// Group : https://fiber.wiki/application#group +func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group { + prefix = groupPaths(grp.prefix, prefix) + if len(handlers) > 0 { + grp.app.registerMethod("USE", prefix, handlers...) + } + return &Group{ + prefix: prefix, + app: grp.app, + } +} + +// Static : https://fiber.wiki/application#static +func (grp *Group) Static(prefix, root string, config ...Static) *Group { + prefix = groupPaths(grp.prefix, prefix) + grp.app.registerStatic(prefix, root, config...) + return grp +} + +// Use only match requests starting with the specified prefix +// It's optional to provide a prefix, default: "/" +// Example: Use("/product", handler) +// will match /product +// will match /product/cool +// will match /product/foo +// +// https://fiber.wiki/application#http-methods +func (grp *Group) Use(args ...interface{}) *Group { + var path = "" + var handlers []func(*Ctx) + for i := 0; i < len(args); i++ { + switch arg := args[i].(type) { + case string: + path = arg + case func(*Ctx): + handlers = append(handlers, arg) + default: + log.Fatalf("Invalid Use() arguments, must be (prefix, handler) or (handler)") + } + } + grp.app.registerMethod("USE", groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Connect : https://fiber.wiki/application#http-methods +func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodConnect, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Put : https://fiber.wiki/application#http-methods +func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodPut, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Post : https://fiber.wiki/application#http-methods +func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodPost, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Delete : https://fiber.wiki/application#http-methods +func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodDelete, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Head : https://fiber.wiki/application#http-methods +func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodHead, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Patch : https://fiber.wiki/application#http-methods +func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodPatch, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Options : https://fiber.wiki/application#http-methods +func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodOptions, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Trace : https://fiber.wiki/application#http-methods +func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodTrace, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// Get : https://fiber.wiki/application#http-methods +func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod(MethodGet, groupPaths(grp.prefix, path), handlers...) + return grp +} + +// All matches all HTTP methods and complete paths +// Example: All("/product", handler) +// will match /product +// won't match /product/cool <-- important +// won't match /product/foo <-- important +// +// https://fiber.wiki/application#http-methods +func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group { + grp.app.registerMethod("ALL", groupPaths(grp.prefix, path), handlers...) + return grp +} + // Listen : https://fiber.wiki/application#listen func (app *App) Listen(address interface{}, tlsconfig ...*tls.Config) error { addr, ok := address.(string) diff --git a/app_test.go b/application_test.go similarity index 100% rename from app_test.go rename to application_test.go diff --git a/consts.go b/consts.go deleted file mode 100644 index c8b58113..00000000 --- a/consts.go +++ /dev/null @@ -1,547 +0,0 @@ -// 🚀 Fiber is an Express inspired web framework written in Go with 💖 -// 📌 API Documentation: https://fiber.wiki -// 📝 Github Repository: https://github.com/gofiber/fiber - -package fiber - -// HTTP status codes were copied from net/http. -var statusMessages = map[int]string{ - 100: "Continue", - 101: "Switching Protocols", - 102: "Processing", - 200: "OK", - 201: "Created", - 202: "Accepted", - 203: "Non-Authoritative Information", - 204: "No Content", - 205: "Reset Content", - 206: "Partial Content", - 207: "Multi-Status", - 208: "Already Reported", - 226: "IM Used", - 300: "Multiple Choices", - 301: "Moved Permanently", - 302: "Found", - 303: "See Other", - 304: "Not Modified", - 305: "Use Proxy", - 306: "Switch Proxy", - 307: "Temporary Redirect", - 308: "Permanent Redirect", - 400: "Bad Request", - 401: "Unauthorized", - 402: "Payment Required", - 403: "Forbidden", - 404: "Not Found", - 405: "Method Not Allowed", - 406: "Not Acceptable", - 407: "Proxy Authentication Required", - 408: "Request Timeout", - 409: "Conflict", - 410: "Gone", - 411: "Length Required", - 412: "Precondition Failed", - 413: "Request Entity Too Large", - 414: "Request URI Too Long", - 415: "Unsupported Media Type", - 416: "Requested Range Not Satisfiable", - 417: "Expectation Failed", - 418: "I'm a teapot", - 422: "Unprocessable Entity", - 423: "Locked", - 424: "Failed Dependency", - 426: "Upgrade Required", - 428: "Precondition Required", - 429: "Too Many Requests", - 431: "Request Header Fields Too Large", - 451: "Unavailable For Legal Reasons", - 500: "Internal Server Error", - 501: "Not Implemented", - 502: "Bad Gateway", - 503: "Service Unavailable", - 504: "Gateway Timeout", - 505: "HTTP Version Not Supported", - 506: "Variant Also Negotiates", - 507: "Insufficient Storage", - 508: "Loop Detected", - 510: "Not Extended", - 511: "Network Authentication Required", -} - -// MIME types were copied from labstack/echo -const ( - MIMETextXML = "text/xml" - MIMETextHTML = "text/html" - MIMETextPlain = "text/plain" - - MIMEApplicationJSON = "application/json" - MIMEApplicationJavaScript = "application/javascript" - MIMEApplicationXML = "application/xml" - MIMEApplicationForm = "application/x-www-form-urlencoded" - - MIMEMultipartForm = "multipart/form-data" - - MIMEOctetStream = "application/octet-stream" -) - -// MIME types were copied from nginx/mime.types. -var extensionMIME = map[string]string{ - // without dot - "html": "text/html", - "htm": "text/html", - "shtml": "text/html", - "css": "text/css", - "gif": "image/gif", - "jpeg": "image/jpeg", - "jpg": "image/jpeg", - "xml": "application/xml", - "js": "application/javascript", - "atom": "application/atom+xml", - "rss": "application/rss+xml", - "mml": "text/mathml", - "txt": "text/plain", - "jad": "text/vnd.sun.j2me.app-descriptor", - "wml": "text/vnd.wap.wml", - "htc": "text/x-component", - "png": "image/png", - "svg": "image/svg+xml", - "svgz": "image/svg+xml", - "tif": "image/tiff", - "tiff": "image/tiff", - "wbmp": "image/vnd.wap.wbmp", - "webp": "image/webp", - "ico": "image/x-icon", - "jng": "image/x-jng", - "bmp": "image/x-ms-bmp", - "woff": "font/woff", - "woff2": "font/woff2", - "jar": "application/java-archive", - "war": "application/java-archive", - "ear": "application/java-archive", - "json": "application/json", - "hqx": "application/mac-binhex40", - "doc": "application/msword", - "pdf": "application/pdf", - "ps": "application/postscript", - "eps": "application/postscript", - "ai": "application/postscript", - "rtf": "application/rtf", - "m3u8": "application/vnd.apple.mpegurl", - "kml": "application/vnd.google-earth.kml+xml", - "kmz": "application/vnd.google-earth.kmz", - "xls": "application/vnd.ms-excel", - "eot": "application/vnd.ms-fontobject", - "ppt": "application/vnd.ms-powerpoint", - "odg": "application/vnd.oasis.opendocument.graphics", - "odp": "application/vnd.oasis.opendocument.presentation", - "ods": "application/vnd.oasis.opendocument.spreadsheet", - "odt": "application/vnd.oasis.opendocument.text", - "wmlc": "application/vnd.wap.wmlc", - "7z": "application/x-7z-compressed", - "cco": "application/x-cocoa", - "jardiff": "application/x-java-archive-diff", - "jnlp": "application/x-java-jnlp-file", - "run": "application/x-makeself", - "pl": "application/x-perl", - "pm": "application/x-perl", - "prc": "application/x-pilot", - "pdb": "application/x-pilot", - "rar": "application/x-rar-compressed", - "rpm": "application/x-redhat-package-manager", - "sea": "application/x-sea", - "swf": "application/x-shockwave-flash", - "sit": "application/x-stuffit", - "tcl": "application/x-tcl", - "tk": "application/x-tcl", - "der": "application/x-x509-ca-cert", - "pem": "application/x-x509-ca-cert", - "crt": "application/x-x509-ca-cert", - "xpi": "application/x-xpinstall", - "xhtml": "application/xhtml+xml", - "xspf": "application/xspf+xml", - "zip": "application/zip", - "bin": "application/octet-stream", - "exe": "application/octet-stream", - "dll": "application/octet-stream", - "deb": "application/octet-stream", - "dmg": "application/octet-stream", - "iso": "application/octet-stream", - "img": "application/octet-stream", - "msi": "application/octet-stream", - "msp": "application/octet-stream", - "msm": "application/octet-stream", - "mid": "audio/midi", - "midi": "audio/midi", - "kar": "audio/midi", - "mp3": "audio/mpeg", - "ogg": "audio/ogg", - "m4a": "audio/x-m4a", - "ra": "audio/x-realaudio", - "3gpp": "video/3gpp", - "3gp": "video/3gpp", - "ts": "video/mp2t", - "mp4": "video/mp4", - "mpeg": "video/mpeg", - "mpg": "video/mpeg", - "mov": "video/quicktime", - "webm": "video/webm", - "flv": "video/x-flv", - "m4v": "video/x-m4v", - "mng": "video/x-mng", - "asx": "video/x-ms-asf", - "asf": "video/x-ms-asf", - "wmv": "video/x-ms-wmv", - "avi": "video/x-msvideo", - - // with dot - ".html": "text/html", - ".htm": "text/html", - ".shtml": "text/html", - ".css": "text/css", - ".gif": "image/gif", - ".jpeg": "image/jpeg", - ".jpg": "image/jpeg", - ".xml": "application/xml", - ".js": "application/javascript", - ".atom": "application/atom+xml", - ".rss": "application/rss+xml", - ".mml": "text/mathml", - ".txt": "text/plain", - ".jad": "text/vnd.sun.j2me.app-descriptor", - ".wml": "text/vnd.wap.wml", - ".htc": "text/x-component", - ".png": "image/png", - ".svg": "image/svg+xml", - ".svgz": "image/svg+xml", - ".tif": "image/tiff", - ".tiff": "image/tiff", - ".wbmp": "image/vnd.wap.wbmp", - ".webp": "image/webp", - ".ico": "image/x-icon", - ".jng": "image/x-jng", - ".bmp": "image/x-ms-bmp", - ".woff": "font/woff", - ".woff2": "font/woff2", - ".jar": "application/java-archive", - ".war": "application/java-archive", - ".ear": "application/java-archive", - ".json": "application/json", - ".hqx": "application/mac-binhex40", - ".doc": "application/msword", - ".pdf": "application/pdf", - ".ps": "application/postscript", - ".eps": "application/postscript", - ".ai": "application/postscript", - ".rtf": "application/rtf", - ".m3u8": "application/vnd.apple.mpegurl", - ".kml": "application/vnd.google-earth.kml+xml", - ".kmz": "application/vnd.google-earth.kmz", - ".xls": "application/vnd.ms-excel", - ".eot": "application/vnd.ms-fontobject", - ".ppt": "application/vnd.ms-powerpoint", - ".odg": "application/vnd.oasis.opendocument.graphics", - ".odp": "application/vnd.oasis.opendocument.presentation", - ".ods": "application/vnd.oasis.opendocument.spreadsheet", - ".odt": "application/vnd.oasis.opendocument.text", - ".wmlc": "application/vnd.wap.wmlc", - ".7z": "application/x-7z-compressed", - ".cco": "application/x-cocoa", - ".jardiff": "application/x-java-archive-diff", - ".jnlp": "application/x-java-jnlp-file", - ".run": "application/x-makeself", - ".pl": "application/x-perl", - ".pm": "application/x-perl", - ".prc": "application/x-pilot", - ".pdb": "application/x-pilot", - ".rar": "application/x-rar-compressed", - ".rpm": "application/x-redhat-package-manager", - ".sea": "application/x-sea", - ".swf": "application/x-shockwave-flash", - ".sit": "application/x-stuffit", - ".tcl": "application/x-tcl", - ".tk": "application/x-tcl", - ".der": "application/x-x509-ca-cert", - ".pem": "application/x-x509-ca-cert", - ".crt": "application/x-x509-ca-cert", - ".xpi": "application/x-xpinstall", - ".xhtml": "application/xhtml+xml", - ".xspf": "application/xspf+xml", - ".zip": "application/zip", - ".bin": "application/octet-stream", - ".exe": "application/octet-stream", - ".dll": "application/octet-stream", - ".deb": "application/octet-stream", - ".dmg": "application/octet-stream", - ".iso": "application/octet-stream", - ".img": "application/octet-stream", - ".msi": "application/octet-stream", - ".msp": "application/octet-stream", - ".msm": "application/octet-stream", - ".mid": "audio/midi", - ".midi": "audio/midi", - ".kar": "audio/midi", - ".mp3": "audio/mpeg", - ".ogg": "audio/ogg", - ".m4a": "audio/x-m4a", - ".ra": "audio/x-realaudio", - ".3gpp": "video/3gpp", - ".3gp": "video/3gpp", - ".ts": "video/mp2t", - ".mp4": "video/mp4", - ".mpeg": "video/mpeg", - ".mpg": "video/mpeg", - ".mov": "video/quicktime", - ".webm": "video/webm", - ".flv": "video/x-flv", - ".m4v": "video/x-m4v", - ".mng": "video/x-mng", - ".asx": "video/x-ms-asf", - ".asf": "video/x-ms-asf", - ".wmv": "video/x-ms-wmv", - ".avi": "video/x-msvideo", -} - -// HTTP methods were copied from net/http. -const ( - MethodGet = "GET" // RFC 7231, 4.3.1 - MethodHead = "HEAD" // RFC 7231, 4.3.2 - MethodPost = "POST" // RFC 7231, 4.3.3 - MethodPut = "PUT" // RFC 7231, 4.3.4 - MethodPatch = "PATCH" // RFC 5789 - MethodDelete = "DELETE" // RFC 7231, 4.3.5 - MethodConnect = "CONNECT" // RFC 7231, 4.3.6 - MethodOptions = "OPTIONS" // RFC 7231, 4.3.7 - MethodTrace = "TRACE" // RFC 7231, 4.3.8 -) - -// HTTP Headers were copied from net/http. -const ( - // Authentication - HeaderAuthorization = "Authorization" - HeaderProxyAuthenticate = "Proxy-Authenticate" - HeaderProxyAuthorization = "Proxy-Authorization" - HeaderWWWAuthenticate = "WWW-Authenticate" - - // Caching - HeaderAge = "Age" - HeaderCacheControl = "Cache-Control" - HeaderClearSiteData = "Clear-Site-Data" - HeaderExpires = "Expires" - HeaderPragma = "Pragma" - HeaderWarning = "Warning" - - // Client hints - HeaderAcceptCH = "Accept-CH" - HeaderAcceptCHLifetime = "Accept-CH-Lifetime" - HeaderContentDPR = "Content-DPR" - HeaderDPR = "DPR" - HeaderEarlyData = "Early-Data" - HeaderSaveData = "Save-Data" - HeaderViewportWidth = "Viewport-Width" - HeaderWidth = "Width" - - // Conditionals - HeaderETag = "ETag" - HeaderIfMatch = "If-Match" - HeaderIfModifiedSince = "If-Modified-Since" - HeaderIfNoneMatch = "If-None-Match" - HeaderIfUnmodifiedSince = "If-Unmodified-Since" - HeaderLastModified = "Last-Modified" - HeaderVary = "Vary" - - // Connection management - HeaderConnection = "Connection" - HeaderKeepAlive = "Keep-Alive" - - // Content negotiation - HeaderAccept = "Accept" - HeaderAcceptCharset = "Accept-Charset" - HeaderAcceptEncoding = "Accept-Encoding" - HeaderAcceptLanguage = "Accept-Language" - - // Controls - HeaderCookie = "Cookie" - HeaderExpect = "Expect" - HeaderMaxForwards = "Max-Forwards" - HeaderSetCookie = "Set-Cookie" - - // CORS - HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" - HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" - HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" - HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" - HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" - HeaderAccessControlMaxAge = "Access-Control-Max-Age" - HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" - HeaderAccessControlRequestMethod = "Access-Control-Request-Method" - HeaderOrigin = "Origin" - HeaderTimingAllowOrigin = "Timing-Allow-Origin" - HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" - - // Do Not Track - HeaderDNT = "DNT" - HeaderTk = "Tk" - - // Downloads - HeaderContentDisposition = "Content-Disposition" - - // Message body information - HeaderContentEncoding = "Content-Encoding" - HeaderContentLanguage = "Content-Language" - HeaderContentLength = "Content-Length" - HeaderContentLocation = "Content-Location" - HeaderContentType = "Content-Type" - - // Proxies - HeaderForwarded = "Forwarded" - HeaderVia = "Via" - HeaderXForwardedFor = "X-Forwarded-For" - HeaderXForwardedHost = "X-Forwarded-Host" - HeaderXForwardedProto = "X-Forwarded-Proto" - - // Redirects - HeaderLocation = "Location" - - // Request context - HeaderFrom = "From" - HeaderHost = "Host" - HeaderReferer = "Referer" - HeaderReferrerPolicy = "Referrer-Policy" - HeaderUserAgent = "User-Agent" - - // Response context - HeaderAllow = "Allow" - HeaderServer = "Server" - - // Range requests - HeaderAcceptRanges = "Accept-Ranges" - HeaderContentRange = "Content-Range" - HeaderIfRange = "If-Range" - HeaderRange = "Range" - - // Security - HeaderContentSecurityPolicy = "Content-Security-Policy" - HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" - HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" - HeaderExpectCT = "Expect-CT" - HeaderFeaturePolicy = "Feature-Policy" - HeaderPublicKeyPins = "Public-Key-Pins" - HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" - HeaderStrictTransportSecurity = "Strict-Transport-Security" - HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" - HeaderXContentTypeOptions = "X-Content-Type-Options" - HeaderXDownloadOptions = "X-Download-Options" - HeaderXFrameOptions = "X-Frame-Options" - HeaderXPoweredBy = "X-Powered-By" - HeaderXXSSProtection = "X-XSS-Protection" - - // Server-sent event - HeaderLastEventID = "Last-Event-ID" - HeaderNEL = "NEL" - HeaderPingFrom = "Ping-From" - HeaderPingTo = "Ping-To" - HeaderReportTo = "Report-To" - - // Transfer coding - HeaderTE = "TE" - HeaderTrailer = "Trailer" - HeaderTransferEncoding = "Transfer-Encoding" - - // WebSockets - HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" - HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" - HeaderSecWebSocketKey = "Sec-WebSocket-Key" - HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" - HeaderSecWebSocketVersion = "Sec-WebSocket-Version" - - // Other - HeaderAcceptPatch = "Accept-Patch" - HeaderAcceptPushPolicy = "Accept-Push-Policy" - HeaderAcceptSignature = "Accept-Signature" - HeaderAltSvc = "Alt-Svc" - HeaderDate = "Date" - HeaderIndex = "Index" - HeaderLargeAllocation = "Large-Allocation" - HeaderLink = "Link" - HeaderPushPolicy = "Push-Policy" - HeaderRetryAfter = "Retry-After" - HeaderServerTiming = "Server-Timing" - HeaderSignature = "Signature" - HeaderSignedHeaders = "Signed-Headers" - HeaderSourceMap = "SourceMap" - HeaderUpgrade = "Upgrade" - HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" - HeaderXPingback = "X-Pingback" - HeaderXRequestID = "X-Request-ID" - HeaderXRequestedWith = "X-Requested-With" - HeaderXRobotsTag = "X-Robots-Tag" - HeaderXUACompatible = "X-UA-Compatible" -) - -// HTTP status codes were copied from net/http. -const ( - StatusContinue = 100 // RFC 7231, 6.2.1 - StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 - StatusProcessing = 102 // RFC 2518, 10.1 - - StatusOK = 200 // RFC 7231, 6.3.1 - StatusCreated = 201 // RFC 7231, 6.3.2 - StatusAccepted = 202 // RFC 7231, 6.3.3 - StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 - StatusNoContent = 204 // RFC 7231, 6.3.5 - StatusResetContent = 205 // RFC 7231, 6.3.6 - StatusPartialContent = 206 // RFC 7233, 4.1 - StatusMultiStatus = 207 // RFC 4918, 11.1 - StatusAlreadyReported = 208 // RFC 5842, 7.1 - StatusIMUsed = 226 // RFC 3229, 10.4.1 - - StatusMultipleChoices = 300 // RFC 7231, 6.4.1 - StatusMovedPermanently = 301 // RFC 7231, 6.4.2 - StatusFound = 302 // RFC 7231, 6.4.3 - StatusSeeOther = 303 // RFC 7231, 6.4.4 - StatusNotModified = 304 // RFC 7232, 4.1 - StatusUseProxy = 305 // RFC 7231, 6.4.5 - - StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 - StatusPermanentRedirect = 308 // RFC 7538, 3 - - StatusBadRequest = 400 // RFC 7231, 6.5.1 - StatusUnauthorized = 401 // RFC 7235, 3.1 - StatusPaymentRequired = 402 // RFC 7231, 6.5.2 - StatusForbidden = 403 // RFC 7231, 6.5.3 - StatusNotFound = 404 // RFC 7231, 6.5.4 - StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 - StatusNotAcceptable = 406 // RFC 7231, 6.5.6 - StatusProxyAuthRequired = 407 // RFC 7235, 3.2 - StatusRequestTimeout = 408 // RFC 7231, 6.5.7 - StatusConflict = 409 // RFC 7231, 6.5.8 - StatusGone = 410 // RFC 7231, 6.5.9 - StatusLengthRequired = 411 // RFC 7231, 6.5.10 - StatusPreconditionFailed = 412 // RFC 7232, 4.2 - StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 - StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 - StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 - StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 - StatusExpectationFailed = 417 // RFC 7231, 6.5.14 - StatusTeapot = 418 // RFC 7168, 2.3.3 - StatusUnprocessableEntity = 422 // RFC 4918, 11.2 - StatusLocked = 423 // RFC 4918, 11.3 - StatusFailedDependency = 424 // RFC 4918, 11.4 - StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 - StatusPreconditionRequired = 428 // RFC 6585, 3 - StatusTooManyRequests = 429 // RFC 6585, 4 - StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 - StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 - - StatusInternalServerError = 500 // RFC 7231, 6.6.1 - StatusNotImplemented = 501 // RFC 7231, 6.6.2 - StatusBadGateway = 502 // RFC 7231, 6.6.3 - StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 - StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 - StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 - StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 - StatusInsufficientStorage = 507 // RFC 4918, 11.5 - StatusLoopDetected = 508 // RFC 5842, 7.2 - StatusNotExtended = 510 // RFC 2774, 7 - StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 -) diff --git a/context.go b/context.go index d7621715..16d0b245 100644 --- a/context.go +++ b/context.go @@ -18,7 +18,6 @@ import ( "sync" "time" - websocket "github.com/fasthttp/websocket" template "github.com/gofiber/template" jsoniter "github.com/json-iterator/go" fasthttp "github.com/valyala/fasthttp" @@ -34,7 +33,6 @@ type Ctx struct { method string // HTTP method path string // HTTP path values []string // Route parameter values - compress bool // If the response needs to be compressed Fasthttp *fasthttp.RequestCtx // Reference to *fasthttp.RequestCtx err error // Contains error if catched } @@ -81,37 +79,11 @@ func acquireCtx(fctx *fasthttp.RequestCtx) *Ctx { func releaseCtx(ctx *Ctx) { ctx.route = nil ctx.values = nil - ctx.compress = false ctx.Fasthttp = nil ctx.err = nil poolCtx.Put(ctx) } -// Conn https://godoc.org/github.com/gorilla/websocket#pkg-index -type Conn struct { - *websocket.Conn -} - -// Conn pool -var poolConn = sync.Pool{ - New: func() interface{} { - return new(Conn) - }, -} - -// Acquire Conn from pool -func acquireConn(fconn *websocket.Conn) *Conn { - conn := poolConn.Get().(*Conn) - conn.Conn = fconn - return conn -} - -// Return Conn to pool -func releaseConn(conn *Conn) { - conn.Conn = nil - poolConn.Put(conn) -} - // Checks, if the specified extensions or content types are acceptable. // // https://fiber.wiki/context#accepts diff --git a/context_test.go b/context_test.go index 08c2af34..51f2cc42 100644 --- a/context_test.go +++ b/context_test.go @@ -28,7 +28,6 @@ func Test_Accepts(t *testing.T) { } expect = ".xml" result = c.Accepts(expect) - t.Log(result) if result != expect { t.Fatalf(`Expecting %s, got %s`, expect, result) } diff --git a/deprecated.go b/deprecated.go deleted file mode 100644 index 0a291e02..00000000 --- a/deprecated.go +++ /dev/null @@ -1,115 +0,0 @@ -// 🚀 Fiber is an Express inspired web framework written in Go with 💖 -// 📌 API Documentation: https://fiber.wiki -// 📝 Github Repository: https://github.com/gofiber/fiber - -package fiber - -import ( - "log" - "regexp" - "strings" - - websocket "github.com/fasthttp/websocket" - fasthttp "github.com/valyala/fasthttp" -) - -// These variables are deprecated since v1.8.2! -var compressResponse = fasthttp.CompressHandlerLevel(func(c *fasthttp.RequestCtx) {}, fasthttp.CompressDefaultCompression) -var websocketUpgrader = websocket.FastHTTPUpgrader{ - ReadBufferSize: 1024, - WriteBufferSize: 1024, - CheckOrigin: func(fctx *fasthttp.RequestCtx) bool { - return true - }, -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/compression -func (ctx *Ctx) Compress(enable ...bool) { - log.Println("Warning: c.Compress() is deprecated since v1.8.2, please use github.com/gofiber/compression instead.") - ctx.compress = true - if len(enable) > 0 { - ctx.compress = enable[0] - } -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/websocket -func (app *App) WebSocket(path string, handle func(*Ctx)) *App { - log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") - app.registerWebSocket(fasthttp.MethodGet, path, handle) - return app -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/websocket -func (grp *Group) WebSocket(path string, handle func(*Ctx)) *Group { - log.Println("Warning: app.WebSocket() is deprecated since v1.8.2, please use github.com/gofiber/websocket instead.") - grp.app.registerWebSocket(fasthttp.MethodGet, groupPaths(grp.prefix, path), handle) - return grp -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/recover -func (app *App) Recover(handler func(*Ctx)) { - log.Println("Warning: app.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") - app.recover = handler -} - -// This function is deprecated since v1.8.2! -// Please us github.com/gofiber/recover -func (grp *Group) Recover(handler func(*Ctx)) { - log.Println("Warning: Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover instead.") - grp.app.recover = handler -} - -func (app *App) registerWebSocket(method, path string, handle func(*Ctx)) { - // Cannot have an empty path - if path == "" { - path = "/" - } - // Path always start with a '/' or '*' - if path[0] != '/' && path[0] != '*' { - path = "/" + path - } - // Store original path to strip case sensitive params - original := path - // Case sensitive routing, all to lowercase - if !app.Settings.CaseSensitive { - path = strings.ToLower(path) - } - // Strict routing, remove last `/` - if !app.Settings.StrictRouting && len(path) > 1 { - path = strings.TrimRight(path, "/") - } - - var isWebSocket = true - - var isStar = path == "*" || path == "/*" - var isSlash = path == "/" - var isRegex = false - // Route properties - var Params = getParams(original) - var Regexp *regexp.Regexp - // Params requires regex pattern - if len(Params) > 0 { - regex, err := getRegex(path) - if err != nil { - log.Fatal("Router: Invalid path pattern: " + path) - } - isRegex = true - Regexp = regex - } - app.routes = append(app.routes, &Route{ - isWebSocket: isWebSocket, - isStar: isStar, - isSlash: isSlash, - isRegex: isRegex, - - Method: method, - Path: path, - Params: Params, - Regexp: Regexp, - HandleCtx: handle, - }) -} diff --git a/go.mod b/go.mod index 7c2bf8f2..f0f1706b 100644 --- a/go.mod +++ b/go.mod @@ -3,11 +3,8 @@ module github.com/gofiber/fiber go 1.11 require ( - github.com/fasthttp/websocket v1.4.2 github.com/gofiber/template v1.0.0 - github.com/google/uuid v1.1.1 github.com/gorilla/schema v1.1.0 github.com/json-iterator/go v1.1.9 github.com/valyala/fasthttp v1.9.0 - github.com/valyala/fasttemplate v1.1.0 ) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..532502b4 --- /dev/null +++ b/go.sum @@ -0,0 +1,39 @@ +github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a/go.mod h1:MzD2WMdSxvbHw5fM/OXOFily/lipJWRc9C1px0Mt0ZE= +github.com/Joker/jade v1.0.0 h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc= +github.com/Joker/jade v1.0.0/go.mod h1:efZIdO0py/LtcJRSa/j2WEklMSAw84WV0zZVMxNToB8= +github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0= +github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= +github.com/cbroglie/mustache v1.0.1 h1:ivMg8MguXq/rrz2eu3tw6g3b16+PQhoTn6EZAhst2mw= +github.com/cbroglie/mustache v1.0.1/go.mod h1:R/RUa+SobQ14qkP4jtx5Vke5sDytONDQXNLPY/PO69g= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= +github.com/gofiber/template v1.0.0 h1:Vf4Fby9zUWVQyY2y69KKyRHsEYlIE+Pxb25M+jiaEL0= +github.com/gofiber/template v1.0.0/go.mod h1:+bij+R0NI6urTg2jtQvPj5wb2uWMxW9eYGsAN3QhnP0= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY= +github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= +github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/klauspost/compress v1.8.2 h1:Bx0qjetmNjdFXASH02NSAREKpiaDwkO1DRZ3dV2KCcs= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/cpuid v1.2.1 h1:vJi+O/nMdFt0vqm8NZBI6wzALWdA2X+egi0ogNyrC/w= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742 h1:Esafd1046DLDQ0W1YjYsBW+p8U2u7vzgW2SQVmlNazg= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrMw= +github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/group.go b/group.go deleted file mode 100644 index fd632e3d..00000000 --- a/group.go +++ /dev/null @@ -1,125 +0,0 @@ -// 🚀 Fiber is an Express inspired web framework written in Go with 💖 -// 📌 API Documentation: https://fiber.wiki -// 📝 Github Repository: https://github.com/gofiber/fiber - -package fiber - -import ( - "log" -) - -// Group ... -type Group struct { - prefix string - app *App -} - -// Group : https://fiber.wiki/application#group -func (grp *Group) Group(prefix string, handlers ...func(*Ctx)) *Group { - prefix = groupPaths(grp.prefix, prefix) - if len(handlers) > 0 { - grp.app.registerMethod("USE", prefix, handlers...) - } - return &Group{ - prefix: prefix, - app: grp.app, - } -} - -// Static : https://fiber.wiki/application#static -func (grp *Group) Static(prefix, root string, config ...Static) *Group { - prefix = groupPaths(grp.prefix, prefix) - grp.app.registerStatic(prefix, root, config...) - return grp -} - -// Use only match requests starting with the specified prefix -// It's optional to provide a prefix, default: "/" -// Example: Use("/product", handler) -// will match /product -// will match /product/cool -// will match /product/foo -// -// https://fiber.wiki/application#http-methods -func (grp *Group) Use(args ...interface{}) *Group { - var path = "" - var handlers []func(*Ctx) - for i := 0; i < len(args); i++ { - switch arg := args[i].(type) { - case string: - path = arg - case func(*Ctx): - handlers = append(handlers, arg) - default: - log.Fatalf("Invalid Use() arguments, must be (prefix, handler) or (handler)") - } - } - grp.app.registerMethod("USE", groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Connect : https://fiber.wiki/application#http-methods -func (grp *Group) Connect(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodConnect, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Put : https://fiber.wiki/application#http-methods -func (grp *Group) Put(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodPut, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Post : https://fiber.wiki/application#http-methods -func (grp *Group) Post(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodPost, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Delete : https://fiber.wiki/application#http-methods -func (grp *Group) Delete(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodDelete, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Head : https://fiber.wiki/application#http-methods -func (grp *Group) Head(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodHead, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Patch : https://fiber.wiki/application#http-methods -func (grp *Group) Patch(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodPatch, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Options : https://fiber.wiki/application#http-methods -func (grp *Group) Options(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodOptions, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Trace : https://fiber.wiki/application#http-methods -func (grp *Group) Trace(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodTrace, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// Get : https://fiber.wiki/application#http-methods -func (grp *Group) Get(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod(MethodGet, groupPaths(grp.prefix, path), handlers...) - return grp -} - -// All matches all HTTP methods and complete paths -// Example: All("/product", handler) -// will match /product -// won't match /product/cool <-- important -// won't match /product/foo <-- important -// -// https://fiber.wiki/application#http-methods -func (grp *Group) All(path string, handlers ...func(*Ctx)) *Group { - grp.app.registerMethod("ALL", groupPaths(grp.prefix, path), handlers...) - return grp -} diff --git a/middleware/basic_auth.go b/middleware/basic_auth.go deleted file mode 100644 index a60fce59..00000000 --- a/middleware/basic_auth.go +++ /dev/null @@ -1,80 +0,0 @@ -package middleware - -import ( - "encoding/base64" - "log" - "strings" - - "github.com/gofiber/fiber" -) - -// BasicAuthConfig defines the config for BasicAuth middleware -type BasicAuthConfig struct { - // Skip defines a function to skip middleware. - // Optional. Default: nil - Skip func(*fiber.Ctx) bool - // Users defines the allowed credentials - // Required. Default: map[string]string{} - Users map[string]string - // Realm is a string to define realm attribute of BasicAuth. - // Optional. Default: "Restricted". - Realm string -} - -// BasicAuthConfigDefault is the default BasicAuth middleware config. -var BasicAuthConfigDefault = BasicAuthConfig{ - Skip: nil, - Users: map[string]string{}, - Realm: "Restricted", -} - -// BasicAuth ... -func BasicAuth(config ...BasicAuthConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.BasicAuth() is deprecated since v1.8.2, please use github.com/gofiber/basicauth") - // Init config - var cfg BasicAuthConfig - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if cfg.Users == nil { - cfg.Users = BasicAuthConfigDefault.Users - } - if cfg.Realm == "" { - cfg.Realm = BasicAuthConfigDefault.Realm - } - // Return middleware handler - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - // Get authorization header - auth := c.Get(fiber.HeaderAuthorization) - // Check if characters are provided - if len(auth) > 6 && strings.ToLower(auth[:5]) == "basic" { - // Try to decode - if raw, err := base64.StdEncoding.DecodeString(auth[6:]); err == nil { - // Convert to string - cred := string(raw) - // Find semicolumn - for i := 0; i < len(cred); i++ { - if cred[i] == ':' { - // Split into user & pass - user := cred[:i] - pass := cred[i+1:] - // If exist & match in Users, we let him pass - if cfg.Users[user] == pass { - c.Next() - return - } - } - } - } - } - // Authentication required - c.Set(fiber.HeaderWWWAuthenticate, "basic realm="+cfg.Realm) - c.SendStatus(401) - } -} diff --git a/middleware/cors.go b/middleware/cors.go deleted file mode 100644 index 44779563..00000000 --- a/middleware/cors.go +++ /dev/null @@ -1,174 +0,0 @@ -package middleware - -import ( - "log" - "net/http" - "strconv" - "strings" - - "github.com/gofiber/fiber" -) - -// CORSConfig ... -type CORSConfig struct { - Skip func(*fiber.Ctx) bool - // Optional. Default value []string{"*"}. - AllowOrigins []string - // Optional. Default value []string{"GET","POST","HEAD","PUT","DELETE","PATCH"} - AllowMethods []string - // Optional. Default value []string{}. - AllowHeaders []string - // Optional. Default value false. - AllowCredentials bool - // Optional. Default value []string{}. - ExposeHeaders []string - // Optional. Default value 0. - MaxAge int -} - -// CorsConfigDefault is the defaul Cors middleware config. -var CorsConfigDefault = CORSConfig{ - Skip: nil, - AllowOrigins: []string{"*"}, - AllowMethods: []string{ - http.MethodGet, - http.MethodPost, - http.MethodHead, - http.MethodPut, - http.MethodDelete, - http.MethodPatch, - }, -} - -// Cors ... -func Cors(config ...CORSConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.Cors() is deprecated since v1.8.2, please use github.com/gofiber/cors") - // Init config - var cfg CORSConfig - // Set config if provided - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if len(cfg.AllowOrigins) == 0 { - cfg.AllowOrigins = CorsConfigDefault.AllowOrigins - } - if len(cfg.AllowMethods) == 0 { - cfg.AllowMethods = CorsConfigDefault.AllowMethods - } - // Middleware settings - allowMethods := strings.Join(cfg.AllowMethods, ",") - allowHeaders := strings.Join(cfg.AllowHeaders, ",") - exposeHeaders := strings.Join(cfg.ExposeHeaders, ",") - maxAge := strconv.Itoa(cfg.MaxAge) - // Middleware function - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - origin := c.Get(fiber.HeaderOrigin) - allowOrigin := "" - // Check allowed origins - for _, o := range cfg.AllowOrigins { - if o == "*" && cfg.AllowCredentials { - allowOrigin = origin - break - } - if o == "*" || o == origin { - allowOrigin = o - break - } - if matchSubdomain(origin, o) { - allowOrigin = origin - break - } - } - // Simple request - if c.Method() != http.MethodOptions { - c.Vary(fiber.HeaderOrigin) - c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin) - - if cfg.AllowCredentials { - c.Set(fiber.HeaderAccessControlAllowCredentials, "true") - } - if exposeHeaders != "" { - c.Set(fiber.HeaderAccessControlExposeHeaders, exposeHeaders) - } - c.Next() - return - } - // Preflight request - c.Vary(fiber.HeaderOrigin) - c.Vary(fiber.HeaderAccessControlRequestMethod) - c.Vary(fiber.HeaderAccessControlRequestHeaders) - c.Set(fiber.HeaderAccessControlAllowOrigin, allowOrigin) - c.Set(fiber.HeaderAccessControlAllowMethods, allowMethods) - - if cfg.AllowCredentials { - c.Set(fiber.HeaderAccessControlAllowCredentials, "true") - } - if allowHeaders != "" { - c.Set(fiber.HeaderAccessControlAllowHeaders, allowHeaders) - } else { - h := c.Get(fiber.HeaderAccessControlRequestHeaders) - if h != "" { - c.Set(fiber.HeaderAccessControlAllowHeaders, h) - } - } - if cfg.MaxAge > 0 { - c.Set(fiber.HeaderAccessControlMaxAge, maxAge) - } - c.SendStatus(204) // No Content - } -} - -func matchScheme(domain, pattern string) bool { - didx := strings.Index(domain, ":") - pidx := strings.Index(pattern, ":") - return didx != -1 && pidx != -1 && domain[:didx] == pattern[:pidx] -} - -// matchSubdomain compares authority with wildcard -func matchSubdomain(domain, pattern string) bool { - if !matchScheme(domain, pattern) { - return false - } - didx := strings.Index(domain, "://") - pidx := strings.Index(pattern, "://") - if didx == -1 || pidx == -1 { - return false - } - domAuth := domain[didx+3:] - // to avoid long loop by invalid long domain - if len(domAuth) > 253 { - return false - } - patAuth := pattern[pidx+3:] - - domComp := strings.Split(domAuth, ".") - patComp := strings.Split(patAuth, ".") - for i := len(domComp)/2 - 1; i >= 0; i-- { - opp := len(domComp) - 1 - i - domComp[i], domComp[opp] = domComp[opp], domComp[i] - } - for i := len(patComp)/2 - 1; i >= 0; i-- { - opp := len(patComp) - 1 - i - patComp[i], patComp[opp] = patComp[opp], patComp[i] - } - - for i, v := range domComp { - if len(patComp) <= i { - return false - } - p := patComp[i] - if p == "*" { - return true - } - if p != v { - return false - } - } - return false -} diff --git a/middleware/helmet.go b/middleware/helmet.go deleted file mode 100644 index b24c2467..00000000 --- a/middleware/helmet.go +++ /dev/null @@ -1,109 +0,0 @@ -package middleware - -import ( - "fmt" - "log" - - "github.com/gofiber/fiber" -) - -// HelmetConfig ... -type HelmetConfig struct { - // Skip defines a function to skip middleware. - // Optional. Default: nil - Skip func(*fiber.Ctx) bool - // XSSProtection - // Optional. Default value "1; mode=block". - XSSProtection string - // ContentTypeNosniff - // Optional. Default value "nosniff". - ContentTypeNosniff string - // XFrameOptions - // Optional. Default value "SAMEORIGIN". - // Possible values: "SAMEORIGIN", "DENY", "ALLOW-FROM uri" - XFrameOptions string - // HSTSMaxAge - // Optional. Default value 0. - HSTSMaxAge int - // HSTSExcludeSubdomains - // Optional. Default value false. - HSTSExcludeSubdomains bool - // ContentSecurityPolicy - // Optional. Default value "". - ContentSecurityPolicy string - // CSPReportOnly - // Optional. Default value false. - CSPReportOnly bool - // HSTSPreloadEnabled - // Optional. Default value false. - HSTSPreloadEnabled bool - // ReferrerPolicy - // Optional. Default value "". - ReferrerPolicy string -} - -// HelmetConfigDefault is the defaul Helmet middleware config. -var HelmetConfigDefault = HelmetConfig{ - Skip: nil, - XSSProtection: "1; mode=block", - ContentTypeNosniff: "nosniff", - XFrameOptions: "SAMEORIGIN", -} - -// Helmet ... -func Helmet(config ...HelmetConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.Helmet() is deprecated since v1.8.2, please use github.com/gofiber/helmet") - // Init config - var cfg HelmetConfig - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if cfg.XSSProtection == "" { - cfg.XSSProtection = HelmetConfigDefault.XSSProtection - } - if cfg.ContentTypeNosniff == "" { - cfg.ContentTypeNosniff = HelmetConfigDefault.ContentTypeNosniff - } - if cfg.XFrameOptions == "" { - cfg.XFrameOptions = HelmetConfigDefault.XFrameOptions - } - // Return middleware handler - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - if cfg.XSSProtection != "" { - c.Set(fiber.HeaderXXSSProtection, cfg.XSSProtection) - } - if cfg.ContentTypeNosniff != "" { - c.Set(fiber.HeaderXContentTypeOptions, cfg.ContentTypeNosniff) - } - if cfg.XFrameOptions != "" { - c.Set(fiber.HeaderXFrameOptions, cfg.XFrameOptions) - } - if (c.Secure() || (c.Get(fiber.HeaderXForwardedProto) == "https")) && cfg.HSTSMaxAge != 0 { - subdomains := "" - if !cfg.HSTSExcludeSubdomains { - subdomains = "; includeSubdomains" - } - if cfg.HSTSPreloadEnabled { - subdomains = fmt.Sprintf("%s; preload", subdomains) - } - c.Set(fiber.HeaderStrictTransportSecurity, fmt.Sprintf("max-age=%d%s", cfg.HSTSMaxAge, subdomains)) - } - if cfg.ContentSecurityPolicy != "" { - if cfg.CSPReportOnly { - c.Set(fiber.HeaderContentSecurityPolicyReportOnly, cfg.ContentSecurityPolicy) - } else { - c.Set(fiber.HeaderContentSecurityPolicy, cfg.ContentSecurityPolicy) - } - } - if cfg.ReferrerPolicy != "" { - c.Set(fiber.HeaderReferrerPolicy, cfg.ReferrerPolicy) - } - c.Next() - } -} diff --git a/middleware/limiter.go b/middleware/limiter.go deleted file mode 100644 index e2c2a7ca..00000000 --- a/middleware/limiter.go +++ /dev/null @@ -1,143 +0,0 @@ -package middleware - -import ( - "log" - "strconv" - "time" - - "github.com/gofiber/fiber" -) - -// LimiterConfig ... -type LimiterConfig struct { - Skip func(*fiber.Ctx) bool - // Timeout in seconds on how long to keep records of requests in memory - // Default: 60 - Timeout int - // Max number of recent connections during `Timeout` seconds before sending a 429 response - // Default: 10 - Max int - // Message - // default: "Too many requests, please try again later." - Message string - // StatusCode - // Default: 429 Too Many Requests - StatusCode int - // Key allows to use a custom handler to create custom keys - // Default: func(c *fiber.Ctx) string { - // return c.IP() - // } - Key func(*fiber.Ctx) string - // Handler is called when a request hits the limit - // Default: func(c *fiber.Ctx) { - // c.Status(cfg.StatusCode).SendString(cfg.Message) - // } - Handler func(*fiber.Ctx) -} - -// LimiterConfigDefault is the defaul Limiter middleware config. -var LimiterConfigDefault = LimiterConfig{ - Skip: nil, - Timeout: 60, - Max: 10, - Message: "Too many requests, please try again later.", - StatusCode: 429, - Key: func(c *fiber.Ctx) string { - return c.IP() - }, -} - -// Limiter ... -func Limiter(config ...LimiterConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.Limiter() is deprecated since v1.8.2, please use github.com/gofiber/limiter") - // Init config - var cfg LimiterConfig - // Set config if provided - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if cfg.Timeout == 0 { - cfg.Timeout = LimiterConfigDefault.Timeout - } - if cfg.Max == 0 { - cfg.Max = LimiterConfigDefault.Max - } - if cfg.Message == "" { - cfg.Message = LimiterConfigDefault.Message - } - if cfg.StatusCode == 0 { - cfg.StatusCode = LimiterConfigDefault.StatusCode - } - if cfg.Key == nil { - cfg.Key = LimiterConfigDefault.Key - } - if cfg.Handler == nil { - cfg.Handler = func(c *fiber.Ctx) { - c.Status(cfg.StatusCode).SendString(cfg.Message) - } - } - // Limiter settings - var hits = map[string]int{} - var reset = map[string]int{} - var timestamp = int(time.Now().Unix()) - // Update timestamp every second - go func() { - for { - timestamp = int(time.Now().Unix()) - time.Sleep(1 * time.Second) - } - }() - // Reset hits every cfg.Timeout - go func() { - for { - // For every key in reset - for key := range reset { - // If resetTime exist and current time is equal or bigger - if reset[key] != 0 && timestamp >= reset[key] { - // Reset hits and resetTime - hits[key] = 0 - reset[key] = 0 - } - } - // Wait cfg.Timeout - time.Sleep(time.Duration(cfg.Timeout) * time.Second) - } - }() - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - // Get key (default is the remote IP) - key := cfg.Key(c) - // Increment key hits - hits[key]++ - // Set unix timestamp if not exist - if reset[key] == 0 { - reset[key] = timestamp + cfg.Timeout - } - // Get current hits - hitCount := hits[key] - // Set how many hits we have left - remaining := cfg.Max - hitCount - // Calculate when it resets in seconds - resetTime := reset[key] - timestamp - // Check if hits exceed the cfg.Max - if remaining < 1 { - // Call Handler func - cfg.Handler(c) - // Return response with Retry-After header - // https://tools.ietf.org/html/rfc6584 - c.Set("Retry-After", strconv.Itoa(resetTime)) - return - } - // We can continue, update RateLimit headers - c.Set("X-RateLimit-Limit", strconv.Itoa(cfg.Max)) - c.Set("X-RateLimit-Remaining", strconv.Itoa(remaining)) - c.Set("X-RateLimit-Reset", strconv.Itoa(resetTime)) - // Bye! - c.Next() - } -} diff --git a/middleware/logger.go b/middleware/logger.go deleted file mode 100644 index 5d490186..00000000 --- a/middleware/logger.go +++ /dev/null @@ -1,140 +0,0 @@ -package middleware - -import ( - "bytes" - "fmt" - "io" - "log" - "os" - "strconv" - "strings" - "sync" - "time" - - "github.com/gofiber/fiber" - "github.com/valyala/fasttemplate" -) - -// LoggerConfig ... -type LoggerConfig struct { - // Skip defines a function to skip middleware. - // Optional. Default: nil - Skip func(*fiber.Ctx) bool - // Format defines the logging format with defined variables - // Optional. Default: "${time} - ${ip} - ${method} ${path}\t${ua}\n" - // Possible values: time, ip, url, host, method, path, protocol - // referer, ua, header:, query:, formform:, cookie: - Format string - // TimeFormat https://programming.guide/go/format-parse-string-time-date-example.html - // Optional. Default: 15:04:05 - TimeFormat string - // Output is a writter where logs are written - // Default: os.Stderr - Output io.Writer -} - -// LoggerConfigDefault is the defaul Logger middleware config. -var LoggerConfigDefault = LoggerConfig{ - Skip: nil, - Format: "${time} ${method} ${path} - ${ip} - ${status} - ${latency}\n", - TimeFormat: "15:04:05", - Output: os.Stderr, -} - -// Logger ... -func Logger(config ...LoggerConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.Logger() is deprecated since v1.8.2, please use github.com/gofiber/logger") - // Init config - var cfg LoggerConfig - // Set config if provided - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if cfg.Format == "" { - cfg.Format = LoggerConfigDefault.Format - } - if cfg.TimeFormat == "" { - cfg.TimeFormat = LoggerConfigDefault.TimeFormat - } - if cfg.Output == nil { - cfg.Output = LoggerConfigDefault.Output - } - // Middleware settings - tmpl := fasttemplate.New(cfg.Format, "${", "}") - pool := &sync.Pool{ - New: func() interface{} { - return bytes.NewBuffer(make([]byte, 256)) - }, - } - timestamp := time.Now().Format(cfg.TimeFormat) - // Update date/time every second in a seperate go routine - if strings.Contains(cfg.Format, "${time}") { - go func() { - for { - timestamp = time.Now().Format(cfg.TimeFormat) - time.Sleep(1 * time.Second) - } - }() - } - // Middleware function - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - start := time.Now() - // handle request - c.Next() - // build log - stop := time.Now() - buf := pool.Get().(*bytes.Buffer) - buf.Reset() - defer pool.Put(buf) - _, err := tmpl.ExecuteFunc(buf, func(w io.Writer, tag string) (int, error) { - switch tag { - case "time": - return buf.WriteString(timestamp) - case "referer": - return buf.WriteString(c.Get(fiber.HeaderReferer)) - case "protocol": - return buf.WriteString(c.Protocol()) - case "ip": - return buf.WriteString(c.IP()) - case "host": - return buf.WriteString(c.Hostname()) - case "method": - return buf.WriteString(c.Method()) - case "path": - return buf.WriteString(c.Path()) - case "url": - return buf.WriteString(c.OriginalURL()) - case "ua": - return buf.WriteString(c.Get(fiber.HeaderUserAgent)) - case "latency": - return buf.WriteString(stop.Sub(start).String()) - case "status": - return buf.WriteString(strconv.Itoa(c.Fasthttp.Response.StatusCode())) - default: - switch { - case strings.HasPrefix(tag, "header:"): - return buf.WriteString(c.Get(tag[7:])) - case strings.HasPrefix(tag, "query:"): - return buf.WriteString(c.Query(tag[6:])) - case strings.HasPrefix(tag, "form:"): - return buf.WriteString(c.FormValue(tag[5:])) - case strings.HasPrefix(tag, "cookie:"): - return buf.WriteString(c.Cookies(tag[7:])) - } - } - return 0, nil - }) - if err != nil { - buf.WriteString(err.Error()) - } - if _, err := cfg.Output.Write(buf.Bytes()); err != nil { - fmt.Println(err) - } - } -} diff --git a/middleware/recover.go b/middleware/recover.go deleted file mode 100644 index 269f0e1e..00000000 --- a/middleware/recover.go +++ /dev/null @@ -1,34 +0,0 @@ -package middleware - -import ( - "fmt" - "log" - - "github.com/gofiber/fiber" -) - -// Recover ... -func Recover(handle ...func(*fiber.Ctx, error)) func(*fiber.Ctx) { - log.Println("Warning: middleware.Recover() is deprecated since v1.8.2, please use github.com/gofiber/recover") - h := func(c *fiber.Ctx, err error) { - log.Println(err) - c.SendStatus(500) - } - // Init custom error handler if exist - if len(handle) > 0 { - h = handle[0] - } - // Return middleware handle - return func(c *fiber.Ctx) { - defer func() { - if r := recover(); r != nil { - err, ok := r.(error) - if !ok { - err = fmt.Errorf("%v", r) - } - h(c, err) - } - }() - c.Next() - } -} diff --git a/middleware/request_id.go b/middleware/request_id.go deleted file mode 100644 index e6069233..00000000 --- a/middleware/request_id.go +++ /dev/null @@ -1,65 +0,0 @@ -package middleware - -import ( - "fmt" - "log" - - "github.com/gofiber/fiber" - "github.com/google/uuid" -) - -// RequestIDConfig defines the config for RequestID middleware -type RequestIDConfig struct { - // Skip defines a function to skip middleware. - // Optional. Default: nil - Skip func(*fiber.Ctx) bool - // Generator defines a function to generate an ID. - // Optional. Default: func() string { - // return uuid.New().String() - // } - Generator func() string -} - -// RequestIDConfigDefault is the default RequestID middleware config. -var RequestIDConfigDefault = RequestIDConfig{ - Skip: nil, - Generator: func() string { - return uuid.New().String() - }, -} - -// RequestID adds an indentifier to the request using the `X-Request-ID` header -func RequestID(config ...RequestIDConfig) func(*fiber.Ctx) { - log.Println("Warning: middleware.RequestID() is deprecated since v1.8.2, please use github.com/gofiber/requestid") - // Init config - var cfg RequestIDConfig - if len(config) > 0 { - cfg = config[0] - } - // Set config default values - if cfg.Skip == nil { - cfg.Skip = RequestIDConfigDefault.Skip - } - if cfg.Generator == nil { - cfg.Generator = RequestIDConfigDefault.Generator - } - // Return middleware handler - return func(c *fiber.Ctx) { - // Skip middleware if Skip returns true - if cfg.Skip != nil && cfg.Skip(c) { - c.Next() - return - } - // Get value from RequestID - rid := c.Get(fiber.HeaderXRequestID) - fmt.Println(rid) - // Create new ID - if rid == "" { - rid = cfg.Generator() - } - // Set X-Request-ID - c.Set(fiber.HeaderXRequestID, rid) - // Bye! - c.Next() - } -} diff --git a/router.go b/router.go index b5bad1d2..2ff469b9 100644 --- a/router.go +++ b/router.go @@ -10,7 +10,6 @@ import ( "strings" "time" - websocket "github.com/fasthttp/websocket" fasthttp "github.com/valyala/fasthttp" ) @@ -19,7 +18,6 @@ type Route struct { isGet bool // allows HEAD requests if GET isMiddleware bool // is middleware route - isWebSocket bool // is websocket route isStar bool // path == '*' isSlash bool // path == '/' @@ -30,9 +28,7 @@ type Route struct { Params []string // path params Regexp *regexp.Regexp // regexp matcher - HandleCtx func(*Ctx) // ctx handler - HandleConn func(*Conn) // conn handler - + Handler func(*Ctx) // ctx handler } func (app *App) nextRoute(ctx *Ctx) { @@ -45,19 +41,7 @@ func (app *App) nextRoute(ctx *Ctx) { if match { ctx.route = route ctx.values = values - // Deprecated since v1.8.2 - // github.com/gofiber/websocket - if route.isWebSocket { - if err := websocketUpgrader.Upgrade(ctx.Fasthttp, func(fconn *websocket.Conn) { - conn := acquireConn(fconn) - defer releaseConn(conn) - route.HandleConn(conn) - }); err != nil { // Upgrading failed - ctx.SendStatus(400) - } - } else { - route.HandleCtx(ctx) - } + route.Handler(ctx) return } } @@ -123,7 +107,6 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) { defer releaseCtx(ctx) // attach app poiner and compress settings ctx.app = app - ctx.compress = app.Settings.Compression // Case sensitive routing if !app.Settings.CaseSensitive { @@ -133,12 +116,8 @@ func (app *App) handler(fctx *fasthttp.RequestCtx) { if !app.Settings.StrictRouting && len(ctx.path) > 1 { ctx.path = strings.TrimRight(ctx.path, "/") } - + // Find route app.nextRoute(ctx) - // Deprecated since v1.8.2 https://github.com/gofiber/compress - if ctx.compress { - compressResponse(fctx) - } } func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) { @@ -201,7 +180,7 @@ func (app *App) registerMethod(method, path string, handlers ...func(*Ctx)) { Path: path, Params: Params, Regexp: Regexp, - HandleCtx: handlers[i], + Handler: handlers[i], }) } } @@ -273,7 +252,7 @@ func (app *App) registerStatic(prefix, root string, config ...Static) { isSlash: isSlash, Method: "*", Path: prefix, - HandleCtx: func(c *Ctx) { + Handler: func(c *Ctx) { // Only handle GET & HEAD methods if c.method == "GET" || c.method == "HEAD" { // Do stuff diff --git a/utils.go b/utils.go index 273d1333..a2a4fb6f 100644 --- a/utils.go +++ b/utils.go @@ -133,3 +133,545 @@ func (c *testConn) Close() error { return nil } func (c *testConn) SetDeadline(t time.Time) error { return nil } func (c *testConn) SetReadDeadline(t time.Time) error { return nil } func (c *testConn) SetWriteDeadline(t time.Time) error { return nil } + +// HTTP status codes were copied from net/http. +var statusMessages = map[int]string{ + 100: "Continue", + 101: "Switching Protocols", + 102: "Processing", + 200: "OK", + 201: "Created", + 202: "Accepted", + 203: "Non-Authoritative Information", + 204: "No Content", + 205: "Reset Content", + 206: "Partial Content", + 207: "Multi-Status", + 208: "Already Reported", + 226: "IM Used", + 300: "Multiple Choices", + 301: "Moved Permanently", + 302: "Found", + 303: "See Other", + 304: "Not Modified", + 305: "Use Proxy", + 306: "Switch Proxy", + 307: "Temporary Redirect", + 308: "Permanent Redirect", + 400: "Bad Request", + 401: "Unauthorized", + 402: "Payment Required", + 403: "Forbidden", + 404: "Not Found", + 405: "Method Not Allowed", + 406: "Not Acceptable", + 407: "Proxy Authentication Required", + 408: "Request Timeout", + 409: "Conflict", + 410: "Gone", + 411: "Length Required", + 412: "Precondition Failed", + 413: "Request Entity Too Large", + 414: "Request URI Too Long", + 415: "Unsupported Media Type", + 416: "Requested Range Not Satisfiable", + 417: "Expectation Failed", + 418: "I'm a teapot", + 422: "Unprocessable Entity", + 423: "Locked", + 424: "Failed Dependency", + 426: "Upgrade Required", + 428: "Precondition Required", + 429: "Too Many Requests", + 431: "Request Header Fields Too Large", + 451: "Unavailable For Legal Reasons", + 500: "Internal Server Error", + 501: "Not Implemented", + 502: "Bad Gateway", + 503: "Service Unavailable", + 504: "Gateway Timeout", + 505: "HTTP Version Not Supported", + 506: "Variant Also Negotiates", + 507: "Insufficient Storage", + 508: "Loop Detected", + 510: "Not Extended", + 511: "Network Authentication Required", +} + +// MIME types were copied from labstack/echo +const ( + MIMETextXML = "text/xml" + MIMETextHTML = "text/html" + MIMETextPlain = "text/plain" + + MIMEApplicationJSON = "application/json" + MIMEApplicationJavaScript = "application/javascript" + MIMEApplicationXML = "application/xml" + MIMEApplicationForm = "application/x-www-form-urlencoded" + + MIMEMultipartForm = "multipart/form-data" + + MIMEOctetStream = "application/octet-stream" +) + +// MIME types were copied from nginx/mime.types. +var extensionMIME = map[string]string{ + // without dot + "html": "text/html", + "htm": "text/html", + "shtml": "text/html", + "css": "text/css", + "gif": "image/gif", + "jpeg": "image/jpeg", + "jpg": "image/jpeg", + "xml": "application/xml", + "js": "application/javascript", + "atom": "application/atom+xml", + "rss": "application/rss+xml", + "mml": "text/mathml", + "txt": "text/plain", + "jad": "text/vnd.sun.j2me.app-descriptor", + "wml": "text/vnd.wap.wml", + "htc": "text/x-component", + "png": "image/png", + "svg": "image/svg+xml", + "svgz": "image/svg+xml", + "tif": "image/tiff", + "tiff": "image/tiff", + "wbmp": "image/vnd.wap.wbmp", + "webp": "image/webp", + "ico": "image/x-icon", + "jng": "image/x-jng", + "bmp": "image/x-ms-bmp", + "woff": "font/woff", + "woff2": "font/woff2", + "jar": "application/java-archive", + "war": "application/java-archive", + "ear": "application/java-archive", + "json": "application/json", + "hqx": "application/mac-binhex40", + "doc": "application/msword", + "pdf": "application/pdf", + "ps": "application/postscript", + "eps": "application/postscript", + "ai": "application/postscript", + "rtf": "application/rtf", + "m3u8": "application/vnd.apple.mpegurl", + "kml": "application/vnd.google-earth.kml+xml", + "kmz": "application/vnd.google-earth.kmz", + "xls": "application/vnd.ms-excel", + "eot": "application/vnd.ms-fontobject", + "ppt": "application/vnd.ms-powerpoint", + "odg": "application/vnd.oasis.opendocument.graphics", + "odp": "application/vnd.oasis.opendocument.presentation", + "ods": "application/vnd.oasis.opendocument.spreadsheet", + "odt": "application/vnd.oasis.opendocument.text", + "wmlc": "application/vnd.wap.wmlc", + "7z": "application/x-7z-compressed", + "cco": "application/x-cocoa", + "jardiff": "application/x-java-archive-diff", + "jnlp": "application/x-java-jnlp-file", + "run": "application/x-makeself", + "pl": "application/x-perl", + "pm": "application/x-perl", + "prc": "application/x-pilot", + "pdb": "application/x-pilot", + "rar": "application/x-rar-compressed", + "rpm": "application/x-redhat-package-manager", + "sea": "application/x-sea", + "swf": "application/x-shockwave-flash", + "sit": "application/x-stuffit", + "tcl": "application/x-tcl", + "tk": "application/x-tcl", + "der": "application/x-x509-ca-cert", + "pem": "application/x-x509-ca-cert", + "crt": "application/x-x509-ca-cert", + "xpi": "application/x-xpinstall", + "xhtml": "application/xhtml+xml", + "xspf": "application/xspf+xml", + "zip": "application/zip", + "bin": "application/octet-stream", + "exe": "application/octet-stream", + "dll": "application/octet-stream", + "deb": "application/octet-stream", + "dmg": "application/octet-stream", + "iso": "application/octet-stream", + "img": "application/octet-stream", + "msi": "application/octet-stream", + "msp": "application/octet-stream", + "msm": "application/octet-stream", + "mid": "audio/midi", + "midi": "audio/midi", + "kar": "audio/midi", + "mp3": "audio/mpeg", + "ogg": "audio/ogg", + "m4a": "audio/x-m4a", + "ra": "audio/x-realaudio", + "3gpp": "video/3gpp", + "3gp": "video/3gpp", + "ts": "video/mp2t", + "mp4": "video/mp4", + "mpeg": "video/mpeg", + "mpg": "video/mpeg", + "mov": "video/quicktime", + "webm": "video/webm", + "flv": "video/x-flv", + "m4v": "video/x-m4v", + "mng": "video/x-mng", + "asx": "video/x-ms-asf", + "asf": "video/x-ms-asf", + "wmv": "video/x-ms-wmv", + "avi": "video/x-msvideo", + + // with dot + ".html": "text/html", + ".htm": "text/html", + ".shtml": "text/html", + ".css": "text/css", + ".gif": "image/gif", + ".jpeg": "image/jpeg", + ".jpg": "image/jpeg", + ".xml": "application/xml", + ".js": "application/javascript", + ".atom": "application/atom+xml", + ".rss": "application/rss+xml", + ".mml": "text/mathml", + ".txt": "text/plain", + ".jad": "text/vnd.sun.j2me.app-descriptor", + ".wml": "text/vnd.wap.wml", + ".htc": "text/x-component", + ".png": "image/png", + ".svg": "image/svg+xml", + ".svgz": "image/svg+xml", + ".tif": "image/tiff", + ".tiff": "image/tiff", + ".wbmp": "image/vnd.wap.wbmp", + ".webp": "image/webp", + ".ico": "image/x-icon", + ".jng": "image/x-jng", + ".bmp": "image/x-ms-bmp", + ".woff": "font/woff", + ".woff2": "font/woff2", + ".jar": "application/java-archive", + ".war": "application/java-archive", + ".ear": "application/java-archive", + ".json": "application/json", + ".hqx": "application/mac-binhex40", + ".doc": "application/msword", + ".pdf": "application/pdf", + ".ps": "application/postscript", + ".eps": "application/postscript", + ".ai": "application/postscript", + ".rtf": "application/rtf", + ".m3u8": "application/vnd.apple.mpegurl", + ".kml": "application/vnd.google-earth.kml+xml", + ".kmz": "application/vnd.google-earth.kmz", + ".xls": "application/vnd.ms-excel", + ".eot": "application/vnd.ms-fontobject", + ".ppt": "application/vnd.ms-powerpoint", + ".odg": "application/vnd.oasis.opendocument.graphics", + ".odp": "application/vnd.oasis.opendocument.presentation", + ".ods": "application/vnd.oasis.opendocument.spreadsheet", + ".odt": "application/vnd.oasis.opendocument.text", + ".wmlc": "application/vnd.wap.wmlc", + ".7z": "application/x-7z-compressed", + ".cco": "application/x-cocoa", + ".jardiff": "application/x-java-archive-diff", + ".jnlp": "application/x-java-jnlp-file", + ".run": "application/x-makeself", + ".pl": "application/x-perl", + ".pm": "application/x-perl", + ".prc": "application/x-pilot", + ".pdb": "application/x-pilot", + ".rar": "application/x-rar-compressed", + ".rpm": "application/x-redhat-package-manager", + ".sea": "application/x-sea", + ".swf": "application/x-shockwave-flash", + ".sit": "application/x-stuffit", + ".tcl": "application/x-tcl", + ".tk": "application/x-tcl", + ".der": "application/x-x509-ca-cert", + ".pem": "application/x-x509-ca-cert", + ".crt": "application/x-x509-ca-cert", + ".xpi": "application/x-xpinstall", + ".xhtml": "application/xhtml+xml", + ".xspf": "application/xspf+xml", + ".zip": "application/zip", + ".bin": "application/octet-stream", + ".exe": "application/octet-stream", + ".dll": "application/octet-stream", + ".deb": "application/octet-stream", + ".dmg": "application/octet-stream", + ".iso": "application/octet-stream", + ".img": "application/octet-stream", + ".msi": "application/octet-stream", + ".msp": "application/octet-stream", + ".msm": "application/octet-stream", + ".mid": "audio/midi", + ".midi": "audio/midi", + ".kar": "audio/midi", + ".mp3": "audio/mpeg", + ".ogg": "audio/ogg", + ".m4a": "audio/x-m4a", + ".ra": "audio/x-realaudio", + ".3gpp": "video/3gpp", + ".3gp": "video/3gpp", + ".ts": "video/mp2t", + ".mp4": "video/mp4", + ".mpeg": "video/mpeg", + ".mpg": "video/mpeg", + ".mov": "video/quicktime", + ".webm": "video/webm", + ".flv": "video/x-flv", + ".m4v": "video/x-m4v", + ".mng": "video/x-mng", + ".asx": "video/x-ms-asf", + ".asf": "video/x-ms-asf", + ".wmv": "video/x-ms-wmv", + ".avi": "video/x-msvideo", +} + +// HTTP methods were copied from net/http. +const ( + MethodGet = "GET" // RFC 7231, 4.3.1 + MethodHead = "HEAD" // RFC 7231, 4.3.2 + MethodPost = "POST" // RFC 7231, 4.3.3 + MethodPut = "PUT" // RFC 7231, 4.3.4 + MethodPatch = "PATCH" // RFC 5789 + MethodDelete = "DELETE" // RFC 7231, 4.3.5 + MethodConnect = "CONNECT" // RFC 7231, 4.3.6 + MethodOptions = "OPTIONS" // RFC 7231, 4.3.7 + MethodTrace = "TRACE" // RFC 7231, 4.3.8 +) + +// HTTP Headers were copied from net/http. +const ( + // Authentication + HeaderAuthorization = "Authorization" + HeaderProxyAuthenticate = "Proxy-Authenticate" + HeaderProxyAuthorization = "Proxy-Authorization" + HeaderWWWAuthenticate = "WWW-Authenticate" + + // Caching + HeaderAge = "Age" + HeaderCacheControl = "Cache-Control" + HeaderClearSiteData = "Clear-Site-Data" + HeaderExpires = "Expires" + HeaderPragma = "Pragma" + HeaderWarning = "Warning" + + // Client hints + HeaderAcceptCH = "Accept-CH" + HeaderAcceptCHLifetime = "Accept-CH-Lifetime" + HeaderContentDPR = "Content-DPR" + HeaderDPR = "DPR" + HeaderEarlyData = "Early-Data" + HeaderSaveData = "Save-Data" + HeaderViewportWidth = "Viewport-Width" + HeaderWidth = "Width" + + // Conditionals + HeaderETag = "ETag" + HeaderIfMatch = "If-Match" + HeaderIfModifiedSince = "If-Modified-Since" + HeaderIfNoneMatch = "If-None-Match" + HeaderIfUnmodifiedSince = "If-Unmodified-Since" + HeaderLastModified = "Last-Modified" + HeaderVary = "Vary" + + // Connection management + HeaderConnection = "Connection" + HeaderKeepAlive = "Keep-Alive" + + // Content negotiation + HeaderAccept = "Accept" + HeaderAcceptCharset = "Accept-Charset" + HeaderAcceptEncoding = "Accept-Encoding" + HeaderAcceptLanguage = "Accept-Language" + + // Controls + HeaderCookie = "Cookie" + HeaderExpect = "Expect" + HeaderMaxForwards = "Max-Forwards" + HeaderSetCookie = "Set-Cookie" + + // CORS + HeaderAccessControlAllowCredentials = "Access-Control-Allow-Credentials" + HeaderAccessControlAllowHeaders = "Access-Control-Allow-Headers" + HeaderAccessControlAllowMethods = "Access-Control-Allow-Methods" + HeaderAccessControlAllowOrigin = "Access-Control-Allow-Origin" + HeaderAccessControlExposeHeaders = "Access-Control-Expose-Headers" + HeaderAccessControlMaxAge = "Access-Control-Max-Age" + HeaderAccessControlRequestHeaders = "Access-Control-Request-Headers" + HeaderAccessControlRequestMethod = "Access-Control-Request-Method" + HeaderOrigin = "Origin" + HeaderTimingAllowOrigin = "Timing-Allow-Origin" + HeaderXPermittedCrossDomainPolicies = "X-Permitted-Cross-Domain-Policies" + + // Do Not Track + HeaderDNT = "DNT" + HeaderTk = "Tk" + + // Downloads + HeaderContentDisposition = "Content-Disposition" + + // Message body information + HeaderContentEncoding = "Content-Encoding" + HeaderContentLanguage = "Content-Language" + HeaderContentLength = "Content-Length" + HeaderContentLocation = "Content-Location" + HeaderContentType = "Content-Type" + + // Proxies + HeaderForwarded = "Forwarded" + HeaderVia = "Via" + HeaderXForwardedFor = "X-Forwarded-For" + HeaderXForwardedHost = "X-Forwarded-Host" + HeaderXForwardedProto = "X-Forwarded-Proto" + + // Redirects + HeaderLocation = "Location" + + // Request context + HeaderFrom = "From" + HeaderHost = "Host" + HeaderReferer = "Referer" + HeaderReferrerPolicy = "Referrer-Policy" + HeaderUserAgent = "User-Agent" + + // Response context + HeaderAllow = "Allow" + HeaderServer = "Server" + + // Range requests + HeaderAcceptRanges = "Accept-Ranges" + HeaderContentRange = "Content-Range" + HeaderIfRange = "If-Range" + HeaderRange = "Range" + + // Security + HeaderContentSecurityPolicy = "Content-Security-Policy" + HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only" + HeaderCrossOriginResourcePolicy = "Cross-Origin-Resource-Policy" + HeaderExpectCT = "Expect-CT" + HeaderFeaturePolicy = "Feature-Policy" + HeaderPublicKeyPins = "Public-Key-Pins" + HeaderPublicKeyPinsReportOnly = "Public-Key-Pins-Report-Only" + HeaderStrictTransportSecurity = "Strict-Transport-Security" + HeaderUpgradeInsecureRequests = "Upgrade-Insecure-Requests" + HeaderXContentTypeOptions = "X-Content-Type-Options" + HeaderXDownloadOptions = "X-Download-Options" + HeaderXFrameOptions = "X-Frame-Options" + HeaderXPoweredBy = "X-Powered-By" + HeaderXXSSProtection = "X-XSS-Protection" + + // Server-sent event + HeaderLastEventID = "Last-Event-ID" + HeaderNEL = "NEL" + HeaderPingFrom = "Ping-From" + HeaderPingTo = "Ping-To" + HeaderReportTo = "Report-To" + + // Transfer coding + HeaderTE = "TE" + HeaderTrailer = "Trailer" + HeaderTransferEncoding = "Transfer-Encoding" + + // WebSockets + HeaderSecWebSocketAccept = "Sec-WebSocket-Accept" + HeaderSecWebSocketExtensions = "Sec-WebSocket-Extensions" + HeaderSecWebSocketKey = "Sec-WebSocket-Key" + HeaderSecWebSocketProtocol = "Sec-WebSocket-Protocol" + HeaderSecWebSocketVersion = "Sec-WebSocket-Version" + + // Other + HeaderAcceptPatch = "Accept-Patch" + HeaderAcceptPushPolicy = "Accept-Push-Policy" + HeaderAcceptSignature = "Accept-Signature" + HeaderAltSvc = "Alt-Svc" + HeaderDate = "Date" + HeaderIndex = "Index" + HeaderLargeAllocation = "Large-Allocation" + HeaderLink = "Link" + HeaderPushPolicy = "Push-Policy" + HeaderRetryAfter = "Retry-After" + HeaderServerTiming = "Server-Timing" + HeaderSignature = "Signature" + HeaderSignedHeaders = "Signed-Headers" + HeaderSourceMap = "SourceMap" + HeaderUpgrade = "Upgrade" + HeaderXDNSPrefetchControl = "X-DNS-Prefetch-Control" + HeaderXPingback = "X-Pingback" + HeaderXRequestID = "X-Request-ID" + HeaderXRequestedWith = "X-Requested-With" + HeaderXRobotsTag = "X-Robots-Tag" + HeaderXUACompatible = "X-UA-Compatible" +) + +// HTTP status codes were copied from net/http. +const ( + StatusContinue = 100 // RFC 7231, 6.2.1 + StatusSwitchingProtocols = 101 // RFC 7231, 6.2.2 + StatusProcessing = 102 // RFC 2518, 10.1 + + StatusOK = 200 // RFC 7231, 6.3.1 + StatusCreated = 201 // RFC 7231, 6.3.2 + StatusAccepted = 202 // RFC 7231, 6.3.3 + StatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 + StatusNoContent = 204 // RFC 7231, 6.3.5 + StatusResetContent = 205 // RFC 7231, 6.3.6 + StatusPartialContent = 206 // RFC 7233, 4.1 + StatusMultiStatus = 207 // RFC 4918, 11.1 + StatusAlreadyReported = 208 // RFC 5842, 7.1 + StatusIMUsed = 226 // RFC 3229, 10.4.1 + + StatusMultipleChoices = 300 // RFC 7231, 6.4.1 + StatusMovedPermanently = 301 // RFC 7231, 6.4.2 + StatusFound = 302 // RFC 7231, 6.4.3 + StatusSeeOther = 303 // RFC 7231, 6.4.4 + StatusNotModified = 304 // RFC 7232, 4.1 + StatusUseProxy = 305 // RFC 7231, 6.4.5 + + StatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 + StatusPermanentRedirect = 308 // RFC 7538, 3 + + StatusBadRequest = 400 // RFC 7231, 6.5.1 + StatusUnauthorized = 401 // RFC 7235, 3.1 + StatusPaymentRequired = 402 // RFC 7231, 6.5.2 + StatusForbidden = 403 // RFC 7231, 6.5.3 + StatusNotFound = 404 // RFC 7231, 6.5.4 + StatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 + StatusNotAcceptable = 406 // RFC 7231, 6.5.6 + StatusProxyAuthRequired = 407 // RFC 7235, 3.2 + StatusRequestTimeout = 408 // RFC 7231, 6.5.7 + StatusConflict = 409 // RFC 7231, 6.5.8 + StatusGone = 410 // RFC 7231, 6.5.9 + StatusLengthRequired = 411 // RFC 7231, 6.5.10 + StatusPreconditionFailed = 412 // RFC 7232, 4.2 + StatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 + StatusRequestURITooLong = 414 // RFC 7231, 6.5.12 + StatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 + StatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 + StatusExpectationFailed = 417 // RFC 7231, 6.5.14 + StatusTeapot = 418 // RFC 7168, 2.3.3 + StatusUnprocessableEntity = 422 // RFC 4918, 11.2 + StatusLocked = 423 // RFC 4918, 11.3 + StatusFailedDependency = 424 // RFC 4918, 11.4 + StatusUpgradeRequired = 426 // RFC 7231, 6.5.15 + StatusPreconditionRequired = 428 // RFC 6585, 3 + StatusTooManyRequests = 429 // RFC 6585, 4 + StatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 + StatusUnavailableForLegalReasons = 451 // RFC 7725, 3 + + StatusInternalServerError = 500 // RFC 7231, 6.6.1 + StatusNotImplemented = 501 // RFC 7231, 6.6.2 + StatusBadGateway = 502 // RFC 7231, 6.6.3 + StatusServiceUnavailable = 503 // RFC 7231, 6.6.4 + StatusGatewayTimeout = 504 // RFC 7231, 6.6.5 + StatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 + StatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 + StatusInsufficientStorage = 507 // RFC 4918, 11.5 + StatusLoopDetected = 508 // RFC 5842, 7.2 + StatusNotExtended = 510 // RFC 2774, 7 + StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 +) From bfede902e4d62591de77cd37b7b56404efa73e91 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 02:06:29 +0100 Subject: [PATCH 06/15] Update .travis.yml --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a6f74d85..841c65d3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,6 @@ os: - windows - osx go: - - 1.9.x - - 1.10.x - 1.11.x - 1.12.x - 1.13.x From a29c75b5190396fed6ca3d04605b512473e4f879 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 04:58:57 +0100 Subject: [PATCH 07/15] Update .travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 841c65d3..0275dde9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go sudo: false -dist: bionic + os: - linux - windows From be61c7d3d000c627b17f80226708a53a7bce5a4f Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 05:34:18 +0100 Subject: [PATCH 08/15] Update .travis.yml --- .travis.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0275dde9..903441ef 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,10 +14,10 @@ env: - GO111MODULE=on script: # build test for supported platforms - - GOOS=linux go build - - GOOS=darwin go build - - GOOS=freebsd go build - - GOOS=windows go build - - GOARCH=386 go build + # - GOOS=linux go build + # - GOOS=darwin go build + # - GOOS=freebsd go build + # - GOOS=windows go build + # - GOARCH=386 go build - go test -v - go test -race -v From 82a8ae6f92b070c0e34c8699321a32fa1153a5f6 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 17:28:01 +0100 Subject: [PATCH 09/15] Update .travis.yml --- .travis.yml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index 903441ef..da5d5997 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,14 +10,13 @@ go: - 1.12.x - 1.13.x - 1.14.x -env: - - GO111MODULE=on + script: # build test for supported platforms - # - GOOS=linux go build - # - GOOS=darwin go build - # - GOOS=freebsd go build - # - GOOS=windows go build - # - GOARCH=386 go build + - GOOS=linux go build + - GOOS=darwin go build + - GOOS=freebsd go build + - GOOS=windows go build + - GOARCH=386 go build - go test -v - go test -race -v From ad9f3eccadd78989cba170c42381c987fe332177 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 17:35:12 +0100 Subject: [PATCH 10/15] Add timeout for Test --- application.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/application.go b/application.go index 7ec5e641..86406d9b 100644 --- a/application.go +++ b/application.go @@ -396,7 +396,11 @@ func (app *App) Shutdown() error { } // Test : https://fiber.wiki/application#test -func (app *App) Test(request *http.Request) (*http.Response, error) { +func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, error) { + timeout := 200 + if len(msTimeout) > 0 { + timeout = msTimeout[0] + } // Dump raw http request dump, err := httputil.DumpRequest(request, true) if err != nil { @@ -421,7 +425,7 @@ func (app *App) Test(request *http.Request) (*http.Response, error) { if err != nil { return nil, err } - case <-time.After(200 * time.Millisecond): + case <-time.After(time.Duration(timeout) * time.Millisecond): return nil, fmt.Errorf("Timeout error") } // Read response From 83937bec52b27bc90b6bf49d246c354a13ce8ac8 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 20:31:58 +0100 Subject: [PATCH 11/15] Move template engines to middleware --- .travis.yml | 3 +- application.go | 2 +- context.go | 85 ++++++++++++++++++++++++++++++++++++-------------- go.mod | 1 - go.sum | 12 ------- 5 files changed, 64 insertions(+), 39 deletions(-) diff --git a/.travis.yml b/.travis.yml index da5d5997..0275dde9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,8 @@ go: - 1.12.x - 1.13.x - 1.14.x - +env: + - GO111MODULE=on script: # build test for supported platforms - GOOS=linux go build diff --git a/application.go b/application.go index 86406d9b..6dc6d7f3 100644 --- a/application.go +++ b/application.go @@ -53,7 +53,7 @@ type ( // Folder containing template files TemplateFolder string `default:""` // Template engine: html, amber, handlebars , mustache or pug - TemplateEngine string `default:""` + TemplateEngine func(raw string, bind interface{}) (out string, err error) `default:""` // Extension for the template files TemplateExtension string `default:""` } diff --git a/context.go b/context.go index 16d0b245..4f08283c 100644 --- a/context.go +++ b/context.go @@ -5,8 +5,10 @@ package fiber import ( + "bytes" "encoding/xml" "fmt" + "html/template" "io/ioutil" "log" "mime" @@ -18,7 +20,6 @@ import ( "sync" "time" - template "github.com/gofiber/template" jsoniter "github.com/json-iterator/go" fasthttp "github.com/valyala/fasthttp" ) @@ -720,15 +721,11 @@ func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error { var err error var raw []byte var html string - var e string if len(engine) > 0 { - e = engine[0] - } else if ctx.app.Settings.TemplateEngine != "" { - e = ctx.app.Settings.TemplateEngine - } else { - e = filepath.Ext(file)[1:] + log.Println("Warning: engine parameter is deprecated since v1.8.4, please use github.com/gofiber/template instead.") } + if ctx.app.Settings.TemplateFolder != "" { file = filepath.Join(ctx.app.Settings.TemplateFolder, file) } @@ -738,32 +735,72 @@ func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error { if raw, err = ioutil.ReadFile(filepath.Clean(file)); err != nil { return err } + if ctx.app.Settings.TemplateEngine != nil { + // Custom template engine + // https://github.com/gofiber/template + if html, err = ctx.app.Settings.TemplateEngine(getString(raw), bind); err != nil { + return err + } + } else { + // Default template engine + // https://golang.org/pkg/text/template/ + var buf bytes.Buffer + var tmpl *template.Template - switch e { - case "amber": // https://github.com/eknkc/amber - if html, err = template.Amber(getString(raw), bind); err != nil { + if tmpl, err = template.New("").Parse(getString(raw)); err != nil { return err } - case "handlebars": // https://github.com/aymerick/raymond - if html, err = template.Handlebars(getString(raw), bind); err != nil { - return err - } - case "mustache": // https://github.com/cbroglie/mustache - if html, err = template.Mustache(getString(raw), bind); err != nil { - return err - } - case "pug": // https://github.com/Joker/jade - if html, err = template.Pug(getString(raw), bind); err != nil { - return err - } - default: // https://golang.org/pkg/text/template/ - if html, err = template.HTML(getString(raw), bind); err != nil { + if err = tmpl.Execute(&buf, bind); err != nil { return err } + html = buf.String() } ctx.Set("Content-Type", "text/html") ctx.SendString(html) return err + // if len(engine) > 0 { + // log.Println("Deprectated") + // e = engine[0] + // } else if ctx.app.Settings.TemplateEngine != "" { + // e = ctx.app.Settings.TemplateEngine + // } else { + // e = filepath.Ext(file)[1:] + // } + // if ctx.app.Settings.TemplateFolder != "" { + // file = filepath.Join(ctx.app.Settings.TemplateFolder, file) + // } + // if ctx.app.Settings.TemplateExtension != "" { + // file = file + ctx.app.Settings.TemplateExtension + // } + // if raw, err = ioutil.ReadFile(filepath.Clean(file)); err != nil { + // return err + // } + + // switch e { + // case "amber": // https://github.com/eknkc/amber + // if html, err = template.Amber(getString(raw), bind); err != nil { + // return err + // } + // case "handlebars": // https://github.com/aymerick/raymond + // if html, err = template.Handlebars(getString(raw), bind); err != nil { + // return err + // } + // case "mustache": // https://github.com/cbroglie/mustache + // if html, err = template.Mustache(getString(raw), bind); err != nil { + // return err + // } + // case "pug": // https://github.com/Joker/jade + // if html, err = template.Pug(getString(raw), bind); err != nil { + // return err + // } + // default: // https://golang.org/pkg/text/template/ + // if html, err = template.HTML(getString(raw), bind); err != nil { + // return err + // } + // } + // ctx.Set("Content-Type", "text/html") + // ctx.SendString(html) + // return err } // Returns the matched Route struct. diff --git a/go.mod b/go.mod index f0f1706b..01c7106d 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,6 @@ module github.com/gofiber/fiber go 1.11 require ( - github.com/gofiber/template v1.0.0 github.com/gorilla/schema v1.1.0 github.com/json-iterator/go v1.1.9 github.com/valyala/fasthttp v1.9.0 diff --git a/go.sum b/go.sum index 532502b4..276b6cc9 100644 --- a/go.sum +++ b/go.sum @@ -1,16 +1,5 @@ -github.com/Joker/hpp v0.0.0-20180418125244-6893e659854a/go.mod h1:MzD2WMdSxvbHw5fM/OXOFily/lipJWRc9C1px0Mt0ZE= -github.com/Joker/jade v1.0.0 h1:lOCEPvTAtWfLpSZYMOv/g44MGQFAolbKh2khHHGu0Kc= -github.com/Joker/jade v1.0.0/go.mod h1:efZIdO0py/LtcJRSa/j2WEklMSAw84WV0zZVMxNToB8= -github.com/aymerick/raymond v2.0.2+incompatible h1:VEp3GpgdAnv9B2GFyTvqgcKvY+mfKMjPOA3SbKLtnU0= -github.com/aymerick/raymond v2.0.2+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= -github.com/cbroglie/mustache v1.0.1 h1:ivMg8MguXq/rrz2eu3tw6g3b16+PQhoTn6EZAhst2mw= -github.com/cbroglie/mustache v1.0.1/go.mod h1:R/RUa+SobQ14qkP4jtx5Vke5sDytONDQXNLPY/PO69g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 h1:clC1lXBpe2kTj2VHdaIu9ajZQe4kcEY9j0NsnDDBZ3o= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/gofiber/template v1.0.0 h1:Vf4Fby9zUWVQyY2y69KKyRHsEYlIE+Pxb25M+jiaEL0= -github.com/gofiber/template v1.0.0/go.mod h1:+bij+R0NI6urTg2jtQvPj5wb2uWMxW9eYGsAN3QhnP0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/gorilla/schema v1.1.0 h1:CamqUDOFUBqzrvxuz2vEwo8+SUdwsluFh7IlzJh30LY= github.com/gorilla/schema v1.1.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= @@ -33,7 +22,6 @@ github.com/valyala/fasthttp v1.9.0 h1:hNpmUdy/+ZXYpGy0OBfm7K0UQTzb73W0T0U4iJIVrM github.com/valyala/fasthttp v1.9.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From c14e7771d6e4900fa23c31acdded1af9dabd8e8d Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 21:49:57 +0100 Subject: [PATCH 12/15] Update context.go --- context.go | 49 +------------------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/context.go b/context.go index 4f08283c..c6f1c5d7 100644 --- a/context.go +++ b/context.go @@ -717,15 +717,11 @@ func (ctx *Ctx) Redirect(path string, status ...int) { // We support the following engines: html, amber, handlebars, mustache, pug // // https://fiber.wiki/context#render -func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error { +func (ctx *Ctx) Render(file string, bind interface{}) error { var err error var raw []byte var html string - if len(engine) > 0 { - log.Println("Warning: engine parameter is deprecated since v1.8.4, please use github.com/gofiber/template instead.") - } - if ctx.app.Settings.TemplateFolder != "" { file = filepath.Join(ctx.app.Settings.TemplateFolder, file) } @@ -758,49 +754,6 @@ func (ctx *Ctx) Render(file string, bind interface{}, engine ...string) error { ctx.Set("Content-Type", "text/html") ctx.SendString(html) return err - // if len(engine) > 0 { - // log.Println("Deprectated") - // e = engine[0] - // } else if ctx.app.Settings.TemplateEngine != "" { - // e = ctx.app.Settings.TemplateEngine - // } else { - // e = filepath.Ext(file)[1:] - // } - // if ctx.app.Settings.TemplateFolder != "" { - // file = filepath.Join(ctx.app.Settings.TemplateFolder, file) - // } - // if ctx.app.Settings.TemplateExtension != "" { - // file = file + ctx.app.Settings.TemplateExtension - // } - // if raw, err = ioutil.ReadFile(filepath.Clean(file)); err != nil { - // return err - // } - - // switch e { - // case "amber": // https://github.com/eknkc/amber - // if html, err = template.Amber(getString(raw), bind); err != nil { - // return err - // } - // case "handlebars": // https://github.com/aymerick/raymond - // if html, err = template.Handlebars(getString(raw), bind); err != nil { - // return err - // } - // case "mustache": // https://github.com/cbroglie/mustache - // if html, err = template.Mustache(getString(raw), bind); err != nil { - // return err - // } - // case "pug": // https://github.com/Joker/jade - // if html, err = template.Pug(getString(raw), bind); err != nil { - // return err - // } - // default: // https://golang.org/pkg/text/template/ - // if html, err = template.HTML(getString(raw), bind); err != nil { - // return err - // } - // } - // ctx.Set("Content-Type", "text/html") - // ctx.SendString(html) - // return err } // Returns the matched Route struct. From 614453e6ba21da886b04be7470cc312bbe0e8cbf Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Sun, 22 Mar 2020 23:37:55 +0100 Subject: [PATCH 13/15] Update application.go --- application.go | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/application.go b/application.go index 6dc6d7f3..3ed656f2 100644 --- a/application.go +++ b/application.go @@ -419,14 +419,24 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e go func() { channel <- app.server.ServeConn(conn) }() - // Wait for callback - select { - case err := <-channel: - if err != nil { - return nil, err + if timeout == 0 || timeout == -1 { + // Wait for callback + select { + case err := <-channel: + if err != nil { + return nil, err + } + } + } else { + // Wait for callback + select { + case err := <-channel: + if err != nil { + return nil, err + } + case <-time.After(time.Duration(timeout) * time.Millisecond): + return nil, fmt.Errorf("Timeout error") } - case <-time.After(time.Duration(timeout) * time.Millisecond): - return nil, fmt.Errorf("Timeout error") } // Read response buffer := bufio.NewReader(&conn.w) From 7140c75f635b4b05f6c88020c0397f6d6fae3d99 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Mon, 23 Mar 2020 01:43:42 +0100 Subject: [PATCH 14/15] Update application.go --- application.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application.go b/application.go index 3ed656f2..b0af55ea 100644 --- a/application.go +++ b/application.go @@ -419,7 +419,7 @@ func (app *App) Test(request *http.Request, msTimeout ...int) (*http.Response, e go func() { channel <- app.server.ServeConn(conn) }() - if timeout == 0 || timeout == -1 { + if timeout < 0 { // Wait for callback select { case err := <-channel: From 26c0ecf7f44c4c92acdb42384b27714d90ff16d6 Mon Sep 17 00:00:00 2001 From: Fenny <25108519+Fenny@users.noreply.github.com> Date: Mon, 23 Mar 2020 01:56:07 +0100 Subject: [PATCH 15/15] Update application.go --- application.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/application.go b/application.go index b0af55ea..9a908bed 100644 --- a/application.go +++ b/application.go @@ -53,7 +53,7 @@ type ( // Folder containing template files TemplateFolder string `default:""` // Template engine: html, amber, handlebars , mustache or pug - TemplateEngine func(raw string, bind interface{}) (out string, err error) `default:""` + TemplateEngine func(raw string, bind interface{}) (string, error) `default:""` // Extension for the template files TemplateExtension string `default:""` }