@@ -9,11 +9,13 @@ import (
99 "flag"
1010 "fmt"
1111 "io/ioutil"
12+ "log"
1213 "net"
1314 "net/http"
1415 "net/http/httputil"
1516 "os"
1617 "os/exec"
18+ "reflect"
1719 "runtime"
1820 "strconv"
1921 "strings"
@@ -23,7 +25,7 @@ import (
2325)
2426
2527// Version of Fiber
26- const Version = "1.7.1 "
28+ const Version = "1.8.0 "
2729
2830type (
2931 // App denotes the Fiber application.
4648 CaseSensitive bool `default:"false"`
4749 // Enables the "Server: value" HTTP header.
4850 ServerHeader string `default:""`
51+ // Enables handler values to be immutable even if you return from handler
52+ Immutable bool `default:"false"`
4953 // fasthttp settings
5054 GETOnly bool `default:"false"`
5155 IdleTimeout time.Duration `default:"0"`
@@ -65,26 +69,40 @@ type (
6569 NoHeaderNormalizing bool `default:"false"`
6670 NoDefaultContentType bool `default:"false"`
6771 // template settings
68- ViewCache bool `default:"false"`
69- ViewFolder string `default:""`
70- ViewEngine string `default:""`
71- ViewExtension string `default:""`
72+ TemplateFolder string `default:""`
73+ TemplateEngine string `default:""`
74+ TemplateExtension string `default:""`
7275 }
7376)
7477
75- var prefork = flag .Bool ("fiber-prefork" , false , "use prefork" )
76- var child = flag .Bool ("fiber-child" , false , "is child process" )
78+ func init () {
79+ flag .Bool ("prefork" , false , "Use prefork" )
80+ flag .Bool ("child" , false , "Is a child process" )
81+ }
7782
78- // New ...
83+ // New : https://fiber.wiki/application#new
7984func New (settings ... * Settings ) (app * App ) {
80- flag .Parse ()
85+ var prefork bool
86+ var child bool
87+ for _ , arg := range os .Args [1 :] {
88+ if arg == "-prefork" {
89+ prefork = true
90+ } else if arg == "-child" {
91+ child = true
92+ }
93+ }
8194 app = & App {
82- child : * child ,
95+ child : child ,
8396 }
8497 if len (settings ) > 0 {
8598 opt := settings [0 ]
8699 if ! opt .Prefork {
87- opt .Prefork = * prefork
100+ opt .Prefork = prefork
101+ }
102+ if opt .Immutable {
103+ getString = func (b []byte ) string {
104+ return string (b )
105+ }
88106 }
89107 if opt .Concurrency == 0 {
90108 opt .Concurrency = 256 * 1024
@@ -102,7 +120,7 @@ func New(settings ...*Settings) (app *App) {
102120 return
103121 }
104122 app .Settings = & Settings {
105- Prefork : * prefork ,
123+ Prefork : prefork ,
106124 Concurrency : 256 * 1024 ,
107125 ReadBufferSize : 4096 ,
108126 WriteBufferSize : 4096 ,
@@ -111,94 +129,112 @@ func New(settings ...*Settings) (app *App) {
111129 return
112130}
113131
114- // Recover
115- func (app * App ) Recover (cb func (* Ctx )) {
116- app .recover = cb
117- }
118-
119- // Recover
120- func (grp * Group ) Recover (cb func (* Ctx )) {
121- grp .app .recover = cb
132+ // Group : https://fiber.wiki/application#group
133+ func (app * App ) Group (prefix string , handlers ... func (* Ctx )) * Group {
134+ if len (handlers ) > 0 {
135+ app .registerMethod ("USE" , prefix , "" , handlers ... )
136+ }
137+ return & Group {
138+ prefix : prefix ,
139+ app : app ,
140+ }
122141}
123142
124- // Static ...
143+ // Static : https://fiber.wiki/application#static
125144func (app * App ) Static (args ... string ) * App {
126145 app .registerStatic ("/" , args ... )
127146 return app
128147}
129148
130- // WebSocket ...
131- func (app * App ) WebSocket (args ... interface {}) * App {
132- app .register ("GET" , "" , args ... )
149+ // Use : https://fiber.wiki/application#http-methods
150+ func (app * App ) Use (args ... interface {}) * App {
151+ var path = ""
152+ var handlers []func (* Ctx )
153+ for i := 0 ; i < len (args ); i ++ {
154+ switch arg := args [i ].(type ) {
155+ case string :
156+ path = arg
157+ case func (* Ctx ):
158+ handlers = append (handlers , arg )
159+ default :
160+ log .Fatalf ("Invalid handler: %v" , reflect .TypeOf (arg ))
161+ }
162+ }
163+ app .registerMethod ("USE" , "" , path , handlers ... )
133164 return app
134165}
135166
136- // Connect ...
137- func (app * App ) Connect (args ... interface {} ) * App {
138- app .register ( "CONNECT" , "" , args ... )
167+ // Connect : https://fiber.wiki/application#http-methods
168+ func (app * App ) Connect (path string , handlers ... func ( * Ctx ) ) * App {
169+ app .registerMethod ( http . MethodConnect , "" , path , handlers ... )
139170 return app
140171}
141172
142- // Put ...
143- func (app * App ) Put (args ... interface {} ) * App {
144- app .register ( "PUT" , "" , args ... )
173+ // Put : https://fiber.wiki/application#http-methods
174+ func (app * App ) Put (path string , handlers ... func ( * Ctx ) ) * App {
175+ app .registerMethod ( http . MethodPut , "" , path , handlers ... )
145176 return app
146177}
147178
148- // Post ...
149- func (app * App ) Post (args ... interface {} ) * App {
150- app .register ( "POST" , "" , args ... )
179+ // Post : https://fiber.wiki/application#http-methods
180+ func (app * App ) Post (path string , handlers ... func ( * Ctx ) ) * App {
181+ app .registerMethod ( http . MethodPost , "" , path , handlers ... )
151182 return app
152183}
153184
154- // Delete ...
155- func (app * App ) Delete (args ... interface {} ) * App {
156- app .register ( "DELETE" , "" , args ... )
185+ // Delete : https://fiber.wiki/application#http-methods
186+ func (app * App ) Delete (path string , handlers ... func ( * Ctx ) ) * App {
187+ app .registerMethod ( http . MethodDelete , "" , path , handlers ... )
157188 return app
158189}
159190
160- // Head ...
161- func (app * App ) Head (args ... interface {} ) * App {
162- app .register ( "HEAD" , "" , args ... )
191+ // Head : https://fiber.wiki/application#http-methods
192+ func (app * App ) Head (path string , handlers ... func ( * Ctx ) ) * App {
193+ app .registerMethod ( http . MethodHead , "" , path , handlers ... )
163194 return app
164195}
165196
166- // Patch ...
167- func (app * App ) Patch (args ... interface {} ) * App {
168- app .register ( "PATCH" , "" , args ... )
197+ // Patch : https://fiber.wiki/application#http-methods
198+ func (app * App ) Patch (path string , handlers ... func ( * Ctx ) ) * App {
199+ app .registerMethod ( http . MethodPatch , "" , path , handlers ... )
169200 return app
170201}
171202
172- // Options ...
173- func (app * App ) Options (args ... interface {} ) * App {
174- app .register ( "OPTIONS" , "" , args ... )
203+ // Options : https://fiber.wiki/application#http-methods
204+ func (app * App ) Options (path string , handlers ... func ( * Ctx ) ) * App {
205+ app .registerMethod ( http . MethodOptions , "" , path , handlers ... )
175206 return app
176207}
177208
178- // Trace ...
179- func (app * App ) Trace (args ... interface {} ) * App {
180- app .register ( "TRACE" , "" , args ... )
209+ // Trace : https://fiber.wiki/application#http-methods
210+ func (app * App ) Trace (path string , handlers ... func ( * Ctx ) ) * App {
211+ app .registerMethod ( http . MethodTrace , "" , path , handlers ... )
181212 return app
182213}
183214
184- // Get ...
185- func (app * App ) Get (args ... interface {} ) * App {
186- app .register ( "GET" , "" , args ... )
215+ // Get : https://fiber.wiki/application#http-methods
216+ func (app * App ) Get (path string , handlers ... func ( * Ctx ) ) * App {
217+ app .registerMethod ( http . MethodGet , "" , path , handlers ... )
187218 return app
188219}
189220
190- // All ...
191- func (app * App ) All (args ... interface {} ) * App {
192- app .register ("ALL" , "" , args ... )
221+ // All : https://fiber.wiki/application#http-methods
222+ func (app * App ) All (path string , handlers ... func ( * Ctx ) ) * App {
223+ app .registerMethod ("ALL" , "" , path , handlers ... )
193224 return app
194225}
195226
196- // Use ...
197- func (app * App ) Use ( args ... interface {} ) * App {
198- app .register ( "USE" , "" , args ... )
227+ // WebSocket : https://fiber.wiki/application#websocket
228+ func (app * App ) WebSocket ( path string , handler func ( * Conn ) ) * App {
229+ app .registerWebSocket ( http . MethodGet , "" , path , handler )
199230 return app
200231}
201232
233+ // Recover : https://fiber.wiki/application#recover
234+ func (app * App ) Recover (handler func (* Ctx )) {
235+ app .recover = handler
236+ }
237+
202238// Listen : https://fiber.wiki/application#listen
203239func (app * App ) Listen (address interface {}, tls ... string ) error {
204240 addr , ok := address .(string )
@@ -214,10 +250,10 @@ func (app *App) Listen(address interface{}, tls ...string) error {
214250 }
215251 // Create fasthttp server
216252 app .server = app .newServer ()
217- // Print banner
218- // if app.Settings.Banner && !app.child {
219- // fmt.Printf("Fiber-%s is listening on %s\n", Version, addr)
220- // }
253+ // Print listening message
254+ if ! app .child {
255+ fmt .Printf ("Fiber v%s listening on %s\n " , Version , addr )
256+ }
221257 var ln net.Listener
222258 var err error
223259 // Prefork enabled
@@ -238,19 +274,19 @@ func (app *App) Listen(address interface{}, tls ...string) error {
238274 return app .server .Serve (ln )
239275}
240276
241- // Shutdown server gracefully
277+ // Shutdown : TODO: Docs
278+ // Shutsdown the server gracefully
242279func (app * App ) Shutdown () error {
243280 if app .server == nil {
244281 return fmt .Errorf ("Server is not running" )
245282 }
246283 return app .server .Shutdown ()
247284}
248285
249- // Test takes a http.Request and execute a fake connection to the application
250- // It returns a http.Response when the connection was successful
251- func (app * App ) Test (req * http.Request ) (* http.Response , error ) {
286+ // Test : https://fiber.wiki/application#test
287+ func (app * App ) Test (request * http.Request ) (* http.Response , error ) {
252288 // Get raw http request
253- reqRaw , err := httputil .DumpRequest (req , true )
289+ reqRaw , err := httputil .DumpRequest (request , true )
254290 if err != nil {
255291 return nil , err
256292 }
@@ -275,7 +311,7 @@ func (app *App) Test(req *http.Request) (*http.Response, error) {
275311 return nil , err
276312 }
277313 // Throw timeout error after 200ms
278- case <- time .After (1000 * time .Millisecond ):
314+ case <- time .After (200 * time .Millisecond ):
279315 return nil , fmt .Errorf ("timeout" )
280316 }
281317 // Get raw HTTP response
@@ -287,7 +323,7 @@ func (app *App) Test(req *http.Request) (*http.Response, error) {
287323 reader := strings .NewReader (getString (respRaw ))
288324 buffer := bufio .NewReader (reader )
289325 // Convert raw HTTP response to http.Response
290- resp , err := http .ReadResponse (buffer , req )
326+ resp , err := http .ReadResponse (buffer , request )
291327 if err != nil {
292328 return nil , err
293329 }
@@ -299,26 +335,26 @@ func (app *App) Test(req *http.Request) (*http.Response, error) {
299335func (app * App ) prefork (address string ) (ln net.Listener , err error ) {
300336 // Master proc
301337 if ! app .child {
302- addr , err := net .ResolveTCPAddr ("tcp " , address )
338+ addr , err := net .ResolveTCPAddr ("tcp4 " , address )
303339 if err != nil {
304340 return ln , err
305341 }
306- tcplistener , err := net .ListenTCP ("tcp " , addr )
342+ tcplistener , err := net .ListenTCP ("tcp4 " , addr )
307343 if err != nil {
308344 return ln , err
309345 }
310346 fl , err := tcplistener .File ()
311347 if err != nil {
312348 return ln , err
313349 }
350+ files := []* os.File {fl }
314351 childs := make ([]* exec.Cmd , runtime .NumCPU ()/ 2 )
315-
316352 // #nosec G204
317353 for i := range childs {
318- childs [i ] = exec .Command (os .Args [0 ], "-fiber- prefork" , "-fiber- child" )
354+ childs [i ] = exec .Command (os .Args [0 ], append ( os . Args [ 1 :], "- prefork" , "-child" ) ... )
319355 childs [i ].Stdout = os .Stdout
320356 childs [i ].Stderr = os .Stderr
321- childs [i ].ExtraFiles = [] * os. File { fl }
357+ childs [i ].ExtraFiles = files
322358 if err := childs [i ].Start (); err != nil {
323359 return ln , err
324360 }
@@ -331,6 +367,7 @@ func (app *App) prefork(address string) (ln net.Listener, err error) {
331367 }
332368 os .Exit (0 )
333369 } else {
370+ runtime .GOMAXPROCS (1 )
334371 ln , err = net .FileListener (os .NewFile (3 , "" ))
335372 }
336373 return ln , err
0 commit comments