Implement database handshake protocol in RPC layer
- Add ExpectedDB field to RPC Request - Server validates client's expected DB matches daemon's DB - Return clear error on mismatch with both paths - Old clients (no ExpectedDB) still work with warning - Add Path() method to storage.Storage interface - Tests verify cross-database connections rejected Prevents database pollution when client connects to wrong daemon. Amp-Thread-ID: https://ampcode.com/threads/T-c4454192-39c6-4c67-96a9-675cbfc4db92 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -18,6 +18,7 @@ type Client struct {
|
||||
conn net.Conn
|
||||
socketPath string
|
||||
timeout time.Duration
|
||||
dbPath string // Expected database path for validation
|
||||
}
|
||||
|
||||
// TryConnect attempts to connect to the daemon socket
|
||||
@@ -92,21 +93,34 @@ func (c *Client) SetTimeout(timeout time.Duration) {
|
||||
c.timeout = timeout
|
||||
}
|
||||
|
||||
// SetDatabasePath sets the expected database path for validation
|
||||
func (c *Client) SetDatabasePath(dbPath string) {
|
||||
c.dbPath = dbPath
|
||||
}
|
||||
|
||||
// Execute sends an RPC request and waits for a response
|
||||
func (c *Client) Execute(operation string, args interface{}) (*Response, error) {
|
||||
return c.ExecuteWithCwd(operation, args, "")
|
||||
}
|
||||
|
||||
// ExecuteWithCwd sends an RPC request with an explicit cwd (or current dir if empty string)
|
||||
func (c *Client) ExecuteWithCwd(operation string, args interface{}, cwd string) (*Response, error) {
|
||||
argsJSON, err := json.Marshal(args)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal args: %w", err)
|
||||
}
|
||||
|
||||
// Get current working directory for database routing
|
||||
cwd, _ := os.Getwd()
|
||||
// Use provided cwd, or get current working directory for database routing
|
||||
if cwd == "" {
|
||||
cwd, _ = os.Getwd()
|
||||
}
|
||||
|
||||
req := Request{
|
||||
Operation: operation,
|
||||
Args: argsJSON,
|
||||
ClientVersion: ClientVersion,
|
||||
Cwd: cwd,
|
||||
ExpectedDB: c.dbPath, // Send expected database path for validation
|
||||
}
|
||||
|
||||
reqJSON, err := json.Marshal(req)
|
||||
|
||||
Reference in New Issue
Block a user