Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support streaming text responses from functions #1828

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions gateway/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM --platform=${BUILDPLATFORM:-linux/amd64} ghcr.io/openfaas/license-check:0.4.1 as license-check

FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.20 as build
FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.21 as build

ENV GO111MODULE=on
ENV CGO_ENABLED=0
Expand Down Expand Up @@ -42,9 +42,9 @@ RUN CGO_ENABLED=${CGO_ENABLED} GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build --
-X \"github.com/openfaas/faas/gateway/version.GitCommitSHA=${GIT_COMMIT}\" \
-X \"github.com/openfaas/faas/gateway/version.Version=${VERSION}\" \
-X github.com/openfaas/faas/gateway/types.Arch=${TARGETARCH}" \
-a -installsuffix cgo -o gateway .
-o gateway .

FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.18.3 as ship
FROM --platform=${TARGETPLATFORM:-linux/amd64} alpine:3.19.0 as ship

LABEL org.label-schema.license="MIT" \
org.label-schema.vcs-url="https://github.com/openfaas/faas" \
Expand Down
12 changes: 11 additions & 1 deletion gateway/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export DOCKER_CLI_EXPERIMENTAL=enabled

PLATFORM := "linux/amd64,linux/arm/v7,linux/arm64"
PLATFORM?="linux/amd64,linux/arm/v7,linux/arm64"

TAG?=dev
SERVER?=ttl.sh
Expand All @@ -19,6 +19,16 @@ buildx-local:

.PHONY: buildx-push
buildx-push:
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
&& docker buildx create --use --name=multiarch --node multiarch \
&& docker buildx build \
--progress=plain \
--platform linux/amd64 \
--output "type=image,push=true" \
--tag $(SERVER)/$(OWNER)/$(NAME):$(TAG) .

.PHONY: buildx-push-all
buildx-push-all:
@echo $(SERVER)/$(OWNER)/$(NAME):$(TAG) \
&& docker buildx create --use --name=multiarch --node multiarch \
&& docker buildx build \
Expand Down
4 changes: 2 additions & 2 deletions gateway/go.mod
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
module github.com/openfaas/faas/gateway

go 1.20
go 1.21

require (
github.com/docker/distribution v2.8.3+incompatible
github.com/gorilla/mux v1.8.0
github.com/openfaas/faas-provider v0.24.4
github.com/openfaas/faas-provider v0.25.2
github.com/openfaas/nats-queue-worker v0.0.0-20231023101743-fa54e89c9db2
github.com/prometheus/client_golang v1.17.0
github.com/prometheus/client_model v0.5.0
Expand Down
2 changes: 2 additions & 0 deletions gateway/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,8 @@ github.com/openfaas/faas-provider v0.19.1 h1:xH8lTWabfDZwzIvC0u1AO48ghD3BNw6Vo23
github.com/openfaas/faas-provider v0.19.1/go.mod h1:Farrp+9Med8LeK3aoYpqplMP8f5ebTILbCSLg2LPLZk=
github.com/openfaas/faas-provider v0.24.4 h1:Zzbkabgd0PoQmnRjy53NbMXjhLaIyoIiwP3qaLkm9rE=
github.com/openfaas/faas-provider v0.24.4/go.mod h1:NsETIfEndZn4mn/w/XnBTcDTwKqULCziphLp7KgeRcA=
github.com/openfaas/faas-provider v0.25.2 h1:sAyL96CzAk/YnuXQZiRJcHo7UrcYMaf7RDvKxsQb/2o=
github.com/openfaas/faas-provider v0.25.2/go.mod h1:NsETIfEndZn4mn/w/XnBTcDTwKqULCziphLp7KgeRcA=
github.com/openfaas/nats-queue-worker v0.0.0-20230303171817-9dfe6fa61387 h1:D4xbdy309Wdyhlm6PgJqUV/aR77VQQG8UTF+q0ay71c=
github.com/openfaas/nats-queue-worker v0.0.0-20230303171817-9dfe6fa61387/go.mod h1:s86POyW6C8S4CALFRhO8ax5sR2uaQUJQ0HaQGvbTpTc=
github.com/openfaas/nats-queue-worker v0.0.0-20231023101743-fa54e89c9db2 h1:I8U2kq2h7Wl6pkd4hjRK6P0/o3AcCNdfmNJS5gdgxKU=
Expand Down
46 changes: 36 additions & 10 deletions gateway/handlers/forwarding_proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import (
"io"
"log"
"net/http"
"net/http/httputil"
"os"
"strings"
"time"

fhttputil "github.com/openfaas/faas-provider/httputil"
"github.com/openfaas/faas/gateway/pkg/middleware"
"github.com/openfaas/faas/gateway/types"
)
Expand All @@ -28,7 +31,10 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy,
writeRequestURI = exists
}

reverseProxy := makeRewriteProxy(baseURLResolver, urlPathTransformer)

return func(w http.ResponseWriter, r *http.Request) {

baseURL := baseURLResolver.Resolve(r)
originalURL := r.URL.String()
requestURL := urlPathTransformer.Transform(r)
Expand All @@ -39,13 +45,13 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy,

start := time.Now()

statusCode, err := forwardRequest(w, r, proxy.Client, baseURL, requestURL, proxy.Timeout, writeRequestURI, serviceAuthInjector)

seconds := time.Since(start)
statusCode, err := forwardRequest(w, r, proxy.Client, baseURL, requestURL, proxy.Timeout, writeRequestURI, serviceAuthInjector, reverseProxy)
if err != nil {
log.Printf("error with upstream request to: %s, %s\n", requestURL, err.Error())
}

seconds := time.Since(start)

for _, notifier := range notifiers {
notifier.Notify(r.Method, requestURL, originalURL, statusCode, "completed", seconds)
}
Expand Down Expand Up @@ -86,7 +92,12 @@ func forwardRequest(w http.ResponseWriter,
requestURL string,
timeout time.Duration,
writeRequestURI bool,
serviceAuthInjector middleware.AuthInjector) (int, error) {
serviceAuthInjector middleware.AuthInjector,
reverseProxy *httputil.ReverseProxy) (int, error) {

if r.Body != nil {
defer r.Body.Close()
}

upstreamReq := buildUpstreamRequest(r, baseURL, requestURL)
if upstreamReq.Body != nil {
Expand All @@ -101,14 +112,20 @@ func forwardRequest(w http.ResponseWriter,
log.Printf("forwardRequest: %s %s\n", upstreamReq.Host, upstreamReq.URL.String())
}

if strings.HasPrefix(r.Header.Get("Accept"), "text/event-stream") {
ww := fhttputil.NewHttpWriteInterceptor(w)
reverseProxy.ServeHTTP(ww, upstreamReq)
return ww.Status(), nil
}

ctx, cancel := context.WithTimeout(r.Context(), timeout)
defer cancel()

res, resErr := proxyClient.Do(upstreamReq.WithContext(ctx))
if resErr != nil {
res, err := proxyClient.Do(upstreamReq.WithContext(ctx))
if err != nil {
badStatus := http.StatusBadGateway
w.WriteHeader(badStatus)
return badStatus, resErr
return badStatus, err
}

if res.Body != nil {
Expand All @@ -117,12 +134,10 @@ func forwardRequest(w http.ResponseWriter,

copyHeaders(w.Header(), &res.Header)

// Write status code
w.WriteHeader(res.StatusCode)

if res.Body != nil {
// Copy the body over
io.CopyBuffer(w, res.Body, nil)
io.Copy(w, res.Body)
}

return res.StatusCode, nil
Expand Down Expand Up @@ -159,3 +174,14 @@ var hopHeaders = []string{
"Transfer-Encoding",
"Upgrade",
}

func makeRewriteProxy(baseURLResolver middleware.BaseURLResolver, urlPathTransformer middleware.URLPathTransformer) *httputil.ReverseProxy {
return &httputil.ReverseProxy{
ErrorLog: log.New(io.Discard, "proxy:", 0),
Transport: http.DefaultClient.Transport,
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
},
Director: func(r *http.Request) {
},
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion gateway/vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ github.com/nats-io/nuid
## explicit; go 1.14
github.com/nats-io/stan.go
github.com/nats-io/stan.go/pb
# github.com/openfaas/faas-provider v0.24.4
# github.com/openfaas/faas-provider v0.25.2
## explicit; go 1.20
github.com/openfaas/faas-provider/auth
github.com/openfaas/faas-provider/httputil
Expand Down