You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: developer/README.md
+89-43Lines changed: 89 additions & 43 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,66 +6,112 @@ sidebar: false
6
6
7
7
A client library for xrDebug is easy to implement as any HTTP API. Client libraries are HTTP wrappers for interacting with xrDebug, making the configuration and usage trivial to end-users.
8
8
9
+
## Design considerations
10
+
11
+
- The client software is responsible for formatting the debug information.
12
+
- The "ID" field is used to identify messages and pauses. It should be unique for each message or pause, and it's up to the client to generate it.
13
+
9
14
## Message
10
15
11
-
To send messages is required to `POST /messages`. Code below outlines a `sendMessage` function.
16
+
To send messages use the `POST /messages` endpoint. In xrDebug is the client software which formats the debug information, so the server doesn't enforce any specific format. You can send any data you want, but it's recommended to use HTML.
12
17
13
-
```php
14
-
function sendMessage($data): void
15
-
{
16
-
// POST /messages
17
-
$curl = new Curl(/** on data **/);
18
-
$curl->exec();
19
-
// ...
20
-
}
21
-
```
18
+
## Pauses
19
+
20
+
Pauses allow you to temporarily halt program execution until a specific condition is met. They work in a two-state system:
22
21
23
-
## Pause
22
+
1. When a pause is created (`POST /pauses`), it starts with `stop: false`
23
+
2. The program enters a polling loop, checking the pause status (`GET /pauses/{id}`)
24
+
3. The pause can be released in two ways:
25
+
- Stopped (`PATCH /pauses/{id}`) - Sets `stop: true`, program should terminate
26
+
- Deleted (`DELETE /pauses/{id}`) - Removes the pause, program should continue
24
27
25
-
To implement pause is required to `POST /pauses` and sleep/wait while the `id` is paused. Code below outlines a `sendPause` and `isPaused` functions used on the PHP client.
28
+
### Example pause loop
26
29
27
30
```php
28
-
function sendPause(...$args): void
31
+
class PauseException extends Exception {}
32
+
33
+
function waitForPause(string $id): void
29
34
{
30
-
// POST /pauses
31
-
$curl = new Curl(/** on id **/);
32
-
$curl->exec();
33
-
$curlError = $curl->error();
34
-
// Ignore on error
35
-
if ($curlError !== '') {
36
-
return;
37
-
}
38
-
// Sleep while id is paused
39
-
do {
35
+
while (true) {
36
+
$response = http_get("/pauses/{$id}");
37
+
if (!$response) {
38
+
// Pause was deleted, continue execution
39
+
return;
40
+
}
41
+
if ($response->stop === true) {
42
+
// Pause was stopped, terminate execution
43
+
throw new PauseException("Execution stopped by debugger");
44
+
}
45
+
// Wait before next check
40
46
sleep(1);
41
-
} while (isPaused($id));
47
+
}
42
48
}
43
49
44
-
function isPaused($id): bool
50
+
try {
51
+
// Create pause
52
+
http_post("/pauses", ["id" => "debug-123"]);
53
+
// Wait for pause to be released
54
+
waitForPause("debug-123");
55
+
// Continue execution if pause was deleted
56
+
echo "Continuing...";
57
+
} catch (PauseException $e) {
58
+
echo "Execution stopped";
59
+
exit(1);
60
+
}
61
+
```
62
+
63
+
## Signed requests
64
+
65
+
Request signing using Ed25519 digital signatures to verify message origin authenticity.
66
+
67
+
To sign a request, the client must include the `X-Signature` header on requests made to the xrDebug server. The signature is a base64 encoded string generated by signing the serialized post fields with the private key. If there's no fields sign an empty string.
68
+
69
+
### Sign workflow
70
+
71
+
To sign a request server expect the following data workflow:
72
+
73
+
1. Sort the post fields by key
74
+
2. Concatenate the key-value pairs
75
+
3. Sign the concatenated string
76
+
4. Base64 encode the signature at `X-Signature` header
77
+
78
+
Example in PHP:
79
+
80
+
```php
81
+
function serialize(array $data): string
45
82
{
46
-
// POST /pauses/$id
47
-
$curl = new Curl(/** on id **/);
48
-
$curlExec = $curl->exec();
49
-
// Free pause on error
50
-
if (! $curlExec || $curl->error() !== '') {
51
-
return false;
52
-
}
53
-
// Read response {stop: true|false}
54
-
$response = json_decode($curlExec);
55
-
$stop = $response->stop ?? false;
56
-
// Stop execution on stop: true
57
-
if ($stop) {
58
-
throw new Exception();
83
+
$result = '';
84
+
ksort($data);
85
+
foreach ($data as $key => $value) {
86
+
$result .= $key . $value;
59
87
}
60
88
61
-
return true;
89
+
return $result;
62
90
}
91
+
92
+
$serialized = serialize($data);
93
+
$signature = $privateKey->sign($serialized);
94
+
$signHeader = base64_encode($signature);
63
95
```
64
96
65
-
## Singing requests
97
+
Example in Python:
66
98
67
-
`🚧 Work in progress`
99
+
```python
100
+
defserialize(data: dict) -> str:
101
+
return''.join(f'{k}{v}'for k, v insorted(data.items()))
68
102
69
-
## End-to-end encryption
103
+
serialized = serialize(data)
104
+
signature = private_key.sign(serialized)
105
+
signHeader = base64.b64encode(signature).decode()
106
+
```
107
+
108
+
The `X-Signature` header should contain the base64 encoded signature generated by the client.
0 commit comments