/ gcf.go
gcf.go
1 // Code from https://github.com/gofiber/recipes/blob/master/gcloud/functions.go 2 // Copyright by https://github.com/alvarowolfx and https://github.com/Fenny 3 4 package main 5 6 import ( 7 "bytes" 8 "context" 9 "fmt" 10 "io" 11 "io/ioutil" 12 "log" 13 "net" 14 "net/http" 15 "strings" 16 17 "github.com/gofiber/fiber/v2" 18 "github.com/valyala/fasthttp/fasthttputil" 19 ) 20 21 // CloudFunctionRouteToFiber route cloud function http.Handler to *fiber.App 22 // Internally, google calls the function with the /execute base URL 23 func CloudFunctionRouteToFiber(fiberApp *fiber.App, w http.ResponseWriter, r *http.Request) error { 24 return RouteToFiber(fiberApp, w, r, "/execute") 25 } 26 27 // RouteToFiber route http.Handler to *fiber.App 28 func RouteToFiber(fiberApp *fiber.App, w http.ResponseWriter, r *http.Request, rootURL ...string) error { 29 ln := fasthttputil.NewInmemoryListener() 30 defer ln.Close() 31 32 // Copy request 33 body, err := ioutil.ReadAll(r.Body) 34 if err != nil { 35 return err 36 } 37 38 url := fmt.Sprintf("%s://%s%s", "http", "0.0.0.0", r.RequestURI) 39 if len(rootURL) > 0 { 40 url = strings.Replace(url, rootURL[0], "", -1) 41 } 42 43 proxyReq, err := http.NewRequest(r.Method, url, bytes.NewReader(body)) 44 proxyReq.Header = r.Header 45 46 // Create http client 47 client := http.Client{ 48 Transport: &http.Transport{ 49 DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { 50 return ln.Dial() 51 }, 52 }, 53 } 54 55 // Serve request to internal HTTP client 56 go func() { 57 log.Fatal(fiberApp.Listener(ln)) 58 }() 59 60 // Call internal Fiber API 61 response, err := client.Do(proxyReq) 62 if err != nil { 63 return err 64 } 65 66 // Copy response and headers 67 for k, values := range response.Header { 68 for _, v := range values { 69 w.Header().Set(k, v) 70 } 71 } 72 w.WriteHeader(response.StatusCode) 73 74 io.Copy(w, response.Body) 75 response.Body.Close() 76 77 return nil 78 }