// 🚀 Fiber is an Express.js inspired web framework written in Go with 💖 // 📌 Please open an issue if you got suggestions or found a bug! // 🖥 Links: https://github.com/gofiber/fiber, https://fiber.wiki // 🦸 Not all heroes wear capes, thank you to some amazing people // 💖 @valyala, @erikdubbelboer, @savsgio, @julienschmidt, @koddr package fiber import ( "bytes" "net" "os" "path/filepath" "reflect" "regexp" "strings" "time" "unsafe" ) func getParams(path string) (params []string) { segments := strings.Split(path, "/") replacer := strings.NewReplacer(":", "", "?", "") for _, s := range segments { if s == "" { continue } else if s[0] == ':' { params = append(params, replacer.Replace(s)) } else if s[0] == '*' { params = append(params, "*") } } return params } func getRegex(path string) (*regexp.Regexp, error) { pattern := "^" segments := strings.Split(path, "/") for _, s := range segments { if s == "" { continue } if s[0] == ':' { if strings.Contains(s, "?") { pattern += "(?:/([^/]+?))?" } else { pattern += "/(?:([^/]+?))" } } else if s[0] == '*' { pattern += "/(.*)" } else { pattern += "/" + s } } pattern += "/?$" regex, err := regexp.Compile(pattern) return regex, err } func getFiles(root string) (files []string, isDir bool, err error) { err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { if !info.IsDir() { files = append(files, path) } else { isDir = true } return err }) return files, isDir, err } func getType(ext string) (mime string) { if ext == "" { return mime } if ext[0] == '.' { ext = ext[1:] } mime = contentTypes[ext] if mime == "" { return contentTypeOctetStream } return mime } func getStatus(status int) (msg string) { return statusMessages[status] } // #nosec G103 // getString converts byte slice to a string without memory allocation. // See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ . func getString(b []byte) string { return *(*string)(unsafe.Pointer(&b)) } // #nosec G103 // getBytes converts string to a byte slice without memory allocation. // See https://groups.google.com/forum/#!msg/Golang-Nuts/ENgbUzYvCuU/90yGx7GUAgAJ . func getBytes(s string) (b []byte) { // return *(*[]byte)(unsafe.Pointer(&s)) sh := *(*reflect.StringHeader)(unsafe.Pointer(&s)) bh := (*reflect.SliceHeader)(unsafe.Pointer(&b)) bh.Data, bh.Len, bh.Cap = sh.Data, sh.Len, sh.Len return b } // Check for error and format // func checkErr(err error, title ...string) { // if err != nil { // t := "Error" // if len(title) > 0 { // t = title[0] // } // fmt.Printf("\n%s%s: %v%s\n\n", "\x1b[1;30m", t, err, "\x1b[0m") // os.Exit(1) // } // } // https://golang.org/src/net/net.go#L113 // Helper methods for Testing type conn struct { net.Conn r bytes.Buffer w bytes.Buffer } func (c *conn) RemoteAddr() net.Addr { return &net.TCPAddr{ IP: net.IPv4(0, 0, 0, 0), } } func (c *conn) LocalAddr() net.Addr { return c.LocalAddr() } func (c *conn) Read(b []byte) (int, error) { return c.r.Read(b) } func (c *conn) Write(b []byte) (int, error) { return c.w.Write(b) } func (c *conn) Close() error { return nil } func (c *conn) SetDeadline(t time.Time) error { return nil } func (c *conn) SetReadDeadline(t time.Time) error { return nil } func (c *conn) SetWriteDeadline(t time.Time) error { return nil } 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", } const ( contentTypeJSON = "application/json" contentTypeJs = "application/javascript" contentTypeXML = "application/xml" contentTypeOctetStream = "application/octet-stream" ) // https://github.com/nginx/nginx/blob/master/conf/mime.types var contentTypes = map[string]string{ "html": "text/html", "htm": "text/html", "shtml": "text/html", "css": "text/css", "xml": "text/xml", "gif": "image/gif", "jpeg": "image/jpeg", "jpg": "image/jpeg", "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", }