srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/internal/ipc/ipc.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/ipc/ipc.go')
-rw-r--r--internal/ipc/ipc.go15
1 files changed, 15 insertions, 0 deletions
diff --git a/internal/ipc/ipc.go b/internal/ipc/ipc.go
index 691dadf..f890715 100644
--- a/internal/ipc/ipc.go
+++ b/internal/ipc/ipc.go
@@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"net"
+ "sync"
"mitmux/internal/store"
)
@@ -51,7 +52,15 @@ type EntryDetail struct {
// Client talks to a mitmuxd instance for request/response queries
// (list, get). Use Subscribe separately for the live-update stream.
+//
+// One request/response round trip is in flight on the connection at a
+// time, guarded by mu - a caller like the mitmux TUI dispatches each
+// request as its own goroutine (a Bubble Tea tea.Cmd), and without this
+// two overlapping calls (e.g. opening two entries in quick succession)
+// would interleave their JSON on the wire or hand one call the other's
+// response.
type Client struct {
+ mu sync.Mutex
conn net.Conn
dec *json.Decoder
enc *json.Encoder
@@ -84,6 +93,8 @@ func (c *Client) Search(query string, limit int, beforeID int64) ([]store.Summar
}
func (c *Client) list(req Request) ([]store.Summary, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
if err := c.enc.Encode(req); err != nil {
return nil, err
}
@@ -99,6 +110,8 @@ func (c *Client) list(req Request) ([]store.Summary, error) {
// Get returns the full entry (raw bytes included) for id.
func (c *Client) Get(id int64) (*EntryDetail, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
if err := c.enc.Encode(Request{Type: "get", ID: id}); err != nil {
return nil, err
}
@@ -116,6 +129,8 @@ func (c *Client) Get(id int64) (*EntryDetail, error) {
// no header injection) and returns the resulting entry, including the raw
// response bytes. The exchange is also recorded to history.
func (c *Client) Repeat(scheme, host string, raw []byte) (*EntryDetail, error) {
+ c.mu.Lock()
+ defer c.mu.Unlock()
if err := c.enc.Encode(Request{Type: "repeat", Scheme: scheme, Host: host, Raw: raw}); err != nil {
return nil, err
}