func (h *ClientHandler) ServeHTTP(reqCtx *fasthttp.RequestCtx) {

	// check for pre-cache validators, if at least one of them return false
	// for this specific request, then skip the whole cache
	if !h.rule.Claim(reqCtx) {
		h.bodyHandler(reqCtx)
		return
	}

	uri := &uri.URIBuilder{}
	uri.ServerAddr(h.remoteHandlerURL).ClientURI(string(reqCtx.URI().RequestURI())).ClientMethod(string(reqCtx.Method()))

	req := fasthttp.AcquireRequest()
	defer fasthttp.ReleaseRequest(req)
	req.URI().Update(uri.String())
	req.Header.SetMethodBytes(methodGetBytes)

	res := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseResponse(res)

	err := ClientFasthttp.Do(req, res)
	if err != nil || res.StatusCode() == cfg.FailStatus {

		//	println("lets execute the main fasthttp handler times: ")
		//	print(times)
		//		times++
		// if not found on cache, then execute the handler and save the cache to the remote server
		h.bodyHandler(reqCtx)

		// check if it's a valid response, if it's not then just return.
		if !h.rule.Valid(reqCtx) {
			return
		}

		// save to the remote cache

		body := reqCtx.Response.Body()[0:]
		if len(body) == 0 {
			return // do nothing..
		}
		req.Reset()

		uri.StatusCode(reqCtx.Response.StatusCode())
		uri.Lifetime(h.life)
		uri.ContentType(string(reqCtx.Response.Header.Peek(cfg.ContentTypeHeader)))

		req.URI().Update(uri.String())
		req.Header.SetMethodBytes(methodPostBytes)
		req.SetBody(body)

		//	go func() {
		//	println("[FASTHTTP] POST Do to the remote cache service with the url: " + req.URI().String() + " , method validation: " + string(req.Header.Method()))
		//	err := ClientFasthttp.Do(req, res)
		//	if err != nil {
		//	println("[FASTHTTP] ERROR WHEN POSTING TO SAVE THE CACHE ENTRY. TRACE: " + err.Error())
		//	}
		ClientFasthttp.Do(req, res)
		//	}()

	} else {
		// get the status code , content type and the write the response body
		statusCode := res.StatusCode()
		//	println("[FASTHTTP] ServeHTTP: WRITE WITH THE CACHED, StatusCode: ", statusCode)
		cType := res.Header.ContentType()
		reqCtx.SetStatusCode(statusCode)
		reqCtx.Response.Header.SetContentTypeBytes(cType)

		reqCtx.Write(res.Body())
	}

}
func (h *ClientHandler) ServeHTTP(reqCtx *fasthttp.RequestCtx) {

	
	
	if !h.rule.Claim(reqCtx) {
		h.bodyHandler(reqCtx)
		return
	}

	uri := &uri.URIBuilder{}
	uri.ServerAddr(h.remoteHandlerURL).ClientURI(string(reqCtx.URI().RequestURI())).ClientMethod(string(reqCtx.Method()))

	req := fasthttp.AcquireRequest()
	defer fasthttp.ReleaseRequest(req)
	req.URI().Update(uri.String())
	req.Header.SetMethodBytes(methodGetBytes)

	res := fasthttp.AcquireResponse()
	defer fasthttp.ReleaseResponse(res)

	err := ClientFasthttp.Do(req, res)
	if err != nil || res.StatusCode() == cfg.FailStatus {

		
		
		
		
		h.bodyHandler(reqCtx)

		
		if !h.rule.Valid(reqCtx) {
			return
		}

		

		body := reqCtx.Response.Body()[0:]
		if len(body) == 0 {
			return 
		}
		req.Reset()

		uri.StatusCode(reqCtx.Response.StatusCode())
		uri.Lifetime(h.life)
		uri.ContentType(string(reqCtx.Response.Header.Peek(cfg.ContentTypeHeader)))

		req.URI().Update(uri.String())
		req.Header.SetMethodBytes(methodPostBytes)
		req.SetBody(body)

		
		
		
		
		
		
		ClientFasthttp.Do(req, res)
		

	} else {
		
		statusCode := res.StatusCode()
		
		cType := res.Header.ContentType()
		reqCtx.SetStatusCode(statusCode)
		reqCtx.Response.Header.SetContentTypeBytes(cType)

		reqCtx.Write(res.Body())
	}

}
func ( h * ClientHandler ) ServeHTTP ( reqCtx * fasthttp . RequestCtx ) { // check for pre-cache validators, if at least one of them return false // for this specific request, then skip the whole cache if ! h . rule . Claim ( reqCtx ) { h . bodyHandler ( reqCtx ) return } uri := & uri . URIBuilder { } uri . ServerAddr ( h . remoteHandlerURL ) . ClientURI ( string ( reqCtx . URI ( ) . RequestURI ( ) ) ) . ClientMethod ( string ( reqCtx . Method ( ) ) ) req := fasthttp . AcquireRequest ( ) defer fasthttp . ReleaseRequest ( req ) req . URI ( ) . Update ( uri . String ( ) ) req . Header . SetMethodBytes ( methodGetBytes ) res := fasthttp . AcquireResponse ( ) defer fasthttp . ReleaseResponse ( res ) err := ClientFasthttp . Do ( req , res ) if err != nil || res . StatusCode ( ) == cfg . FailStatus { //	println("lets execute the main fasthttp handler times: ") //	print(times) //		times++ // if not found on cache, then execute the handler and save the cache to the remote server h . bodyHandler ( reqCtx ) // check if it's a valid response, if it's not then just return. if ! h . rule . Valid ( reqCtx ) { return } // save to the remote cache body := reqCtx . Response . Body ( ) [ 0 : ] if len ( body ) == 0 { return // do nothing.. } req . Reset ( ) uri . StatusCode ( reqCtx . Response . StatusCode ( ) ) uri . Lifetime ( h . life ) uri . ContentType ( string ( reqCtx . Response . Header . Peek ( cfg . ContentTypeHeader ) ) ) req . URI ( ) . Update ( uri . String ( ) ) req . Header . SetMethodBytes ( methodPostBytes ) req . SetBody ( body ) //	go func() { //	println("[FASTHTTP] POST Do to the remote cache service with the url: " + req.URI().String() + " , method validation: " + string(req.Header.Method())) //	err := ClientFasthttp.Do(req, res) //	if err != nil { //	println("[FASTHTTP] ERROR WHEN POSTING TO SAVE THE CACHE ENTRY. TRACE: " + err.Error()) //	} ClientFasthttp . Do ( req , res ) //	}() } else { // get the status code , content type and the write the response body statusCode := res . StatusCode ( ) //	println("[FASTHTTP] ServeHTTP: WRITE WITH THE CACHED, StatusCode: ", statusCode) cType := res . Header . ContentType ( ) reqCtx . SetStatusCode ( statusCode ) reqCtx . Response . Header . SetContentTypeBytes ( cType ) reqCtx . Write ( res . Body ( ) ) } }
// ServeHTTP , or remote cache client whatever you like, it's the client-side function of the ServeHTTP
// sends a request to the server-side remote cache Service and sends the cached response to the frontend client
// it is used only when you achieved something like horizontal scaling (separate machines)
// look ../remote/remote.ServeHTTP for more
//
// if cache din't find then it sends a POST request and save the bodyHandler's body to the remote cache.
//
// It takes 3 parameters
// the first is the remote address (it's the address you started your http server which handled by the Service.ServeHTTP)
// the second is the handler (or the mux) you want to cache
// and the  third is the, optionally, cache expiration,
// which is used to set cache duration of this specific cache entry to the remote cache service
// if <=minimumAllowedCacheDuration then the server will try to parse from "cache-control" header
//
// client-side function
ServeHTTP or remote cache client whatever you like it s the client - side function of the ServeHTTP sends a request to the server - side remote cache Service and sends the cached response to the frontend client it is used only when you achieved something like horizontal scaling ( separate machines ) look .. / remote / remote . ServeHTTP for more if cache din t find then it sends a POST request and save the bodyHandler s body to the remote cache . It takes 3 parameters the first is the remote address ( it s the address you started your http server which handled by the Service . ServeHTTP ) the second is the handler ( or the mux ) you want to cache and the third is the optionally cache expiration which is used to set cache duration of this specific cache entry to the remote cache service if < = minimumAllowedCacheDuration then the server will try to parse from cache - control header client - side function