mirror of
https://github.com/buger/goreplay.git
synced 2024-04-21 12:32:02 +00:00
121 lines
2.0 KiB
Go
121 lines
2.0 KiB
Go
package main
|
|
|
|
import (
|
|
"bufio"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"os"
|
|
"os/exec"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Middleware struct {
|
|
command string
|
|
|
|
data chan []byte
|
|
|
|
mu sync.Mutex
|
|
|
|
Stdin io.Writer
|
|
Stdout io.Reader
|
|
}
|
|
|
|
func NewMiddleware(command string) *Middleware {
|
|
m := new(Middleware)
|
|
m.command = command
|
|
m.data = make(chan []byte, 1000)
|
|
|
|
commands := strings.Split(command, " ")
|
|
cmd := exec.Command(commands[0], commands[1:]...)
|
|
|
|
m.Stdout, _ = cmd.StdoutPipe()
|
|
m.Stdin, _ = cmd.StdinPipe()
|
|
|
|
if Settings.verbose {
|
|
cmd.Stderr = os.Stderr
|
|
}
|
|
|
|
go m.read(m.Stdout)
|
|
|
|
go func() {
|
|
err := cmd.Start()
|
|
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
err = cmd.Wait()
|
|
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}()
|
|
|
|
return m
|
|
}
|
|
|
|
func (m *Middleware) ReadFrom(plugin io.Reader) {
|
|
Debug("[MIDDLEWARE-MASTER] Starting reading from", plugin)
|
|
go m.copy(m.Stdin, plugin)
|
|
}
|
|
|
|
func (m *Middleware) copy(to io.Writer, from io.Reader) {
|
|
buf := make([]byte, 5*1024*1024)
|
|
dst := make([]byte, len(buf)*2)
|
|
|
|
for {
|
|
nr, _ := from.Read(buf)
|
|
if nr > 0 && len(buf) > nr {
|
|
|
|
hex.Encode(dst, buf[0:nr])
|
|
dst[nr*2] = '\n'
|
|
|
|
m.mu.Lock()
|
|
to.Write(dst[0 : nr*2+1])
|
|
m.mu.Unlock()
|
|
|
|
if Settings.debug {
|
|
Debug("[MIDDLEWARE-MASTER] Sending:", string(buf[0:nr]), "From:", from)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (m *Middleware) read(from io.Reader) {
|
|
scanner := bufio.NewScanner(from)
|
|
|
|
for scanner.Scan() {
|
|
bytes := scanner.Bytes()
|
|
buf := make([]byte, len(bytes)/2)
|
|
if _, err := hex.Decode(buf, bytes); err != nil {
|
|
fmt.Fprintln(os.Stderr, "Failed to decode input payload", err, len(bytes))
|
|
}
|
|
|
|
if Settings.debug {
|
|
Debug("[MIDDLEWARE-MASTER] Received:", string(buf))
|
|
}
|
|
|
|
m.data <- buf
|
|
}
|
|
|
|
if err := scanner.Err(); err != nil {
|
|
fmt.Fprintln(os.Stderr, "Traffic modifier command failed:", err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (m *Middleware) Read(data []byte) (int, error) {
|
|
buf := <-m.data
|
|
copy(data, buf)
|
|
|
|
return len(buf), nil
|
|
}
|
|
|
|
func (m *Middleware) String() string {
|
|
return fmt.Sprintf("Modifying traffic using '%s' command", m.command)
|
|
}
|