Remove extra logging, auth /cp/serial and add doc

This commit is contained in:
Scott Shawcroft 2022-07-11 14:32:28 -07:00
parent 557e35469f
commit 8cfdfb95f7
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
4 changed files with 50 additions and 44 deletions

View File

@ -286,6 +286,44 @@ not protected by basic auth in case the device is someone elses.
Only `GET` requests are supported and will return `405 Method Not Allowed` otherwise. Only `GET` requests are supported and will return `405 Method Not Allowed` otherwise.
#### `/cp/devices.json`
Returns information about other devices found on the network using MDNS.
* `total`: Total MDNS response count. May be more than in `devices` if internal limits were hit.
* `devices`: List of discovered devices.
* `hostname`: MDNS hostname
* `instance_name`: MDNS instance name. Defaults to human readable board name.
* `port`: Port of CircuitPython Web API
* `ip`: IP address
Example:
```sh
curl -v -L http://circuitpython.local/cp/devices.json
```
```json
{
"total": 1,
"devices": [
{
"hostname": "cpy-951032",
"instance_name": "Adafruit Feather ESP32-S2 TFT",
"port": 80,
"ip": "192.168.1.235"
}
]
}
```
#### `/cp/serial/`
Serves a basic serial terminal program when a `GET` request is received without the
`Upgrade: websocket` header. Otherwise the socket is upgraded to a WebSocket. See WebSockets below for more detail.
This is an authenticated endpoint in both modes.
#### `/cp/version.json` #### `/cp/version.json`
Returns information about the device. Returns information about the device.
@ -323,36 +361,6 @@ curl -v -L http://circuitpython.local/cp/version.json
} }
``` ```
#### `/cp/devices.json`
Returns information about other devices found on the network using MDNS.
* `total`: Total MDNS response count. May be more than in `devices` if internal limits were hit.
* `devices`: List of discovered devices.
* `hostname`: MDNS hostname
* `instance_name`: MDNS instance name. Defaults to human readable board name.
* `port`: Port of CircuitPython Web API
* `ip`: IP address
Example:
```sh
curl -v -L http://circuitpython.local/cp/devices.json
```
```json
{
"total": 1,
"devices": [
{
"hostname": "cpy-951032",
"instance_name": "Adafruit Feather ESP32-S2 TFT",
"port": 80,
"ip": "192.168.1.235"
}
]
}
```
### Static files ### Static files
* `/favicon.ico` - Blinka * `/favicon.ico` - Blinka
@ -361,4 +369,12 @@ curl -v -L http://circuitpython.local/cp/devices.json
### WebSocket ### WebSocket
Coming soon! The CircuitPython serial interactions are available over a WebSocket. A WebSocket begins as a
special HTTP request that gets upgraded to a WebSocket. Authentication happens before upgrading.
WebSockets are *not* bare sockets once upgraded. Instead they have their own framing format for data.
CircuitPython can handle PING and CLOSE opcodes. All others are treated as TEXT. Data to
CircuitPython is expected to be masked UTF-8, as the spec requires. Data from CircuitPython to the
client is unmasked. It is also unbuffered so the client will get a variety of frame sizes.
Only one WebSocket at a time is supported.

View File

@ -3,11 +3,12 @@
<head> <head>
<title>CircuitPython</title> <title>CircuitPython</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="/welcome.js" defer=true></script> <script src="/welcome.js" defer=true></script>
</head> </head>
<body> <body>
<h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;Welcome!</h1> <h1><a href="/"><img src="/favicon.ico"/></a>&nbsp;Welcome!</h1>
Welcome to CircuitPython's Web API. Go to the <a href="/fs/">file browser</a> to work with files in the CIRCUITPY drive. Make sure you've set <code>CIRCUITPY_WEB_API_PASSWORD='somepassword'</code> in <code>/.env</code>. Provide the password when the browser prompts for it. Leave the username blank. Welcome to CircuitPython's Web API. Go to the <a href="/fs/">file browser</a> to work with files in the CIRCUITPY drive. Go to the <a href="/cp/serial/">serial terminal</a> to see code output and interact with the REPL. Make sure you've set <code>CIRCUITPY_WEB_API_PASSWORD='somepassword'</code> in <code>/.env</code>. Provide the password when the browser prompts for it. Leave the username blank.
<h2>Device Info</h2> <h2>Device Info</h2>
Board: <a id="board"></a><br> Board: <a id="board"></a><br>
Version: <span id="version"></span><br> Version: <span id="version"></span><br>

View File

@ -1019,14 +1019,13 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
} else if (strcmp(path, "/version.json") == 0) { } else if (strcmp(path, "/version.json") == 0) {
_reply_with_version_json(socket, request); _reply_with_version_json(socket, request);
} else if (strcmp(path, "/serial/") == 0) { } else if (strcmp(path, "/serial/") == 0) {
if (false && !request->authenticated) { if (!request->authenticated) {
if (_api_password[0] != '\0') { if (_api_password[0] != '\0') {
_reply_unauthorized(socket, request); _reply_unauthorized(socket, request);
} else { } else {
_reply_forbidden(socket, request); _reply_forbidden(socket, request);
} }
} else if (request->websocket) { } else if (request->websocket) {
ESP_LOGI(TAG, "websocket!");
_reply_websocket_upgrade(socket, request); _reply_websocket_upgrade(socket, request);
} else { } else {
_REPLY_STATIC(socket, request, serial_html); _REPLY_STATIC(socket, request, serial_html);
@ -1059,7 +1058,6 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
} }
static void _reset_request(_request *request) { static void _reset_request(_request *request) {
ESP_LOGI(TAG, "reset request");
request->state = STATE_METHOD; request->state = STATE_METHOD;
request->origin[0] = '\0'; request->origin[0] = '\0';
request->content_length = 0; request->content_length = 0;

View File

@ -48,7 +48,6 @@ void websocket_init(void) {
} }
void websocket_handoff(socketpool_socket_obj_t *socket) { void websocket_handoff(socketpool_socket_obj_t *socket) {
ESP_LOGI(TAG, "socket handed off");
cp_serial.socket = *socket; cp_serial.socket = *socket;
cp_serial.closed = false; cp_serial.closed = false;
cp_serial.opcode = 0; cp_serial.opcode = 0;
@ -57,7 +56,6 @@ void websocket_handoff(socketpool_socket_obj_t *socket) {
// Mark the original socket object as closed without telling the lower level. // Mark the original socket object as closed without telling the lower level.
socket->connected = false; socket->connected = false;
socket->num = -1; socket->num = -1;
ESP_LOGI(TAG, "socket hand off done");
} }
bool websocket_connected(void) { bool websocket_connected(void) {
@ -90,7 +88,6 @@ static void _read_next_frame_header(void) {
if (cp_serial.frame_index == 0 && _read_byte(&h)) { if (cp_serial.frame_index == 0 && _read_byte(&h)) {
cp_serial.frame_index++; cp_serial.frame_index++;
cp_serial.opcode = h & 0xf; cp_serial.opcode = h & 0xf;
ESP_LOGI(TAG, "fin %d opcode %x", h >> 7, cp_serial.opcode);
} }
if (cp_serial.frame_index == 1 && _read_byte(&h)) { if (cp_serial.frame_index == 1 && _read_byte(&h)) {
cp_serial.frame_index++; cp_serial.frame_index++;
@ -108,8 +105,6 @@ static void _read_next_frame_header(void) {
if (cp_serial.masked) { if (cp_serial.masked) {
cp_serial.frame_len += 4; cp_serial.frame_len += 4;
} }
ESP_LOGI(TAG, "mask %d length %x", cp_serial.masked, len);
} }
while (cp_serial.frame_index >= 2 && while (cp_serial.frame_index >= 2 &&
cp_serial.frame_index < (cp_serial.payload_len_size + 2) && cp_serial.frame_index < (cp_serial.payload_len_size + 2) &&
@ -133,7 +128,6 @@ static void _read_next_frame_header(void) {
if (cp_serial.frame_index == cp_serial.frame_len) { if (cp_serial.frame_index == cp_serial.frame_len) {
uint8_t opcode = 0x8; // CLOSE uint8_t opcode = 0x8; // CLOSE
if (cp_serial.opcode == 0x9) { if (cp_serial.opcode == 0x9) {
ESP_LOGI(TAG, "websocket ping");
opcode = 0xA; // PONG opcode = 0xA; // PONG
} else { } else {
// Set the TCP socket to send immediately so that we send the payload back before // Set the TCP socket to send immediately so that we send the payload back before
@ -160,7 +154,6 @@ static void _read_next_frame_header(void) {
if (cp_serial.payload_remaining == 0) { if (cp_serial.payload_remaining == 0) {
cp_serial.frame_index = 0; cp_serial.frame_index = 0;
if (cp_serial.opcode == 0x8) { if (cp_serial.opcode == 0x8) {
ESP_LOGI(TAG, "websocket closed");
cp_serial.closed = true; cp_serial.closed = true;
common_hal_socketpool_socket_close(&cp_serial.socket); common_hal_socketpool_socket_close(&cp_serial.socket);
@ -199,7 +192,6 @@ bool websocket_available(void) {
char websocket_read_char(void) { char websocket_read_char(void) {
uint8_t c; uint8_t c;
_read_next_payload_byte(&c); _read_next_payload_byte(&c);
ESP_LOGI(TAG, "read %c", c);
return c; return c;
} }
@ -232,7 +224,6 @@ static void _websocket_send(_websocket *ws, const char *text, size_t len) {
char copy[len]; char copy[len];
memcpy(copy, text, len); memcpy(copy, text, len);
copy[len] = '\0'; copy[len] = '\0';
ESP_LOGI(TAG, "sent over websocket: %s", copy);
} }
void websocket_write(const char *text, size_t len) { void websocket_write(const char *text, size_t len) {