mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-18 20:16:36 +00:00
Compare commits
1 Commits
0.18.0
...
proxy-with
Author | SHA1 | Date | |
---|---|---|---|
97c11b3f5d |
101
pkg/proxy.go
101
pkg/proxy.go
@ -1,11 +1,10 @@
|
|||||||
package pkg
|
package pkg
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"time"
|
"time"
|
||||||
@ -27,6 +26,10 @@ type Proxy struct {
|
|||||||
Port int
|
Port int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type proxyState struct {
|
||||||
|
Host string
|
||||||
|
}
|
||||||
|
|
||||||
// Start listening and forwarding HTTP to the host
|
// Start listening and forwarding HTTP to the host
|
||||||
func (p *Proxy) Start(gatewayChan chan string, done chan bool) error {
|
func (p *Proxy) Start(gatewayChan chan string, done chan bool) error {
|
||||||
tcp := p.Port
|
tcp := p.Port
|
||||||
@ -44,83 +47,37 @@ func (p *Proxy) Start(gatewayChan chan string, done chan bool) error {
|
|||||||
|
|
||||||
fmt.Printf("Gateway: %s\n", ps.Host)
|
fmt.Printf("Gateway: %s\n", ps.Host)
|
||||||
|
|
||||||
s := &http.Server{
|
l, err := net.Listen("tcp", fmt.Sprintf("0.0.0.0:%d", tcp))
|
||||||
Addr: fmt.Sprintf(":%d", tcp),
|
if err != nil {
|
||||||
ReadTimeout: p.Timeout,
|
log.Printf("Error: %s", err.Error())
|
||||||
WriteTimeout: p.Timeout,
|
return err
|
||||||
MaxHeaderBytes: 1 << 20, // Max header of 1MB
|
|
||||||
Handler: http.HandlerFunc(makeProxy(&ps)),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
go func() {
|
defer l.Close()
|
||||||
log.Printf("[proxy] Begin listen on %d\n", p.Port)
|
|
||||||
if err := s.ListenAndServe(); err != http.ErrServerClosed {
|
for {
|
||||||
log.Printf("Error ListenAndServe: %v", err)
|
// Wait for a connection.
|
||||||
|
conn, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
acceptErr := fmt.Errorf("Unable to accept on %d, error: %s", tcp, err.Error())
|
||||||
|
log.Printf("%s", acceptErr.Error())
|
||||||
|
return acceptErr
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
|
|
||||||
log.Println("[proxy] Wait for done")
|
upstream, err := net.Dial("tcp", fmt.Sprintf("%s", ps.Host))
|
||||||
<-done
|
|
||||||
log.Println("[proxy] Done received")
|
|
||||||
if err := s.Shutdown(context.Background()); err != nil {
|
|
||||||
log.Printf("[proxy] Error in Shutdown: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
if err != nil {
|
||||||
}
|
log.Printf("unable to dial to %s, error: %s", ps.Host, err.Error())
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
go pipe(conn, upstream)
|
||||||
|
go pipe(upstream, conn)
|
||||||
|
|
||||||
// copyHeaders clones the header values from the source into the destination.
|
|
||||||
func copyHeaders(destination http.Header, source *http.Header) {
|
|
||||||
for k, v := range *source {
|
|
||||||
vClone := make([]string, len(v))
|
|
||||||
copy(vClone, v)
|
|
||||||
destination[k] = vClone
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type proxyState struct {
|
func pipe(from net.Conn, to net.Conn) {
|
||||||
Host string
|
defer from.Close()
|
||||||
}
|
io.Copy(from, to)
|
||||||
|
|
||||||
func makeProxy(ps *proxyState) func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
|
||||||
|
|
||||||
query := ""
|
|
||||||
if len(r.URL.RawQuery) > 0 {
|
|
||||||
query = "?" + r.URL.RawQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
upstream := fmt.Sprintf("http://%s%s%s", ps.Host, r.URL.Path, query)
|
|
||||||
fmt.Printf("[faasd] proxy: %s\n", upstream)
|
|
||||||
|
|
||||||
if r.Body != nil {
|
|
||||||
defer r.Body.Close()
|
|
||||||
}
|
|
||||||
|
|
||||||
wrapper := ioutil.NopCloser(r.Body)
|
|
||||||
upReq, upErr := http.NewRequest(r.Method, upstream, wrapper)
|
|
||||||
|
|
||||||
copyHeaders(upReq.Header, &r.Header)
|
|
||||||
|
|
||||||
if upErr != nil {
|
|
||||||
log.Println(upErr)
|
|
||||||
|
|
||||||
http.Error(w, upErr.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
upRes, upResErr := http.DefaultClient.Do(upReq)
|
|
||||||
|
|
||||||
if upResErr != nil {
|
|
||||||
log.Println(upResErr)
|
|
||||||
|
|
||||||
http.Error(w, upResErr.Error(), http.StatusInternalServerError)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
copyHeaders(w.Header(), &upRes.Header)
|
|
||||||
|
|
||||||
w.WriteHeader(upRes.StatusCode)
|
|
||||||
io.Copy(w, upRes.Body)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user