github.com/gramework/gramework@v1.8.1-0.20231027140105-82555c9057f5/app_handler.go (about)

     1  // Copyright 2017-present Kirill Danshin and Gramework contributors
     2  // Copyright 2019-present Highload LTD (UK CN: 11893420)
     3  //
     4  // Licensed under the Apache License, Version 2.0 (the "License");
     5  // you may not use this file except in compliance with the License.
     6  // You may obtain a copy of the License at
     7  //
     8  //     http://www.apache.org/licenses/LICENSE-2.0
     9  //
    10  
    11  package gramework
    12  
    13  import (
    14  	"github.com/apex/log"
    15  	"github.com/google/uuid"
    16  	"github.com/valyala/fasthttp"
    17  )
    18  
    19  func (app *App) handler() func(*fasthttp.RequestCtx) {
    20  	return func(fhctx *fasthttp.RequestCtx) {
    21  		if app.EnableFirewall {
    22  			app.firewallInit.Do(func() {
    23  				app.initFirewall()
    24  			})
    25  		}
    26  
    27  		ctx := app.defaultRouter.initGrameCtx(fhctx)
    28  		if app.EnableFirewall {
    29  			if shouldBeBlocked, _ := app.firewall.NewRequest(ctx); shouldBeBlocked {
    30  				ctx.SetConnectionClose()
    31  				releaseCtx(ctx)
    32  				return
    33  			}
    34  		}
    35  
    36  		xReqID := ctx.Request.Header.Peek(xRequestID)
    37  		if len(xReqID) > 0 {
    38  			ctx.requestID = string(xReqID)
    39  		} else {
    40  			ctx.requestID = uuid.New().String()
    41  		}
    42  
    43  		tracer := ctx.Logger.
    44  			WithFields(log.Fields{
    45  				"package":  "gramework",
    46  				"method":   BytesToString(ctx.Method()),
    47  				"path":     BytesToString(ctx.Path()),
    48  				xRequestID: ctx.requestID,
    49  			})
    50  
    51  		if app.defaultRouter.router.PanicHandler != nil || !app.NoDefaultPanicHandler {
    52  			// unfortunately, we can't get rid of that defer
    53  			defer app.defaultRouter.router.Recv(ctx, tracer)
    54  		}
    55  
    56  		ctx.Response.Header.Add(xRequestID, ctx.requestID)
    57  		ctx.Logger = ctx.Logger.WithField(xRequestID, ctx.requestID)
    58  
    59  		ctx.loadCookies()
    60  		app.preMiddlewaresMu.RLock()
    61  		for k := range app.preMiddlewares {
    62  			app.preMiddlewares[k](ctx)
    63  		}
    64  
    65  		app.preMiddlewaresMu.RUnlock()
    66  		if ctx.middlewareKilledReq {
    67  			ctx.saveCookies()
    68  			tracer.
    69  				WithField("status", ctx.Response.StatusCode()).
    70  				Debug("middleware stopped processing")
    71  			releaseCtx(ctx)
    72  			return
    73  		}
    74  		ctx.middlewaresShouldStopProcessing = false
    75  		app.middlewaresMu.RLock()
    76  		for k := range app.middlewares {
    77  			app.middlewares[k](ctx)
    78  			if ctx.middlewaresShouldStopProcessing {
    79  				break
    80  			}
    81  		}
    82  
    83  		app.middlewaresMu.RUnlock()
    84  		if ctx.middlewareKilledReq {
    85  			ctx.saveCookies()
    86  			tracer.
    87  				WithField("status", ctx.Response.StatusCode()).
    88  				Debug("middleware stopped processing")
    89  			releaseCtx(ctx)
    90  			return
    91  		}
    92  		if len(app.domains) > 0 {
    93  			app.domainListLock.RLock()
    94  			if app.domains[string(ctx.URI().Host())] != nil {
    95  				app.domainListLock.RUnlock()
    96  				app.domains[string(ctx.URI().Host())].handler(ctx)
    97  				app.runMiddlewaresAfterRequest(ctx)
    98  				ctx.saveCookies()
    99  				tracer.
   100  					WithField("status", ctx.Response.StatusCode()).
   101  					Debug("request processed")
   102  				return
   103  			}
   104  
   105  			app.domainListLock.RUnlock()
   106  			if !app.HandleUnknownDomains {
   107  				ctx.NotFound()
   108  				app.runMiddlewaresAfterRequest(ctx)
   109  				ctx.saveCookies()
   110  				tracer.
   111  					WithField("status", ctx.Response.StatusCode()).
   112  					Debug("request processed")
   113  				releaseCtx(ctx)
   114  				return
   115  			}
   116  		}
   117  
   118  		app.defaultRouter.handler(ctx)
   119  		app.runMiddlewaresAfterRequest(ctx)
   120  		ctx.saveCookies()
   121  		tracer.
   122  			WithField("status", ctx.Response.StatusCode()).
   123  			Debug("request processed")
   124  		releaseCtx(ctx)
   125  	}
   126  }
   127  
   128  func (app *App) runMiddlewaresAfterRequest(ctx *Context) {
   129  	app.middlewaresAfterRequestMu.RLock()
   130  	for k := range app.middlewaresAfterRequest {
   131  		app.middlewaresAfterRequest[k](ctx)
   132  		if ctx.middlewaresShouldStopProcessing {
   133  			break
   134  		}
   135  	}
   136  
   137  	app.middlewaresAfterRequestMu.RUnlock()
   138  }