release new version 1.1.4
Showing
22 changed files
with
258 additions
and
203 deletions
| ... | @@ -9,8 +9,8 @@ import ( | ... | @@ -9,8 +9,8 @@ import ( |
| 9 | "github.com/astaxie/beego/utils" | 9 | "github.com/astaxie/beego/utils" |
| 10 | ) | 10 | ) |
| 11 | 11 | ||
| 12 | // BeeAdminApp is the default AdminApp used by admin module. | 12 | // BeeAdminApp is the default adminApp used by admin module. |
| 13 | var BeeAdminApp *AdminApp | 13 | var beeAdminApp *adminApp |
| 14 | 14 | ||
| 15 | // FilterMonitorFunc is default monitor filter when admin module is enable. | 15 | // FilterMonitorFunc is default monitor filter when admin module is enable. |
| 16 | // if this func returns, admin module records qbs for this request by condition of this function logic. | 16 | // if this func returns, admin module records qbs for this request by condition of this function logic. |
| ... | @@ -31,22 +31,22 @@ var BeeAdminApp *AdminApp | ... | @@ -31,22 +31,22 @@ var BeeAdminApp *AdminApp |
| 31 | var FilterMonitorFunc func(string, string, time.Duration) bool | 31 | var FilterMonitorFunc func(string, string, time.Duration) bool |
| 32 | 32 | ||
| 33 | func init() { | 33 | func init() { |
| 34 | BeeAdminApp = &AdminApp{ | 34 | beeAdminApp = &adminApp{ |
| 35 | routers: make(map[string]http.HandlerFunc), | 35 | routers: make(map[string]http.HandlerFunc), |
| 36 | } | 36 | } |
| 37 | BeeAdminApp.Route("/", AdminIndex) | 37 | beeAdminApp.Route("/", adminIndex) |
| 38 | BeeAdminApp.Route("/qps", QpsIndex) | 38 | beeAdminApp.Route("/qps", qpsIndex) |
| 39 | BeeAdminApp.Route("/prof", ProfIndex) | 39 | beeAdminApp.Route("/prof", profIndex) |
| 40 | BeeAdminApp.Route("/healthcheck", Healthcheck) | 40 | beeAdminApp.Route("/healthcheck", healthcheck) |
| 41 | BeeAdminApp.Route("/task", TaskStatus) | 41 | beeAdminApp.Route("/task", taskStatus) |
| 42 | BeeAdminApp.Route("/runtask", RunTask) | 42 | beeAdminApp.Route("/runtask", runTask) |
| 43 | BeeAdminApp.Route("/listconf", ListConf) | 43 | beeAdminApp.Route("/listconf", listConf) |
| 44 | FilterMonitorFunc = func(string, string, time.Duration) bool { return true } | 44 | FilterMonitorFunc = func(string, string, time.Duration) bool { return true } |
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | // AdminIndex is the default http.Handler for admin module. | 47 | // AdminIndex is the default http.Handler for admin module. |
| 48 | // it matches url pattern "/". | 48 | // it matches url pattern "/". |
| 49 | func AdminIndex(rw http.ResponseWriter, r *http.Request) { | 49 | func adminIndex(rw http.ResponseWriter, r *http.Request) { |
| 50 | rw.Write([]byte("Welcome to Admin Dashboard\n")) | 50 | rw.Write([]byte("Welcome to Admin Dashboard\n")) |
| 51 | rw.Write([]byte("There are servral functions:\n")) | 51 | rw.Write([]byte("There are servral functions:\n")) |
| 52 | rw.Write([]byte("1. Record all request and request time, http://localhost:8088/qps\n")) | 52 | rw.Write([]byte("1. Record all request and request time, http://localhost:8088/qps\n")) |
| ... | @@ -60,13 +60,13 @@ func AdminIndex(rw http.ResponseWriter, r *http.Request) { | ... | @@ -60,13 +60,13 @@ func AdminIndex(rw http.ResponseWriter, r *http.Request) { |
| 60 | 60 | ||
| 61 | // QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter. | 61 | // QpsIndex is the http.Handler for writing qbs statistics map result info in http.ResponseWriter. |
| 62 | // it's registered with url pattern "/qbs" in admin module. | 62 | // it's registered with url pattern "/qbs" in admin module. |
| 63 | func QpsIndex(rw http.ResponseWriter, r *http.Request) { | 63 | func qpsIndex(rw http.ResponseWriter, r *http.Request) { |
| 64 | toolbox.StatisticsMap.GetMap(rw) | 64 | toolbox.StatisticsMap.GetMap(rw) |
| 65 | } | 65 | } |
| 66 | 66 | ||
| 67 | // ListConf is the http.Handler of displaying all beego configuration values as key/value pair. | 67 | // ListConf is the http.Handler of displaying all beego configuration values as key/value pair. |
| 68 | // it's registered with url pattern "/listconf" in admin module. | 68 | // it's registered with url pattern "/listconf" in admin module. |
| 69 | func ListConf(rw http.ResponseWriter, r *http.Request) { | 69 | func listConf(rw http.ResponseWriter, r *http.Request) { |
| 70 | r.ParseForm() | 70 | r.ParseForm() |
| 71 | command := r.Form.Get("command") | 71 | command := r.Form.Get("command") |
| 72 | if command != "" { | 72 | if command != "" { |
| ... | @@ -183,7 +183,7 @@ func ListConf(rw http.ResponseWriter, r *http.Request) { | ... | @@ -183,7 +183,7 @@ func ListConf(rw http.ResponseWriter, r *http.Request) { |
| 183 | 183 | ||
| 184 | // ProfIndex is a http.Handler for showing profile command. | 184 | // ProfIndex is a http.Handler for showing profile command. |
| 185 | // it's in url pattern "/prof" in admin module. | 185 | // it's in url pattern "/prof" in admin module. |
| 186 | func ProfIndex(rw http.ResponseWriter, r *http.Request) { | 186 | func profIndex(rw http.ResponseWriter, r *http.Request) { |
| 187 | r.ParseForm() | 187 | r.ParseForm() |
| 188 | command := r.Form.Get("command") | 188 | command := r.Form.Get("command") |
| 189 | if command != "" { | 189 | if command != "" { |
| ... | @@ -204,7 +204,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) { | ... | @@ -204,7 +204,7 @@ func ProfIndex(rw http.ResponseWriter, r *http.Request) { |
| 204 | 204 | ||
| 205 | // Healthcheck is a http.Handler calling health checking and showing the result. | 205 | // Healthcheck is a http.Handler calling health checking and showing the result. |
| 206 | // it's in "/healthcheck" pattern in admin module. | 206 | // it's in "/healthcheck" pattern in admin module. |
| 207 | func Healthcheck(rw http.ResponseWriter, req *http.Request) { | 207 | func healthcheck(rw http.ResponseWriter, req *http.Request) { |
| 208 | for name, h := range toolbox.AdminCheckList { | 208 | for name, h := range toolbox.AdminCheckList { |
| 209 | if err := h.Check(); err != nil { | 209 | if err := h.Check(); err != nil { |
| 210 | fmt.Fprintf(rw, "%s : ok\n", name) | 210 | fmt.Fprintf(rw, "%s : ok\n", name) |
| ... | @@ -216,7 +216,7 @@ func Healthcheck(rw http.ResponseWriter, req *http.Request) { | ... | @@ -216,7 +216,7 @@ func Healthcheck(rw http.ResponseWriter, req *http.Request) { |
| 216 | 216 | ||
| 217 | // TaskStatus is a http.Handler with running task status (task name, status and the last execution). | 217 | // TaskStatus is a http.Handler with running task status (task name, status and the last execution). |
| 218 | // it's in "/task" pattern in admin module. | 218 | // it's in "/task" pattern in admin module. |
| 219 | func TaskStatus(rw http.ResponseWriter, req *http.Request) { | 219 | func taskStatus(rw http.ResponseWriter, req *http.Request) { |
| 220 | for tname, tk := range toolbox.AdminTaskList { | 220 | for tname, tk := range toolbox.AdminTaskList { |
| 221 | fmt.Fprintf(rw, "%s:%s:%s", tname, tk.GetStatus(), tk.GetPrev().String()) | 221 | fmt.Fprintf(rw, "%s:%s:%s", tname, tk.GetStatus(), tk.GetPrev().String()) |
| 222 | } | 222 | } |
| ... | @@ -224,7 +224,7 @@ func TaskStatus(rw http.ResponseWriter, req *http.Request) { | ... | @@ -224,7 +224,7 @@ func TaskStatus(rw http.ResponseWriter, req *http.Request) { |
| 224 | 224 | ||
| 225 | // RunTask is a http.Handler to run a Task from the "query string. | 225 | // RunTask is a http.Handler to run a Task from the "query string. |
| 226 | // the request url likes /runtask?taskname=sendmail. | 226 | // the request url likes /runtask?taskname=sendmail. |
| 227 | func RunTask(rw http.ResponseWriter, req *http.Request) { | 227 | func runTask(rw http.ResponseWriter, req *http.Request) { |
| 228 | req.ParseForm() | 228 | req.ParseForm() |
| 229 | taskname := req.Form.Get("taskname") | 229 | taskname := req.Form.Get("taskname") |
| 230 | if t, ok := toolbox.AdminTaskList[taskname]; ok { | 230 | if t, ok := toolbox.AdminTaskList[taskname]; ok { |
| ... | @@ -238,19 +238,19 @@ func RunTask(rw http.ResponseWriter, req *http.Request) { | ... | @@ -238,19 +238,19 @@ func RunTask(rw http.ResponseWriter, req *http.Request) { |
| 238 | } | 238 | } |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | // AdminApp is an http.HandlerFunc map used as BeeAdminApp. | 241 | // adminApp is an http.HandlerFunc map used as beeAdminApp. |
| 242 | type AdminApp struct { | 242 | type adminApp struct { |
| 243 | routers map[string]http.HandlerFunc | 243 | routers map[string]http.HandlerFunc |
| 244 | } | 244 | } |
| 245 | 245 | ||
| 246 | // Route adds http.HandlerFunc to AdminApp with url pattern. | 246 | // Route adds http.HandlerFunc to adminApp with url pattern. |
| 247 | func (admin *AdminApp) Route(pattern string, f http.HandlerFunc) { | 247 | func (admin *adminApp) Route(pattern string, f http.HandlerFunc) { |
| 248 | admin.routers[pattern] = f | 248 | admin.routers[pattern] = f |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | // Run AdminApp http server. | 251 | // Run adminApp http server. |
| 252 | // Its addr is defined in configuration file as adminhttpaddr and adminhttpport. | 252 | // Its addr is defined in configuration file as adminhttpaddr and adminhttpport. |
| 253 | func (admin *AdminApp) Run() { | 253 | func (admin *adminApp) Run() { |
| 254 | if len(toolbox.AdminTaskList) > 0 { | 254 | if len(toolbox.AdminTaskList) > 0 { |
| 255 | toolbox.StartTask() | 255 | toolbox.StartTask() |
| 256 | } | 256 | } | ... | ... |
| 1 | // beego is an open-source, high-performance web framework for the Go programming language | ||
| 1 | package beego | 2 | package beego |
| 2 | 3 | ||
| 3 | import ( | 4 | import ( |
| ... | @@ -13,7 +14,7 @@ import ( | ... | @@ -13,7 +14,7 @@ import ( |
| 13 | ) | 14 | ) |
| 14 | 15 | ||
| 15 | // beego web framework version. | 16 | // beego web framework version. |
| 16 | const VERSION = "1.1.3" | 17 | const VERSION = "1.1.4" |
| 17 | 18 | ||
| 18 | type hookfunc func() error //hook function to run | 19 | type hookfunc func() error //hook function to run |
| 19 | var hooks []hookfunc //hook function slice to store the hookfunc | 20 | var hooks []hookfunc //hook function slice to store the hookfunc |
| ... | @@ -137,6 +138,7 @@ func SetStaticPath(url string, path string) *App { | ... | @@ -137,6 +138,7 @@ func SetStaticPath(url string, path string) *App { |
| 137 | if !strings.HasPrefix(url, "/") { | 138 | if !strings.HasPrefix(url, "/") { |
| 138 | url = "/" + url | 139 | url = "/" + url |
| 139 | } | 140 | } |
| 141 | url = strings.TrimRight(url, "/") | ||
| 140 | StaticDir[url] = path | 142 | StaticDir[url] = path |
| 141 | return BeeApp | 143 | return BeeApp |
| 142 | } | 144 | } |
| ... | @@ -178,7 +180,7 @@ func Run() { | ... | @@ -178,7 +180,7 @@ func Run() { |
| 178 | initBeforeHttpRun() | 180 | initBeforeHttpRun() |
| 179 | 181 | ||
| 180 | if EnableAdmin { | 182 | if EnableAdmin { |
| 181 | go BeeAdminApp.Run() | 183 | go beeAdminApp.Run() |
| 182 | } | 184 | } |
| 183 | 185 | ||
| 184 | BeeApp.Run() | 186 | BeeApp.Run() | ... | ... |
| ... | @@ -5,6 +5,8 @@ import ( | ... | @@ -5,6 +5,8 @@ import ( |
| 5 | "errors" | 5 | "errors" |
| 6 | 6 | ||
| 7 | "github.com/beego/memcache" | 7 | "github.com/beego/memcache" |
| 8 | |||
| 9 | "github.com/astaxie/beego/cache" | ||
| 8 | ) | 10 | ) |
| 9 | 11 | ||
| 10 | // Memcache adapter. | 12 | // Memcache adapter. |
| ... | @@ -147,5 +149,5 @@ func (rc *MemcacheCache) connectInit() (*memcache.Connection, error) { | ... | @@ -147,5 +149,5 @@ func (rc *MemcacheCache) connectInit() (*memcache.Connection, error) { |
| 147 | } | 149 | } |
| 148 | 150 | ||
| 149 | func init() { | 151 | func init() { |
| 150 | Register("memcache", NewMemCache()) | 152 | cache.Register("memcache", NewMemCache()) |
| 151 | } | 153 | } | ... | ... |
| ... | @@ -6,6 +6,8 @@ import ( | ... | @@ -6,6 +6,8 @@ import ( |
| 6 | "time" | 6 | "time" |
| 7 | 7 | ||
| 8 | "github.com/beego/redigo/redis" | 8 | "github.com/beego/redigo/redis" |
| 9 | |||
| 10 | "github.com/astaxie/beego/cache" | ||
| 9 | ) | 11 | ) |
| 10 | 12 | ||
| 11 | var ( | 13 | var ( |
| ... | @@ -130,5 +132,5 @@ func (rc *RedisCache) connectInit() { | ... | @@ -130,5 +132,5 @@ func (rc *RedisCache) connectInit() { |
| 130 | } | 132 | } |
| 131 | 133 | ||
| 132 | func init() { | 134 | func init() { |
| 133 | Register("redis", NewRedisCache()) | 135 | cache.Register("redis", NewRedisCache()) |
| 134 | } | 136 | } | ... | ... |
| ... | @@ -306,9 +306,9 @@ func ParseConfig() (err error) { | ... | @@ -306,9 +306,9 @@ func ParseConfig() (err error) { |
| 306 | sds := strings.Fields(sd) | 306 | sds := strings.Fields(sd) |
| 307 | for _, v := range sds { | 307 | for _, v := range sds { |
| 308 | if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 { | 308 | if url2fsmap := strings.SplitN(v, ":", 2); len(url2fsmap) == 2 { |
| 309 | StaticDir["/"+url2fsmap[0]] = url2fsmap[1] | 309 | StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[1] |
| 310 | } else { | 310 | } else { |
| 311 | StaticDir["/"+url2fsmap[0]] = url2fsmap[0] | 311 | StaticDir["/"+strings.TrimRight(url2fsmap[0], "/")] = url2fsmap[0] |
| 312 | } | 312 | } |
| 313 | } | 313 | } |
| 314 | } | 314 | } | ... | ... |
File moved
File moved
File moved
| ... | @@ -2,6 +2,7 @@ package context | ... | @@ -2,6 +2,7 @@ package context |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "bytes" | 4 | "bytes" |
| 5 | "errors" | ||
| 5 | "io/ioutil" | 6 | "io/ioutil" |
| 6 | "net/http" | 7 | "net/http" |
| 7 | "reflect" | 8 | "reflect" |
| ... | @@ -92,6 +93,41 @@ func (input *BeegoInput) Is(method string) bool { | ... | @@ -92,6 +93,41 @@ func (input *BeegoInput) Is(method string) bool { |
| 92 | return input.Method() == method | 93 | return input.Method() == method |
| 93 | } | 94 | } |
| 94 | 95 | ||
| 96 | // Is this a GET method request? | ||
| 97 | func (input *BeegoInput) IsGet() bool { | ||
| 98 | return input.Is("GET") | ||
| 99 | } | ||
| 100 | |||
| 101 | // Is this a POST method request? | ||
| 102 | func (input *BeegoInput) IsPost() bool { | ||
| 103 | return input.Is("POST") | ||
| 104 | } | ||
| 105 | |||
| 106 | // Is this a Head method request? | ||
| 107 | func (input *BeegoInput) IsHead() bool { | ||
| 108 | return input.Is("HEAD") | ||
| 109 | } | ||
| 110 | |||
| 111 | // Is this a OPTIONS method request? | ||
| 112 | func (input *BeegoInput) IsOptions() bool { | ||
| 113 | return input.Is("OPTIONS") | ||
| 114 | } | ||
| 115 | |||
| 116 | // Is this a PUT method request? | ||
| 117 | func (input *BeegoInput) IsPut() bool { | ||
| 118 | return input.Is("PUT") | ||
| 119 | } | ||
| 120 | |||
| 121 | // Is this a DELETE method request? | ||
| 122 | func (input *BeegoInput) IsDelete() bool { | ||
| 123 | return input.Is("DELETE") | ||
| 124 | } | ||
| 125 | |||
| 126 | // Is this a PATCH method request? | ||
| 127 | func (input *BeegoInput) IsPatch() bool { | ||
| 128 | return input.Is("PATCH") | ||
| 129 | } | ||
| 130 | |||
| 95 | // IsAjax returns boolean of this request is generated by ajax. | 131 | // IsAjax returns boolean of this request is generated by ajax. |
| 96 | func (input *BeegoInput) IsAjax() bool { | 132 | func (input *BeegoInput) IsAjax() bool { |
| 97 | return input.Header("X-Requested-With") == "XMLHttpRequest" | 133 | return input.Header("X-Requested-With") == "XMLHttpRequest" |
| ... | @@ -109,7 +145,7 @@ func (input *BeegoInput) IsWebsocket() bool { | ... | @@ -109,7 +145,7 @@ func (input *BeegoInput) IsWebsocket() bool { |
| 109 | 145 | ||
| 110 | // IsSecure returns boolean of whether file uploads in this request or not.. | 146 | // IsSecure returns boolean of whether file uploads in this request or not.. |
| 111 | func (input *BeegoInput) IsUpload() bool { | 147 | func (input *BeegoInput) IsUpload() bool { |
| 112 | return input.Request.MultipartForm != nil | 148 | return input.Header("Content-Type") == "multipart/form-data" |
| 113 | } | 149 | } |
| 114 | 150 | ||
| 115 | // IP returns request client ip. | 151 | // IP returns request client ip. |
| ... | @@ -175,7 +211,9 @@ func (input *BeegoInput) Param(key string) string { | ... | @@ -175,7 +211,9 @@ func (input *BeegoInput) Param(key string) string { |
| 175 | 211 | ||
| 176 | // Query returns input data item string by a given string. | 212 | // Query returns input data item string by a given string. |
| 177 | func (input *BeegoInput) Query(key string) string { | 213 | func (input *BeegoInput) Query(key string) string { |
| 214 | if input.Request.Form == nil { | ||
| 178 | input.Request.ParseForm() | 215 | input.Request.ParseForm() |
| 216 | } | ||
| 179 | return input.Request.Form.Get(key) | 217 | return input.Request.Form.Get(key) |
| 180 | } | 218 | } |
| 181 | 219 | ||
| ... | @@ -200,7 +238,7 @@ func (input *BeegoInput) Session(key interface{}) interface{} { | ... | @@ -200,7 +238,7 @@ func (input *BeegoInput) Session(key interface{}) interface{} { |
| 200 | } | 238 | } |
| 201 | 239 | ||
| 202 | // Body returns the raw request body data as bytes. | 240 | // Body returns the raw request body data as bytes. |
| 203 | func (input *BeegoInput) Body() []byte { | 241 | func (input *BeegoInput) CopyBody() []byte { |
| 204 | requestbody, _ := ioutil.ReadAll(input.Request.Body) | 242 | requestbody, _ := ioutil.ReadAll(input.Request.Body) |
| 205 | input.Request.Body.Close() | 243 | input.Request.Body.Close() |
| 206 | bf := bytes.NewBuffer(requestbody) | 244 | bf := bytes.NewBuffer(requestbody) |
| ... | @@ -222,3 +260,21 @@ func (input *BeegoInput) GetData(key interface{}) interface{} { | ... | @@ -222,3 +260,21 @@ func (input *BeegoInput) GetData(key interface{}) interface{} { |
| 222 | func (input *BeegoInput) SetData(key, val interface{}) { | 260 | func (input *BeegoInput) SetData(key, val interface{}) { |
| 223 | input.Data[key] = val | 261 | input.Data[key] = val |
| 224 | } | 262 | } |
| 263 | |||
| 264 | func (input *BeegoInput) ParseFormOrMulitForm(maxMemory int64) error { | ||
| 265 | // Parse the body depending on the content type. | ||
| 266 | switch input.Header("Content-Type") { | ||
| 267 | case "application/x-www-form-urlencoded": | ||
| 268 | // Typical form. | ||
| 269 | if err := input.Request.ParseForm(); err != nil { | ||
| 270 | return errors.New("Error parsing request body:" + err.Error()) | ||
| 271 | } | ||
| 272 | |||
| 273 | case "multipart/form-data": | ||
| 274 | if err := input.Request.ParseMultipartForm(maxMemory); err != nil { | ||
| 275 | return errors.New("Error parsing request body:" + err.Error()) | ||
| 276 | } | ||
| 277 | } | ||
| 278 | |||
| 279 | return nil | ||
| 280 | } | ... | ... |
| ... | @@ -14,12 +14,12 @@ import ( | ... | @@ -14,12 +14,12 @@ import ( |
| 14 | "time" | 14 | "time" |
| 15 | ) | 15 | ) |
| 16 | 16 | ||
| 17 | var gmfim map[string]*MemFileInfo = make(map[string]*MemFileInfo) | 17 | var gmfim map[string]*memFileInfo = make(map[string]*memFileInfo) |
| 18 | var lock sync.RWMutex | 18 | var lock sync.RWMutex |
| 19 | 19 | ||
| 20 | // OpenMemZipFile returns MemFile object with a compressed static file. | 20 | // OpenMemZipFile returns MemFile object with a compressed static file. |
| 21 | // it's used for serve static file if gzip enable. | 21 | // it's used for serve static file if gzip enable. |
| 22 | func OpenMemZipFile(path string, zip string) (*MemFile, error) { | 22 | func openMemZipFile(path string, zip string) (*memFile, error) { |
| 23 | osfile, e := os.Open(path) | 23 | osfile, e := os.Open(path) |
| 24 | if e != nil { | 24 | if e != nil { |
| 25 | return nil, e | 25 | return nil, e |
| ... | @@ -36,12 +36,9 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { | ... | @@ -36,12 +36,9 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { |
| 36 | lock.RLock() | 36 | lock.RLock() |
| 37 | cfi, ok := gmfim[zip+":"+path] | 37 | cfi, ok := gmfim[zip+":"+path] |
| 38 | lock.RUnlock() | 38 | lock.RUnlock() |
| 39 | if ok && cfi.ModTime() == modtime && cfi.fileSize == fileSize { | 39 | if !(ok && cfi.ModTime() == modtime && cfi.fileSize == fileSize) { |
| 40 | |||
| 41 | } else { | ||
| 42 | var content []byte | 40 | var content []byte |
| 43 | if zip == "gzip" { | 41 | if zip == "gzip" { |
| 44 | //将文件内容压缩到zipbuf中 | ||
| 45 | var zipbuf bytes.Buffer | 42 | var zipbuf bytes.Buffer |
| 46 | gzipwriter, e := gzip.NewWriterLevel(&zipbuf, gzip.BestCompression) | 43 | gzipwriter, e := gzip.NewWriterLevel(&zipbuf, gzip.BestCompression) |
| 47 | if e != nil { | 44 | if e != nil { |
| ... | @@ -52,13 +49,11 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { | ... | @@ -52,13 +49,11 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { |
| 52 | if e != nil { | 49 | if e != nil { |
| 53 | return nil, e | 50 | return nil, e |
| 54 | } | 51 | } |
| 55 | //读zipbuf到content | ||
| 56 | content, e = ioutil.ReadAll(&zipbuf) | 52 | content, e = ioutil.ReadAll(&zipbuf) |
| 57 | if e != nil { | 53 | if e != nil { |
| 58 | return nil, e | 54 | return nil, e |
| 59 | } | 55 | } |
| 60 | } else if zip == "deflate" { | 56 | } else if zip == "deflate" { |
| 61 | //将文件内容压缩到zipbuf中 | ||
| 62 | var zipbuf bytes.Buffer | 57 | var zipbuf bytes.Buffer |
| 63 | deflatewriter, e := flate.NewWriter(&zipbuf, flate.BestCompression) | 58 | deflatewriter, e := flate.NewWriter(&zipbuf, flate.BestCompression) |
| 64 | if e != nil { | 59 | if e != nil { |
| ... | @@ -69,7 +64,6 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { | ... | @@ -69,7 +64,6 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { |
| 69 | if e != nil { | 64 | if e != nil { |
| 70 | return nil, e | 65 | return nil, e |
| 71 | } | 66 | } |
| 72 | //将zipbuf读入到content | ||
| 73 | content, e = ioutil.ReadAll(&zipbuf) | 67 | content, e = ioutil.ReadAll(&zipbuf) |
| 74 | if e != nil { | 68 | if e != nil { |
| 75 | return nil, e | 69 | return nil, e |
| ... | @@ -81,17 +75,17 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { | ... | @@ -81,17 +75,17 @@ func OpenMemZipFile(path string, zip string) (*MemFile, error) { |
| 81 | } | 75 | } |
| 82 | } | 76 | } |
| 83 | 77 | ||
| 84 | cfi = &MemFileInfo{osfileinfo, modtime, content, int64(len(content)), fileSize} | 78 | cfi = &memFileInfo{osfileinfo, modtime, content, int64(len(content)), fileSize} |
| 85 | lock.Lock() | 79 | lock.Lock() |
| 86 | defer lock.Unlock() | 80 | defer lock.Unlock() |
| 87 | gmfim[zip+":"+path] = cfi | 81 | gmfim[zip+":"+path] = cfi |
| 88 | } | 82 | } |
| 89 | return &MemFile{fi: cfi, offset: 0}, nil | 83 | return &memFile{fi: cfi, offset: 0}, nil |
| 90 | } | 84 | } |
| 91 | 85 | ||
| 92 | // MemFileInfo contains a compressed file bytes and file information. | 86 | // MemFileInfo contains a compressed file bytes and file information. |
| 93 | // it implements os.FileInfo interface. | 87 | // it implements os.FileInfo interface. |
| 94 | type MemFileInfo struct { | 88 | type memFileInfo struct { |
| 95 | os.FileInfo | 89 | os.FileInfo |
| 96 | modTime time.Time | 90 | modTime time.Time |
| 97 | content []byte | 91 | content []byte |
| ... | @@ -100,62 +94,62 @@ type MemFileInfo struct { | ... | @@ -100,62 +94,62 @@ type MemFileInfo struct { |
| 100 | } | 94 | } |
| 101 | 95 | ||
| 102 | // Name returns the compressed filename. | 96 | // Name returns the compressed filename. |
| 103 | func (fi *MemFileInfo) Name() string { | 97 | func (fi *memFileInfo) Name() string { |
| 104 | return fi.Name() | 98 | return fi.Name() |
| 105 | } | 99 | } |
| 106 | 100 | ||
| 107 | // Size returns the raw file content size, not compressed size. | 101 | // Size returns the raw file content size, not compressed size. |
| 108 | func (fi *MemFileInfo) Size() int64 { | 102 | func (fi *memFileInfo) Size() int64 { |
| 109 | return fi.contentSize | 103 | return fi.contentSize |
| 110 | } | 104 | } |
| 111 | 105 | ||
| 112 | // Mode returns file mode. | 106 | // Mode returns file mode. |
| 113 | func (fi *MemFileInfo) Mode() os.FileMode { | 107 | func (fi *memFileInfo) Mode() os.FileMode { |
| 114 | return fi.Mode() | 108 | return fi.Mode() |
| 115 | } | 109 | } |
| 116 | 110 | ||
| 117 | // ModTime returns the last modified time of raw file. | 111 | // ModTime returns the last modified time of raw file. |
| 118 | func (fi *MemFileInfo) ModTime() time.Time { | 112 | func (fi *memFileInfo) ModTime() time.Time { |
| 119 | return fi.modTime | 113 | return fi.modTime |
| 120 | } | 114 | } |
| 121 | 115 | ||
| 122 | // IsDir returns the compressing file is a directory or not. | 116 | // IsDir returns the compressing file is a directory or not. |
| 123 | func (fi *MemFileInfo) IsDir() bool { | 117 | func (fi *memFileInfo) IsDir() bool { |
| 124 | return fi.IsDir() | 118 | return fi.IsDir() |
| 125 | } | 119 | } |
| 126 | 120 | ||
| 127 | // return nil. implement the os.FileInfo interface method. | 121 | // return nil. implement the os.FileInfo interface method. |
| 128 | func (fi *MemFileInfo) Sys() interface{} { | 122 | func (fi *memFileInfo) Sys() interface{} { |
| 129 | return nil | 123 | return nil |
| 130 | } | 124 | } |
| 131 | 125 | ||
| 132 | // MemFile contains MemFileInfo and bytes offset when reading. | 126 | // MemFile contains MemFileInfo and bytes offset when reading. |
| 133 | // it implements io.Reader,io.ReadCloser and io.Seeker. | 127 | // it implements io.Reader,io.ReadCloser and io.Seeker. |
| 134 | type MemFile struct { | 128 | type memFile struct { |
| 135 | fi *MemFileInfo | 129 | fi *memFileInfo |
| 136 | offset int64 | 130 | offset int64 |
| 137 | } | 131 | } |
| 138 | 132 | ||
| 139 | // Close memfile. | 133 | // Close memfile. |
| 140 | func (f *MemFile) Close() error { | 134 | func (f *memFile) Close() error { |
| 141 | return nil | 135 | return nil |
| 142 | } | 136 | } |
| 143 | 137 | ||
| 144 | // Get os.FileInfo of memfile. | 138 | // Get os.FileInfo of memfile. |
| 145 | func (f *MemFile) Stat() (os.FileInfo, error) { | 139 | func (f *memFile) Stat() (os.FileInfo, error) { |
| 146 | return f.fi, nil | 140 | return f.fi, nil |
| 147 | } | 141 | } |
| 148 | 142 | ||
| 149 | // read os.FileInfo of files in directory of memfile. | 143 | // read os.FileInfo of files in directory of memfile. |
| 150 | // it returns empty slice. | 144 | // it returns empty slice. |
| 151 | func (f *MemFile) Readdir(count int) ([]os.FileInfo, error) { | 145 | func (f *memFile) Readdir(count int) ([]os.FileInfo, error) { |
| 152 | infos := []os.FileInfo{} | 146 | infos := []os.FileInfo{} |
| 153 | 147 | ||
| 154 | return infos, nil | 148 | return infos, nil |
| 155 | } | 149 | } |
| 156 | 150 | ||
| 157 | // Read bytes from the compressed file bytes. | 151 | // Read bytes from the compressed file bytes. |
| 158 | func (f *MemFile) Read(p []byte) (n int, err error) { | 152 | func (f *memFile) Read(p []byte) (n int, err error) { |
| 159 | if len(f.fi.content)-int(f.offset) >= len(p) { | 153 | if len(f.fi.content)-int(f.offset) >= len(p) { |
| 160 | n = len(p) | 154 | n = len(p) |
| 161 | } else { | 155 | } else { |
| ... | @@ -171,7 +165,7 @@ var errWhence = errors.New("Seek: invalid whence") | ... | @@ -171,7 +165,7 @@ var errWhence = errors.New("Seek: invalid whence") |
| 171 | var errOffset = errors.New("Seek: invalid offset") | 165 | var errOffset = errors.New("Seek: invalid offset") |
| 172 | 166 | ||
| 173 | // Read bytes from the compressed file bytes by seeker. | 167 | // Read bytes from the compressed file bytes by seeker. |
| 174 | func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) { | 168 | func (f *memFile) Seek(offset int64, whence int) (ret int64, err error) { |
| 175 | switch whence { | 169 | switch whence { |
| 176 | default: | 170 | default: |
| 177 | return 0, errWhence | 171 | return 0, errWhence |
| ... | @@ -191,7 +185,7 @@ func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) { | ... | @@ -191,7 +185,7 @@ func (f *MemFile) Seek(offset int64, whence int) (ret int64, err error) { |
| 191 | // GetAcceptEncodingZip returns accept encoding format in http header. | 185 | // GetAcceptEncodingZip returns accept encoding format in http header. |
| 192 | // zip is first, then deflate if both accepted. | 186 | // zip is first, then deflate if both accepted. |
| 193 | // If no accepted, return empty string. | 187 | // If no accepted, return empty string. |
| 194 | func GetAcceptEncodingZip(r *http.Request) string { | 188 | func getAcceptEncodingZip(r *http.Request) string { |
| 195 | ss := r.Header.Get("Accept-Encoding") | 189 | ss := r.Header.Get("Accept-Encoding") |
| 196 | ss = strings.ToLower(ss) | 190 | ss = strings.ToLower(ss) |
| 197 | if strings.Contains(ss, "gzip") { | 191 | if strings.Contains(ss, "gzip") { |
| ... | @@ -203,22 +197,3 @@ func GetAcceptEncodingZip(r *http.Request) string { | ... | @@ -203,22 +197,3 @@ func GetAcceptEncodingZip(r *http.Request) string { |
| 203 | } | 197 | } |
| 204 | return "" | 198 | return "" |
| 205 | } | 199 | } |
| 206 | |||
| 207 | // CloseZWriter closes the io.Writer after compressing static file. | ||
| 208 | func CloseZWriter(zwriter io.Writer) { | ||
| 209 | if zwriter == nil { | ||
| 210 | return | ||
| 211 | } | ||
| 212 | |||
| 213 | switch zwriter.(type) { | ||
| 214 | case *gzip.Writer: | ||
| 215 | zwriter.(*gzip.Writer).Close() | ||
| 216 | case *flate.Writer: | ||
| 217 | zwriter.(*flate.Writer).Close() | ||
| 218 | //其他情况不close, 保持和默认(非压缩)行为一致 | ||
| 219 | /* | ||
| 220 | case io.WriteCloser: | ||
| 221 | zwriter.(io.WriteCloser).Close() | ||
| 222 | */ | ||
| 223 | } | ||
| 224 | } | ... | ... |
| ... | @@ -7,8 +7,6 @@ import ( | ... | @@ -7,8 +7,6 @@ import ( |
| 7 | "net" | 7 | "net" |
| 8 | "net/http" | 8 | "net/http" |
| 9 | "net/url" | 9 | "net/url" |
| 10 | "os" | ||
| 11 | "path" | ||
| 12 | "reflect" | 10 | "reflect" |
| 13 | "regexp" | 11 | "regexp" |
| 14 | "runtime" | 12 | "runtime" |
| ... | @@ -33,7 +31,7 @@ const ( | ... | @@ -33,7 +31,7 @@ const ( |
| 33 | 31 | ||
| 34 | var ( | 32 | var ( |
| 35 | // supported http methods. | 33 | // supported http methods. |
| 36 | HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head"} | 34 | HTTPMETHOD = []string{"get", "post", "put", "delete", "patch", "options", "head", "trace", "connect"} |
| 37 | // these beego.Controller's methods shouldn't reflect to AutoRouter | 35 | // these beego.Controller's methods shouldn't reflect to AutoRouter |
| 38 | exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", | 36 | exceptMethod = []string{"Init", "Prepare", "Finish", "Render", "RenderString", |
| 39 | "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", | 37 | "RenderBytes", "Redirect", "Abort", "StopRun", "UrlFor", "ServeJson", "ServeJsonp", |
| ... | @@ -544,88 +542,26 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -544,88 +542,26 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 544 | http.Error(w, "Method Not Allowed", 405) | 542 | http.Error(w, "Method Not Allowed", 405) |
| 545 | goto Admin | 543 | goto Admin |
| 546 | } | 544 | } |
| 547 | |||
| 548 | if do_filter(BeforeRouter) { | ||
| 549 | goto Admin | ||
| 550 | } | ||
| 551 | |||
| 552 | //static file server | 545 | //static file server |
| 553 | for prefix, staticDir := range StaticDir { | 546 | if serverStaticRouter(context) { |
| 554 | if len(prefix) == 0 { | ||
| 555 | continue | ||
| 556 | } | ||
| 557 | if r.URL.Path == "/favicon.ico" { | ||
| 558 | file := path.Join(staticDir, r.URL.Path) | ||
| 559 | if utils.FileExists(file) { | ||
| 560 | http.ServeFile(w, r, file) | ||
| 561 | w.started = true | ||
| 562 | goto Admin | ||
| 563 | } | ||
| 564 | } | ||
| 565 | if strings.HasPrefix(r.URL.Path, prefix) { | ||
| 566 | if len(r.URL.Path) > len(prefix) && r.URL.Path[len(prefix)] != '/' { | ||
| 567 | continue | ||
| 568 | } | ||
| 569 | if r.URL.Path == prefix && prefix[len(prefix)-1] != '/' { | ||
| 570 | http.Redirect(rw, r, r.URL.Path+"/", 302) | ||
| 571 | goto Admin | ||
| 572 | } | ||
| 573 | file := path.Join(staticDir, r.URL.Path[len(prefix):]) | ||
| 574 | finfo, err := os.Stat(file) | ||
| 575 | if err != nil { | ||
| 576 | if RunMode == "dev" { | ||
| 577 | Warn(err) | ||
| 578 | } | ||
| 579 | http.NotFound(w, r) | ||
| 580 | goto Admin | ||
| 581 | } | ||
| 582 | //if the request is dir and DirectoryIndex is false then | ||
| 583 | if finfo.IsDir() && !DirectoryIndex { | ||
| 584 | middleware.Exception("403", rw, r, "403 Forbidden") | ||
| 585 | goto Admin | 547 | goto Admin |
| 586 | } | 548 | } |
| 587 | 549 | ||
| 588 | //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request | 550 | if context.Input.IsPost() { |
| 589 | isStaticFileToCompress := false | 551 | if CopyRequestBody && !context.Input.IsUpload() { |
| 590 | if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { | 552 | context.Input.CopyBody() |
| 591 | for _, statExtension := range StaticExtensionsToGzip { | ||
| 592 | if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { | ||
| 593 | isStaticFileToCompress = true | ||
| 594 | break | ||
| 595 | } | ||
| 596 | } | 553 | } |
| 554 | context.Input.ParseFormOrMulitForm(MaxMemory) | ||
| 597 | } | 555 | } |
| 598 | 556 | ||
| 599 | if isStaticFileToCompress { | 557 | if do_filter(BeforeRouter) { |
| 600 | if EnableGzip { | ||
| 601 | w.contentEncoding = GetAcceptEncodingZip(r) | ||
| 602 | } | ||
| 603 | |||
| 604 | memzipfile, err := OpenMemZipFile(file, w.contentEncoding) | ||
| 605 | if err != nil { | ||
| 606 | return | ||
| 607 | } | ||
| 608 | |||
| 609 | w.InitHeadContent(finfo.Size()) | ||
| 610 | |||
| 611 | http.ServeContent(w, r, file, finfo.ModTime(), memzipfile) | ||
| 612 | } else { | ||
| 613 | http.ServeFile(w, r, file) | ||
| 614 | } | ||
| 615 | |||
| 616 | w.started = true | ||
| 617 | goto Admin | 558 | goto Admin |
| 618 | } | 559 | } |
| 619 | } | ||
| 620 | 560 | ||
| 621 | if do_filter(AfterStatic) { | 561 | if do_filter(AfterStatic) { |
| 622 | goto Admin | 562 | goto Admin |
| 623 | } | 563 | } |
| 624 | 564 | ||
| 625 | if CopyRequestBody { | ||
| 626 | context.Input.Body() | ||
| 627 | } | ||
| 628 | |||
| 629 | if context.Input.RunController != nil && context.Input.RunMethod != "" { | 565 | if context.Input.RunController != nil && context.Input.RunMethod != "" { |
| 630 | findrouter = true | 566 | findrouter = true |
| 631 | runMethod = context.Input.RunMethod | 567 | runMethod = context.Input.RunMethod |
| ... | @@ -757,9 +693,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -757,9 +693,6 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 757 | } | 693 | } |
| 758 | 694 | ||
| 759 | if findrouter { | 695 | if findrouter { |
| 760 | if r.Method == "POST" { | ||
| 761 | r.ParseMultipartForm(MaxMemory) | ||
| 762 | } | ||
| 763 | //execute middleware filters | 696 | //execute middleware filters |
| 764 | if do_filter(BeforeExec) { | 697 | if do_filter(BeforeExec) { |
| 765 | goto Admin | 698 | goto Admin |
| ... | @@ -830,9 +763,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) | ... | @@ -830,9 +763,8 @@ func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) |
| 830 | } | 763 | } |
| 831 | } | 764 | } |
| 832 | 765 | ||
| 833 | Admin: | ||
| 834 | do_filter(FinishRouter) | 766 | do_filter(FinishRouter) |
| 835 | 767 | Admin: | |
| 836 | //admin module record QPS | 768 | //admin module record QPS |
| 837 | if EnableAdmin { | 769 | if EnableAdmin { |
| 838 | timeend := time.Since(starttime) | 770 | timeend := time.Since(starttime) |
| ... | @@ -894,7 +826,6 @@ type responseWriter struct { | ... | @@ -894,7 +826,6 @@ type responseWriter struct { |
| 894 | writer http.ResponseWriter | 826 | writer http.ResponseWriter |
| 895 | started bool | 827 | started bool |
| 896 | status int | 828 | status int |
| 897 | contentEncoding string | ||
| 898 | } | 829 | } |
| 899 | 830 | ||
| 900 | // Header returns the header map that will be sent by WriteHeader. | 831 | // Header returns the header map that will be sent by WriteHeader. |
| ... | @@ -902,17 +833,6 @@ func (w *responseWriter) Header() http.Header { | ... | @@ -902,17 +833,6 @@ func (w *responseWriter) Header() http.Header { |
| 902 | return w.writer.Header() | 833 | return w.writer.Header() |
| 903 | } | 834 | } |
| 904 | 835 | ||
| 905 | // Init content-length header. | ||
| 906 | func (w *responseWriter) InitHeadContent(contentlength int64) { | ||
| 907 | if w.contentEncoding == "gzip" { | ||
| 908 | w.Header().Set("Content-Encoding", "gzip") | ||
| 909 | } else if w.contentEncoding == "deflate" { | ||
| 910 | w.Header().Set("Content-Encoding", "deflate") | ||
| 911 | } else { | ||
| 912 | w.Header().Set("Content-Length", strconv.FormatInt(contentlength, 10)) | ||
| 913 | } | ||
| 914 | } | ||
| 915 | |||
| 916 | // Write writes the data to the connection as part of an HTTP reply, | 836 | // Write writes the data to the connection as part of an HTTP reply, |
| 917 | // and sets `started` to true. | 837 | // and sets `started` to true. |
| 918 | // started means the response has sent out. | 838 | // started means the response has sent out. | ... | ... |
| 1 | package session | 1 | package session |
| 2 | 2 | ||
| 3 | import ( | 3 | import ( |
| 4 | "github.com/couchbaselabs/go-couchbase" | ||
| 5 | "net/http" | 4 | "net/http" |
| 6 | "strings" | 5 | "strings" |
| 7 | "sync" | 6 | "sync" |
| 7 | |||
| 8 | "github.com/couchbaselabs/go-couchbase" | ||
| 9 | |||
| 10 | "github.com/astaxie/beego/session" | ||
| 8 | ) | 11 | ) |
| 9 | 12 | ||
| 10 | var couchbpder = &CouchbaseProvider{} | 13 | var couchbpder = &CouchbaseProvider{} |
| ... | @@ -70,7 +73,7 @@ func (cs *CouchbaseSessionStore) SessionRelease(w http.ResponseWriter) { | ... | @@ -70,7 +73,7 @@ func (cs *CouchbaseSessionStore) SessionRelease(w http.ResponseWriter) { |
| 70 | return | 73 | return |
| 71 | } | 74 | } |
| 72 | 75 | ||
| 73 | bo, err := encodeGob(cs.values) | 76 | bo, err := session.EncodeGob(cs.values) |
| 74 | if err != nil { | 77 | if err != nil { |
| 75 | return | 78 | return |
| 76 | } | 79 | } |
| ... | @@ -117,7 +120,7 @@ func (cp *CouchbaseProvider) SessionInit(maxlifetime int64, savePath string) err | ... | @@ -117,7 +120,7 @@ func (cp *CouchbaseProvider) SessionInit(maxlifetime int64, savePath string) err |
| 117 | } | 120 | } |
| 118 | 121 | ||
| 119 | // read couchbase session by sid | 122 | // read couchbase session by sid |
| 120 | func (cp *CouchbaseProvider) SessionRead(sid string) (SessionStore, error) { | 123 | func (cp *CouchbaseProvider) SessionRead(sid string) (session.SessionStore, error) { |
| 121 | cp.b = cp.getBucket() | 124 | cp.b = cp.getBucket() |
| 122 | 125 | ||
| 123 | var doc []byte | 126 | var doc []byte |
| ... | @@ -127,7 +130,7 @@ func (cp *CouchbaseProvider) SessionRead(sid string) (SessionStore, error) { | ... | @@ -127,7 +130,7 @@ func (cp *CouchbaseProvider) SessionRead(sid string) (SessionStore, error) { |
| 127 | if doc == nil { | 130 | if doc == nil { |
| 128 | kv = make(map[interface{}]interface{}) | 131 | kv = make(map[interface{}]interface{}) |
| 129 | } else { | 132 | } else { |
| 130 | kv, err = decodeGob(doc) | 133 | kv, err = session.DecodeGob(doc) |
| 131 | if err != nil { | 134 | if err != nil { |
| 132 | return nil, err | 135 | return nil, err |
| 133 | } | 136 | } |
| ... | @@ -150,7 +153,7 @@ func (cp *CouchbaseProvider) SessionExist(sid string) bool { | ... | @@ -150,7 +153,7 @@ func (cp *CouchbaseProvider) SessionExist(sid string) bool { |
| 150 | } | 153 | } |
| 151 | } | 154 | } |
| 152 | 155 | ||
| 153 | func (cp *CouchbaseProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { | 156 | func (cp *CouchbaseProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { |
| 154 | cp.b = cp.getBucket() | 157 | cp.b = cp.getBucket() |
| 155 | 158 | ||
| 156 | var doc []byte | 159 | var doc []byte |
| ... | @@ -172,7 +175,7 @@ func (cp *CouchbaseProvider) SessionRegenerate(oldsid, sid string) (SessionStore | ... | @@ -172,7 +175,7 @@ func (cp *CouchbaseProvider) SessionRegenerate(oldsid, sid string) (SessionStore |
| 172 | if doc == nil { | 175 | if doc == nil { |
| 173 | kv = make(map[interface{}]interface{}) | 176 | kv = make(map[interface{}]interface{}) |
| 174 | } else { | 177 | } else { |
| 175 | kv, err = decodeGob(doc) | 178 | kv, err = session.DecodeGob(doc) |
| 176 | if err != nil { | 179 | if err != nil { |
| 177 | return nil, err | 180 | return nil, err |
| 178 | } | 181 | } |
| ... | @@ -199,5 +202,5 @@ func (cp *CouchbaseProvider) SessionAll() int { | ... | @@ -199,5 +202,5 @@ func (cp *CouchbaseProvider) SessionAll() int { |
| 199 | } | 202 | } |
| 200 | 203 | ||
| 201 | func init() { | 204 | func init() { |
| 202 | Register("couchbase", couchbpder) | 205 | session.Register("couchbase", couchbpder) |
| 203 | } | 206 | } | ... | ... |
| ... | @@ -14,6 +14,8 @@ import ( | ... | @@ -14,6 +14,8 @@ import ( |
| 14 | "sync" | 14 | "sync" |
| 15 | "time" | 15 | "time" |
| 16 | 16 | ||
| 17 | "github.com/astaxie/beego/session" | ||
| 18 | |||
| 17 | _ "github.com/go-sql-driver/mysql" | 19 | _ "github.com/go-sql-driver/mysql" |
| 18 | ) | 20 | ) |
| 19 | 21 | ||
| ... | @@ -73,7 +75,7 @@ func (st *MysqlSessionStore) SessionID() string { | ... | @@ -73,7 +75,7 @@ func (st *MysqlSessionStore) SessionID() string { |
| 73 | // must call this method to save values to database. | 75 | // must call this method to save values to database. |
| 74 | func (st *MysqlSessionStore) SessionRelease(w http.ResponseWriter) { | 76 | func (st *MysqlSessionStore) SessionRelease(w http.ResponseWriter) { |
| 75 | defer st.c.Close() | 77 | defer st.c.Close() |
| 76 | b, err := encodeGob(st.values) | 78 | b, err := session.EncodeGob(st.values) |
| 77 | if err != nil { | 79 | if err != nil { |
| 78 | return | 80 | return |
| 79 | } | 81 | } |
| ... | @@ -106,7 +108,7 @@ func (mp *MysqlProvider) SessionInit(maxlifetime int64, savePath string) error { | ... | @@ -106,7 +108,7 @@ func (mp *MysqlProvider) SessionInit(maxlifetime int64, savePath string) error { |
| 106 | } | 108 | } |
| 107 | 109 | ||
| 108 | // get mysql session by sid | 110 | // get mysql session by sid |
| 109 | func (mp *MysqlProvider) SessionRead(sid string) (SessionStore, error) { | 111 | func (mp *MysqlProvider) SessionRead(sid string) (session.SessionStore, error) { |
| 110 | c := mp.connectInit() | 112 | c := mp.connectInit() |
| 111 | row := c.QueryRow("select session_data from session where session_key=?", sid) | 113 | row := c.QueryRow("select session_data from session where session_key=?", sid) |
| 112 | var sessiondata []byte | 114 | var sessiondata []byte |
| ... | @@ -119,7 +121,7 @@ func (mp *MysqlProvider) SessionRead(sid string) (SessionStore, error) { | ... | @@ -119,7 +121,7 @@ func (mp *MysqlProvider) SessionRead(sid string) (SessionStore, error) { |
| 119 | if len(sessiondata) == 0 { | 121 | if len(sessiondata) == 0 { |
| 120 | kv = make(map[interface{}]interface{}) | 122 | kv = make(map[interface{}]interface{}) |
| 121 | } else { | 123 | } else { |
| 122 | kv, err = decodeGob(sessiondata) | 124 | kv, err = session.DecodeGob(sessiondata) |
| 123 | if err != nil { | 125 | if err != nil { |
| 124 | return nil, err | 126 | return nil, err |
| 125 | } | 127 | } |
| ... | @@ -143,7 +145,7 @@ func (mp *MysqlProvider) SessionExist(sid string) bool { | ... | @@ -143,7 +145,7 @@ func (mp *MysqlProvider) SessionExist(sid string) bool { |
| 143 | } | 145 | } |
| 144 | 146 | ||
| 145 | // generate new sid for mysql session | 147 | // generate new sid for mysql session |
| 146 | func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { | 148 | func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { |
| 147 | c := mp.connectInit() | 149 | c := mp.connectInit() |
| 148 | row := c.QueryRow("select session_data from session where session_key=?", oldsid) | 150 | row := c.QueryRow("select session_data from session where session_key=?", oldsid) |
| 149 | var sessiondata []byte | 151 | var sessiondata []byte |
| ... | @@ -156,7 +158,7 @@ func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er | ... | @@ -156,7 +158,7 @@ func (mp *MysqlProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er |
| 156 | if len(sessiondata) == 0 { | 158 | if len(sessiondata) == 0 { |
| 157 | kv = make(map[interface{}]interface{}) | 159 | kv = make(map[interface{}]interface{}) |
| 158 | } else { | 160 | } else { |
| 159 | kv, err = decodeGob(sessiondata) | 161 | kv, err = session.DecodeGob(sessiondata) |
| 160 | if err != nil { | 162 | if err != nil { |
| 161 | return nil, err | 163 | return nil, err |
| 162 | } | 164 | } |
| ... | @@ -194,5 +196,5 @@ func (mp *MysqlProvider) SessionAll() int { | ... | @@ -194,5 +196,5 @@ func (mp *MysqlProvider) SessionAll() int { |
| 194 | } | 196 | } |
| 195 | 197 | ||
| 196 | func init() { | 198 | func init() { |
| 197 | Register("mysql", mysqlpder) | 199 | session.Register("mysql", mysqlpder) |
| 198 | } | 200 | } | ... | ... |
| ... | @@ -34,6 +34,9 @@ import ( | ... | @@ -34,6 +34,9 @@ import ( |
| 34 | "net/http" | 34 | "net/http" |
| 35 | "sync" | 35 | "sync" |
| 36 | "time" | 36 | "time" |
| 37 | |||
| 38 | "github.com/astaxie/beego/session" | ||
| 39 | |||
| 37 | _ "github.com/lib/pq" | 40 | _ "github.com/lib/pq" |
| 38 | ) | 41 | ) |
| 39 | 42 | ||
| ... | @@ -93,7 +96,7 @@ func (st *PostgresqlSessionStore) SessionID() string { | ... | @@ -93,7 +96,7 @@ func (st *PostgresqlSessionStore) SessionID() string { |
| 93 | // must call this method to save values to database. | 96 | // must call this method to save values to database. |
| 94 | func (st *PostgresqlSessionStore) SessionRelease(w http.ResponseWriter) { | 97 | func (st *PostgresqlSessionStore) SessionRelease(w http.ResponseWriter) { |
| 95 | defer st.c.Close() | 98 | defer st.c.Close() |
| 96 | b, err := encodeGob(st.values) | 99 | b, err := session.EncodeGob(st.values) |
| 97 | if err != nil { | 100 | if err != nil { |
| 98 | return | 101 | return |
| 99 | } | 102 | } |
| ... | @@ -126,7 +129,7 @@ func (mp *PostgresqlProvider) SessionInit(maxlifetime int64, savePath string) er | ... | @@ -126,7 +129,7 @@ func (mp *PostgresqlProvider) SessionInit(maxlifetime int64, savePath string) er |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | // get postgresql session by sid | 131 | // get postgresql session by sid |
| 129 | func (mp *PostgresqlProvider) SessionRead(sid string) (SessionStore, error) { | 132 | func (mp *PostgresqlProvider) SessionRead(sid string) (session.SessionStore, error) { |
| 130 | c := mp.connectInit() | 133 | c := mp.connectInit() |
| 131 | row := c.QueryRow("select session_data from session where session_key=$1", sid) | 134 | row := c.QueryRow("select session_data from session where session_key=$1", sid) |
| 132 | var sessiondata []byte | 135 | var sessiondata []byte |
| ... | @@ -146,7 +149,7 @@ func (mp *PostgresqlProvider) SessionRead(sid string) (SessionStore, error) { | ... | @@ -146,7 +149,7 @@ func (mp *PostgresqlProvider) SessionRead(sid string) (SessionStore, error) { |
| 146 | if len(sessiondata) == 0 { | 149 | if len(sessiondata) == 0 { |
| 147 | kv = make(map[interface{}]interface{}) | 150 | kv = make(map[interface{}]interface{}) |
| 148 | } else { | 151 | } else { |
| 149 | kv, err = decodeGob(sessiondata) | 152 | kv, err = session.DecodeGob(sessiondata) |
| 150 | if err != nil { | 153 | if err != nil { |
| 151 | return nil, err | 154 | return nil, err |
| 152 | } | 155 | } |
| ... | @@ -171,7 +174,7 @@ func (mp *PostgresqlProvider) SessionExist(sid string) bool { | ... | @@ -171,7 +174,7 @@ func (mp *PostgresqlProvider) SessionExist(sid string) bool { |
| 171 | } | 174 | } |
| 172 | 175 | ||
| 173 | // generate new sid for postgresql session | 176 | // generate new sid for postgresql session |
| 174 | func (mp *PostgresqlProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { | 177 | func (mp *PostgresqlProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { |
| 175 | c := mp.connectInit() | 178 | c := mp.connectInit() |
| 176 | row := c.QueryRow("select session_data from session where session_key=$1", oldsid) | 179 | row := c.QueryRow("select session_data from session where session_key=$1", oldsid) |
| 177 | var sessiondata []byte | 180 | var sessiondata []byte |
| ... | @@ -185,7 +188,7 @@ func (mp *PostgresqlProvider) SessionRegenerate(oldsid, sid string) (SessionStor | ... | @@ -185,7 +188,7 @@ func (mp *PostgresqlProvider) SessionRegenerate(oldsid, sid string) (SessionStor |
| 185 | if len(sessiondata) == 0 { | 188 | if len(sessiondata) == 0 { |
| 186 | kv = make(map[interface{}]interface{}) | 189 | kv = make(map[interface{}]interface{}) |
| 187 | } else { | 190 | } else { |
| 188 | kv, err = decodeGob(sessiondata) | 191 | kv, err = session.DecodeGob(sessiondata) |
| 189 | if err != nil { | 192 | if err != nil { |
| 190 | return nil, err | 193 | return nil, err |
| 191 | } | 194 | } |
| ... | @@ -223,5 +226,5 @@ func (mp *PostgresqlProvider) SessionAll() int { | ... | @@ -223,5 +226,5 @@ func (mp *PostgresqlProvider) SessionAll() int { |
| 223 | } | 226 | } |
| 224 | 227 | ||
| 225 | func init() { | 228 | func init() { |
| 226 | Register("postgresql", postgresqlpder) | 229 | session.Register("postgresql", postgresqlpder) |
| 227 | } | 230 | } | ... | ... |
| ... | @@ -6,6 +6,8 @@ import ( | ... | @@ -6,6 +6,8 @@ import ( |
| 6 | "strings" | 6 | "strings" |
| 7 | "sync" | 7 | "sync" |
| 8 | 8 | ||
| 9 | "github.com/astaxie/beego/session" | ||
| 10 | |||
| 9 | "github.com/beego/redigo/redis" | 11 | "github.com/beego/redigo/redis" |
| 10 | ) | 12 | ) |
| 11 | 13 | ||
| ... | @@ -77,7 +79,7 @@ func (rs *RedisSessionStore) SessionRelease(w http.ResponseWriter) { | ... | @@ -77,7 +79,7 @@ func (rs *RedisSessionStore) SessionRelease(w http.ResponseWriter) { |
| 77 | return | 79 | return |
| 78 | } | 80 | } |
| 79 | 81 | ||
| 80 | b, err := encodeGob(rs.values) | 82 | b, err := session.EncodeGob(rs.values) |
| 81 | if err != nil { | 83 | if err != nil { |
| 82 | return | 84 | return |
| 83 | } | 85 | } |
| ... | @@ -134,7 +136,7 @@ func (rp *RedisProvider) SessionInit(maxlifetime int64, savePath string) error { | ... | @@ -134,7 +136,7 @@ func (rp *RedisProvider) SessionInit(maxlifetime int64, savePath string) error { |
| 134 | } | 136 | } |
| 135 | 137 | ||
| 136 | // read redis session by sid | 138 | // read redis session by sid |
| 137 | func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) { | 139 | func (rp *RedisProvider) SessionRead(sid string) (session.SessionStore, error) { |
| 138 | c := rp.poollist.Get() | 140 | c := rp.poollist.Get() |
| 139 | defer c.Close() | 141 | defer c.Close() |
| 140 | 142 | ||
| ... | @@ -143,7 +145,7 @@ func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) { | ... | @@ -143,7 +145,7 @@ func (rp *RedisProvider) SessionRead(sid string) (SessionStore, error) { |
| 143 | if len(kvs) == 0 { | 145 | if len(kvs) == 0 { |
| 144 | kv = make(map[interface{}]interface{}) | 146 | kv = make(map[interface{}]interface{}) |
| 145 | } else { | 147 | } else { |
| 146 | kv, err = decodeGob([]byte(kvs)) | 148 | kv, err = session.DecodeGob([]byte(kvs)) |
| 147 | if err != nil { | 149 | if err != nil { |
| 148 | return nil, err | 150 | return nil, err |
| 149 | } | 151 | } |
| ... | @@ -166,7 +168,7 @@ func (rp *RedisProvider) SessionExist(sid string) bool { | ... | @@ -166,7 +168,7 @@ func (rp *RedisProvider) SessionExist(sid string) bool { |
| 166 | } | 168 | } |
| 167 | 169 | ||
| 168 | // generate new sid for redis session | 170 | // generate new sid for redis session |
| 169 | func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, error) { | 171 | func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (session.SessionStore, error) { |
| 170 | c := rp.poollist.Get() | 172 | c := rp.poollist.Get() |
| 171 | defer c.Close() | 173 | defer c.Close() |
| 172 | 174 | ||
| ... | @@ -185,7 +187,7 @@ func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er | ... | @@ -185,7 +187,7 @@ func (rp *RedisProvider) SessionRegenerate(oldsid, sid string) (SessionStore, er |
| 185 | if len(kvs) == 0 { | 187 | if len(kvs) == 0 { |
| 186 | kv = make(map[interface{}]interface{}) | 188 | kv = make(map[interface{}]interface{}) |
| 187 | } else { | 189 | } else { |
| 188 | kv, err = decodeGob([]byte(kvs)) | 190 | kv, err = session.DecodeGob([]byte(kvs)) |
| 189 | if err != nil { | 191 | if err != nil { |
| 190 | return nil, err | 192 | return nil, err |
| 191 | } | 193 | } |
| ... | @@ -215,5 +217,5 @@ func (rp *RedisProvider) SessionAll() int { | ... | @@ -215,5 +217,5 @@ func (rp *RedisProvider) SessionAll() int { |
| 215 | } | 217 | } |
| 216 | 218 | ||
| 217 | func init() { | 219 | func init() { |
| 218 | Register("redis", redispder) | 220 | session.Register("redis", redispder) |
| 219 | } | 221 | } | ... | ... |
| ... | @@ -70,7 +70,7 @@ func (fs *FileSessionStore) SessionID() string { | ... | @@ -70,7 +70,7 @@ func (fs *FileSessionStore) SessionID() string { |
| 70 | // Write file session to local file with Gob string | 70 | // Write file session to local file with Gob string |
| 71 | func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { | 71 | func (fs *FileSessionStore) SessionRelease(w http.ResponseWriter) { |
| 72 | defer fs.f.Close() | 72 | defer fs.f.Close() |
| 73 | b, err := encodeGob(fs.values) | 73 | b, err := EncodeGob(fs.values) |
| 74 | if err != nil { | 74 | if err != nil { |
| 75 | return | 75 | return |
| 76 | } | 76 | } |
| ... | @@ -123,7 +123,7 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) { | ... | @@ -123,7 +123,7 @@ func (fp *FileProvider) SessionRead(sid string) (SessionStore, error) { |
| 123 | if len(b) == 0 { | 123 | if len(b) == 0 { |
| 124 | kv = make(map[interface{}]interface{}) | 124 | kv = make(map[interface{}]interface{}) |
| 125 | } else { | 125 | } else { |
| 126 | kv, err = decodeGob(b) | 126 | kv, err = DecodeGob(b) |
| 127 | if err != nil { | 127 | if err != nil { |
| 128 | return nil, err | 128 | return nil, err |
| 129 | } | 129 | } |
| ... | @@ -222,7 +222,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err | ... | @@ -222,7 +222,7 @@ func (fp *FileProvider) SessionRegenerate(oldsid, sid string) (SessionStore, err |
| 222 | if len(b) == 0 { | 222 | if len(b) == 0 { |
| 223 | kv = make(map[interface{}]interface{}) | 223 | kv = make(map[interface{}]interface{}) |
| 224 | } else { | 224 | } else { |
| 225 | kv, err = decodeGob(b) | 225 | kv, err = DecodeGob(b) |
| 226 | if err != nil { | 226 | if err != nil { |
| 227 | return nil, err | 227 | return nil, err |
| 228 | } | 228 | } | ... | ... |
| ... | @@ -10,11 +10,11 @@ func Test_gob(t *testing.T) { | ... | @@ -10,11 +10,11 @@ func Test_gob(t *testing.T) { |
| 10 | a := make(map[interface{}]interface{}) | 10 | a := make(map[interface{}]interface{}) |
| 11 | a["username"] = "astaxie" | 11 | a["username"] = "astaxie" |
| 12 | a[12] = 234 | 12 | a[12] = 234 |
| 13 | b, err := encodeGob(a) | 13 | b, err := EncodeGob(a) |
| 14 | if err != nil { | 14 | if err != nil { |
| 15 | t.Error(err) | 15 | t.Error(err) |
| 16 | } | 16 | } |
| 17 | c, err := decodeGob(b) | 17 | c, err := DecodeGob(b) |
| 18 | if err != nil { | 18 | if err != nil { |
| 19 | t.Error(err) | 19 | t.Error(err) |
| 20 | } | 20 | } | ... | ... |
| ... | @@ -27,7 +27,7 @@ func init() { | ... | @@ -27,7 +27,7 @@ func init() { |
| 27 | gob.Register(map[int]int64{}) | 27 | gob.Register(map[int]int64{}) |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | func encodeGob(obj map[interface{}]interface{}) ([]byte, error) { | 30 | func EncodeGob(obj map[interface{}]interface{}) ([]byte, error) { |
| 31 | buf := bytes.NewBuffer(nil) | 31 | buf := bytes.NewBuffer(nil) |
| 32 | enc := gob.NewEncoder(buf) | 32 | enc := gob.NewEncoder(buf) |
| 33 | err := enc.Encode(obj) | 33 | err := enc.Encode(obj) |
| ... | @@ -37,7 +37,7 @@ func encodeGob(obj map[interface{}]interface{}) ([]byte, error) { | ... | @@ -37,7 +37,7 @@ func encodeGob(obj map[interface{}]interface{}) ([]byte, error) { |
| 37 | return buf.Bytes(), nil | 37 | return buf.Bytes(), nil |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | func decodeGob(encoded []byte) (map[interface{}]interface{}, error) { | 40 | func DecodeGob(encoded []byte) (map[interface{}]interface{}, error) { |
| 41 | buf := bytes.NewBuffer(encoded) | 41 | buf := bytes.NewBuffer(encoded) |
| 42 | dec := gob.NewDecoder(buf) | 42 | dec := gob.NewDecoder(buf) |
| 43 | var out map[interface{}]interface{} | 43 | var out map[interface{}]interface{} |
| ... | @@ -97,8 +97,8 @@ func decrypt(block cipher.Block, value []byte) ([]byte, error) { | ... | @@ -97,8 +97,8 @@ func decrypt(block cipher.Block, value []byte) ([]byte, error) { |
| 97 | func encodeCookie(block cipher.Block, hashKey, name string, value map[interface{}]interface{}) (string, error) { | 97 | func encodeCookie(block cipher.Block, hashKey, name string, value map[interface{}]interface{}) (string, error) { |
| 98 | var err error | 98 | var err error |
| 99 | var b []byte | 99 | var b []byte |
| 100 | // 1. encodeGob. | 100 | // 1. EncodeGob. |
| 101 | if b, err = encodeGob(value); err != nil { | 101 | if b, err = EncodeGob(value); err != nil { |
| 102 | return "", err | 102 | return "", err |
| 103 | } | 103 | } |
| 104 | // 2. Encrypt (optional). | 104 | // 2. Encrypt (optional). |
| ... | @@ -158,8 +158,8 @@ func decodeCookie(block cipher.Block, hashKey, name, value string, gcmaxlifetime | ... | @@ -158,8 +158,8 @@ func decodeCookie(block cipher.Block, hashKey, name, value string, gcmaxlifetime |
| 158 | if b, err = decrypt(block, b); err != nil { | 158 | if b, err = decrypt(block, b); err != nil { |
| 159 | return nil, err | 159 | return nil, err |
| 160 | } | 160 | } |
| 161 | // 5. decodeGob. | 161 | // 5. DecodeGob. |
| 162 | if dst, err := decodeGob(b); err != nil { | 162 | if dst, err := DecodeGob(b); err != nil { |
| 163 | return nil, err | 163 | return nil, err |
| 164 | } else { | 164 | } else { |
| 165 | return dst, nil | 165 | return dst, nil | ... | ... |
staticfile.go
0 → 100644
| 1 | package beego | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "net/http" | ||
| 5 | "os" | ||
| 6 | "path" | ||
| 7 | "strconv" | ||
| 8 | "strings" | ||
| 9 | |||
| 10 | "github.com/astaxie/beego/context" | ||
| 11 | "github.com/astaxie/beego/middleware" | ||
| 12 | "github.com/astaxie/beego/utils" | ||
| 13 | ) | ||
| 14 | |||
| 15 | func serverStaticRouter(ctx *context.Context) bool { | ||
| 16 | requestPath := path.Clean(ctx.Input.Request.URL.Path) | ||
| 17 | for prefix, staticDir := range StaticDir { | ||
| 18 | if len(prefix) == 0 { | ||
| 19 | continue | ||
| 20 | } | ||
| 21 | if requestPath == "/favicon.ico" { | ||
| 22 | file := path.Join(staticDir, requestPath) | ||
| 23 | if utils.FileExists(file) { | ||
| 24 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) | ||
| 25 | return true | ||
| 26 | } | ||
| 27 | } | ||
| 28 | if strings.HasPrefix(requestPath, prefix) { | ||
| 29 | if len(requestPath) > len(prefix) && requestPath[len(prefix)] != '/' { | ||
| 30 | continue | ||
| 31 | } | ||
| 32 | if requestPath == prefix && prefix[len(prefix)-1] != '/' { | ||
| 33 | http.Redirect(ctx.ResponseWriter, ctx.Request, requestPath+"/", 302) | ||
| 34 | return true | ||
| 35 | } | ||
| 36 | file := path.Join(staticDir, requestPath[len(prefix):]) | ||
| 37 | finfo, err := os.Stat(file) | ||
| 38 | if err != nil { | ||
| 39 | if RunMode == "dev" { | ||
| 40 | Warn(err) | ||
| 41 | } | ||
| 42 | http.NotFound(ctx.ResponseWriter, ctx.Request) | ||
| 43 | return true | ||
| 44 | } | ||
| 45 | //if the request is dir and DirectoryIndex is false then | ||
| 46 | if finfo.IsDir() && !DirectoryIndex { | ||
| 47 | middleware.Exception("403", ctx.ResponseWriter, ctx.Request, "403 Forbidden") | ||
| 48 | return true | ||
| 49 | } | ||
| 50 | |||
| 51 | //This block obtained from (https://github.com/smithfox/beego) - it should probably get merged into astaxie/beego after a pull request | ||
| 52 | isStaticFileToCompress := false | ||
| 53 | if StaticExtensionsToGzip != nil && len(StaticExtensionsToGzip) > 0 { | ||
| 54 | for _, statExtension := range StaticExtensionsToGzip { | ||
| 55 | if strings.HasSuffix(strings.ToLower(file), strings.ToLower(statExtension)) { | ||
| 56 | isStaticFileToCompress = true | ||
| 57 | break | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | if isStaticFileToCompress { | ||
| 63 | var contentEncoding string | ||
| 64 | if EnableGzip { | ||
| 65 | contentEncoding = getAcceptEncodingZip(ctx.Request) | ||
| 66 | } | ||
| 67 | |||
| 68 | memzipfile, err := openMemZipFile(file, contentEncoding) | ||
| 69 | if err != nil { | ||
| 70 | return true | ||
| 71 | } | ||
| 72 | |||
| 73 | if contentEncoding == "gzip" { | ||
| 74 | ctx.Output.Header("Content-Encoding", "gzip") | ||
| 75 | } else if contentEncoding == "deflate" { | ||
| 76 | ctx.Output.Header("Content-Encoding", "deflate") | ||
| 77 | } else { | ||
| 78 | ctx.Output.Header("Content-Length", strconv.FormatInt(finfo.Size(), 10)) | ||
| 79 | } | ||
| 80 | |||
| 81 | http.ServeContent(ctx.ResponseWriter, ctx.Request, file, finfo.ModTime(), memzipfile) | ||
| 82 | |||
| 83 | } else { | ||
| 84 | http.ServeFile(ctx.ResponseWriter, ctx.Request, file) | ||
| 85 | } | ||
| 86 | return true | ||
| 87 | } | ||
| 88 | } | ||
| 89 | return false | ||
| 90 | } |
| 1 | // most reference from github.com/realint/dbgutil | 1 | // Here are the features: healthcheck, profile, statistics and task. |
| 2 | package toolbox | 2 | package toolbox |
| 3 | 3 | ||
| 4 | import ( | 4 | import ( |
| ... | @@ -34,7 +34,6 @@ func Display(data ...interface{}) { | ... | @@ -34,7 +34,6 @@ func Display(data ...interface{}) { |
| 34 | display(true, data...) | 34 | display(true, data...) |
| 35 | } | 35 | } |
| 36 | 36 | ||
| 37 | |||
| 38 | // return data print string | 37 | // return data print string |
| 39 | func GetDisplayString(data ...interface{}) string { | 38 | func GetDisplayString(data ...interface{}) string { |
| 40 | return display(false, data...) | 39 | return display(false, data...) | ... | ... |
-
Please register or sign in to post a comment