Skip to content

Commit

Permalink
feat: implemented daemonless mode
Browse files Browse the repository at this point in the history
This is a simpler mode of operation when only a single proxy is
required. Start and stop the whole program with a single command instead
of running in multiple terminals, etc.
  • Loading branch information
chetan committed Jul 20, 2022
1 parent 117588c commit 7bda280
Show file tree
Hide file tree
Showing 7 changed files with 52 additions and 11 deletions.
13 changes: 13 additions & 0 deletions bin/vproxy/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,24 @@ vproxy connect hello.local:8888 -- vproxy hello
Value: "127.0.0.1",
Usage: "Server host IP",
},
&cli.StringFlag{
Name: "listen",
Aliases: []string{"l"},
Value: "127.0.0.1",
Usage: "IP to listen on (when in single-client mode)",
Hidden: hideFlags,
},
&cli.IntFlag{
Name: "http",
Value: 80,
Usage: "Server HTTP port",
},
&cli.IntFlag{
Name: "https",
Value: 443,
Usage: "Server HTTPS port (when in single-client mode)",
Hidden: hideFlags,
},
&cli.StringSliceFlag{
Name: "bind",
Usage: "Bind hostname to local port (e.g., app.local.com:7000)",
Expand Down
24 changes: 22 additions & 2 deletions bin/vproxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"path/filepath"
"regexp"
"strings"
"time"

"github.com/jittering/truststore"
"github.com/jittering/vproxy"
Expand Down Expand Up @@ -38,7 +39,6 @@ func printVersion(c *cli.Context) error {
}

func connectVhost(c *cli.Context) error {

// collect and validate binds
args := c.Args().Slice()
binds := c.StringSlice("bind")
Expand Down Expand Up @@ -67,7 +67,27 @@ func connectVhost(c *cli.Context) error {

client := createClient(c)
if !client.IsDaemonRunning() {
return fmt.Errorf("daemon not running on localhost")
fmt.Println("[*] warning: daemon not running on localhost. running in single-client mode")

// start server with defaults
c.Set("listen", "127.0.0.1")
c.Set("https", "443")
go startDaemon(c)

// start command, if avail
client.RunCommand(args)

// wait for server
for {
if client.IsDaemonRunning() {
break
}
time.Sleep(100 * time.Millisecond)
}

// bind
client.AddBinding(binds[0], false)
return nil
}

client.AddBindings(binds, c.Bool("detach"), args)
Expand Down
16 changes: 11 additions & 5 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package vproxy
import (
"bufio"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -31,20 +32,20 @@ func (c *Client) AddBindings(binds []string, detach bool, args []string) {
os.Exit(1)
}

c.runCommand(args)
c.RunCommand(args)

c.wg = &sync.WaitGroup{}
for _, bind := range binds {
c.wg.Add(1)
go c.addBinding(bind, detach)
go c.AddBinding(bind, detach)
c.wg.Wait()
}

// c.wg.Add(1)
c.wg.Wait()
}

func (c *Client) runCommand(args []string) {
func (c *Client) RunCommand(args []string) {
// run command, if given
if len(args) == 0 {
return
Expand All @@ -66,7 +67,8 @@ func (c *Client) runCommand(args []string) {
}()
}

func (c *Client) addBinding(bind string, detach bool) {
// Add single binding. Blocks when detach=false
func (c *Client) AddBinding(bind string, detach bool) {
data := url.Values{}
data.Add("binding", bind)

Expand All @@ -81,13 +83,17 @@ func (c *Client) addBinding(bind string, detach bool) {
stopCommand(c.cmd)
log.Fatalf("error registering client: %s\n", err)
}
b, err := io.ReadAll(res.Body)
if err == nil {
fmt.Println(string(b))
}
res.Body.Close()

if detach {
c.wg.Done()
} else {
c.Tail(s[0], true)
}
res.Body.Close()
}

func (c *Client) Tail(hostname string, follow bool) {
Expand Down
1 change: 0 additions & 1 deletion cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ func runCommand(args []string) *exec.Cmd {
}

func stopCommand(cmd *exec.Cmd) {

if cmd == nil {
return
}
Expand Down
4 changes: 4 additions & 0 deletions daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,10 @@ func (d *Daemon) relayLogsUntilClose(vhost *Vhost, w http.ResponseWriter, reqCtx
return
}

// initial flush to open the stream
fmt.Fprint(w, "")
flusher.Flush()

logChan := vhost.NewLogListener()

// read existing logs first
Expand Down
4 changes: 2 additions & 2 deletions logged_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,15 @@ func (lh *LoggedHandler) CreateTLSConfig() *tls.Config {
// Add default internal cert
cert, err := tls.LoadX509KeyPair(lh.defaultCert, lh.defaultKey)
if err != nil {
log.Fatal("failed to load keypair:", err)
log.Fatal("failed to load internal keypair:", err)
}
cfg.Certificates = append(cfg.Certificates, cert)

// add cert for each vhost
for _, server := range lh.vhostMux.Servers {
cert, err := tls.LoadX509KeyPair(server.Cert, server.Key)
if err != nil {
log.Fatal("failed to load keypair:", err)
log.Fatalf("failed to load keypair (%s, %s): %s", server.Cert, server.Key, err)
}
cfg.Certificates = append(cfg.Certificates, cert)
}
Expand Down
1 change: 0 additions & 1 deletion simpleproxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ func (t *proxyTransport) RoundTrip(request *http.Request) (*http.Response, error
}

func createProxyTransport(targetURL url.URL, vhost string) *proxyTransport {
fmt.Println("creating new transport")
t := &proxyTransport{errMsg: fmt.Sprintf(badGatewayMessage, targetURL.String(), vhost)}
t.transport = http.DefaultTransport.(*http.Transport).Clone()
t.transport.MaxConnsPerHost = 0 // unlim
Expand Down

0 comments on commit 7bda280

Please sign in to comment.