WIP websocket accept and hashlib

This commit is contained in:
Scott Shawcroft 2022-06-29 16:31:55 -07:00
parent 2ae791aa4e
commit 7589e53fea
No known key found for this signature in database
GPG Key ID: 0DFD512649C052DA
14 changed files with 515 additions and 1 deletions

View File

@ -2199,6 +2199,10 @@ msgstr ""
msgid "Unsupported format"
msgstr ""
#: shared-bindings/hashlib/__init__.c
msgid "Unsupported hash algorithm"
msgstr ""
#: ports/espressif/common-hal/dualbank/__init__.c
msgid "Update Failed"
msgstr ""

View File

@ -0,0 +1,52 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/hashlib/Hash.h"
#include "components/mbedtls/mbedtls/include/mbedtls/ssl.h"
void common_hal_hashlib_hash_update(hashlib_hash_obj_t *self, const uint8_t *data, size_t datalen) {
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
mbedtls_sha1_update_ret(&self->sha1, data, datalen);
return;
}
}
void common_hal_hashlib_hash_digest(hashlib_hash_obj_t *self, uint8_t *data, size_t datalen) {
if (datalen < common_hal_hashlib_hash_get_digest_size(self)) {
return;
}
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
mbedtls_sha1_finish_ret(&self->sha1, data);
}
}
size_t common_hal_hashlib_hash_get_digest_size(hashlib_hash_obj_t *self) {
if (self->hash_type == MBEDTLS_SSL_HASH_SHA1) {
return 20;
}
return 0;
}

View File

@ -0,0 +1,41 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_HASHLIB_HASH_H
#define MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_HASHLIB_HASH_H
#include "components/mbedtls/mbedtls/include/mbedtls/sha1.h"
typedef struct {
mp_obj_base_t base;
union {
mbedtls_sha1_context sha1;
};
// Of MBEDTLS_SSL_HASH_*
uint8_t hash_type;
} hashlib_hash_obj_t;
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_HASHLIB_HASH_H

View File

@ -0,0 +1,40 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/hashlib/__init__.h"
#include "components/mbedtls/mbedtls/include/mbedtls/ssl.h"
bool common_hal_hashlib_new(hashlib_hash_obj_t *self, const char *algorithm) {
if (strcmp(algorithm, "sha1") == 0) {
self->hash_type = MBEDTLS_SSL_HASH_SHA1;
mbedtls_sha1_init(&self->sha1);
mbedtls_sha1_starts_ret(&self->sha1);
return true;
}
return false;
}

View File

@ -19,6 +19,7 @@ CIRCUITPY_COUNTIO ?= 1
CIRCUITPY_DUALBANK ?= 1
CIRCUITPY_FRAMEBUFFERIO ?= 1
CIRCUITPY_FREQUENCYIO ?= 1
CIRCUITPY_HASHLIB ?= 1
CIRCUITPY_IMAGECAPTURE ?= 1
CIRCUITPY_I2CPERIPHERAL ?= 1
CIRCUITPY_RGBMATRIX ?= 1

View File

@ -207,6 +207,9 @@ endif
ifeq ($(CIRCUITPY_GNSS),1)
SRC_PATTERNS += gnss/%
endif
ifeq ($(CIRCUITPY_HASHLIB),1)
SRC_PATTERNS += hashlib/%
endif
ifeq ($(CIRCUITPY_I2CPERIPHERAL),1)
SRC_PATTERNS += i2cperipheral/%
endif
@ -419,6 +422,8 @@ SRC_COMMON_HAL_ALL = \
gnss/GNSS.c \
gnss/PositionFix.c \
gnss/SatelliteSystem.c \
hashlib/__init__.c \
hashlib/Hash.c \
i2cperipheral/I2CPeripheral.c \
i2cperipheral/__init__.c \
microcontroller/Pin.c \

View File

@ -0,0 +1,103 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "shared-bindings/hashlib/Hash.h"
// #include "shared-bindings/util.h"
// #include "shared/runtime/buffer_helper.h"
// #include "shared/runtime/interrupt_char.h"
// #include "py/mperrno.h"
// #include "py/mphal.h"
#include "py/obj.h"
#include "py/objproperty.h"
#include "py/objstr.h"
#include "py/runtime.h"
//| class Hash:
//| """In progress hash algorithm. This object is always created by a `hashlib.new()`. It has no
//| user-visible constructor."""
//|
//| digest_size: int
//| """Digest size in bytes"""
//|
STATIC mp_obj_t hashlib_hash_get_digest_size(mp_obj_t self_in) {
mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type));
hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in);
return MP_OBJ_NEW_SMALL_INT(common_hal_hashlib_hash_get_digest_size(self));
}
MP_PROPERTY_GETTER(hashlib_hash_digest_size_obj, hashlib_hash_get_digest_size);
//| def update(self, data: ReadableBuffer) -> None:
//| """Update the hash with the given bytes.
//|
//| :param ~circuitpython_typing.ReadableBuffer data: Update the hash from data in this buffer"""
//| ...
//|
mp_obj_t hashlib_hash_update(mp_obj_t self_in, mp_obj_t buf_in) {
mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type));
hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
common_hal_hashlib_hash_update(self, bufinfo.buf, bufinfo.len);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(hashlib_hash_update_obj, hashlib_hash_update);
//| def digest(self) -> bytes:
//| """Returns the current digest as bytes() with a length of `hashlib.Hash.digest_size`."""
//| ...
//|
STATIC mp_obj_t hashlib_hash_digest(mp_obj_t self_in) {
mp_check_self(mp_obj_is_type(self_in, &hashlib_hash_type));
hashlib_hash_obj_t *self = MP_OBJ_TO_PTR(self_in);
size_t size = common_hal_hashlib_hash_get_digest_size(self);
mp_obj_t obj = mp_obj_new_bytes_of_zeros(size);
mp_obj_str_t *o = MP_OBJ_TO_PTR(obj);
common_hal_hashlib_hash_digest(self, (uint8_t *)o->data, size);
return obj;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(hashlib_hash_digest_obj, hashlib_hash_digest);
STATIC const mp_rom_map_elem_t hashlib_hash_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_digest_size), MP_ROM_PTR(&hashlib_hash_digest_size_obj) },
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&hashlib_hash_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&hashlib_hash_digest_obj) },
};
STATIC MP_DEFINE_CONST_DICT(hashlib_hash_locals_dict, hashlib_hash_locals_dict_table);
const mp_obj_type_t hashlib_hash_type = {
{ &mp_type_type },
.name = MP_QSTR_Hash,
.locals_dict = (mp_obj_dict_t *)&hashlib_hash_locals_dict,
};

View File

@ -0,0 +1,43 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB_HASH_H
#define MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB_HASH_H
#include "py/obj.h"
#include "common-hal/hashlib/Hash.h"
extern const mp_obj_type_t hashlib_hash_type;
// So that new can call it when given data.
mp_obj_t hashlib_hash_update(mp_obj_t self_in, mp_obj_t buf_in);
void common_hal_hashlib_hash_update(hashlib_hash_obj_t *self, const uint8_t *data, size_t datalen);
void common_hal_hashlib_hash_digest(hashlib_hash_obj_t *self, uint8_t *data, size_t datalen);
size_t common_hal_hashlib_hash_get_digest_size(hashlib_hash_obj_t *self);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB_HASH_H

View File

@ -0,0 +1,90 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <string.h>
#include "py/obj.h"
#include "py/mpconfig.h"
#include "py/runtime.h"
#include "shared-bindings/hashlib/__init__.h"
#include "shared-bindings/hashlib/Hash.h"
#include "supervisor/shared/translate/translate.h"
//| """Hashing related functions
//|
//| |see_cpython_module| :mod:`cpython:hashlib`.
//| """
//|
//| def new(name, data=b"") -> hashlib.Hash:
//| """Returns a Hash object setup for the named algorithm. Raises ValueError when the named
//| algorithm is unsupported.
//|
//| :return: a hash object for the given algorithm
//| :rtype: hashlib.Hash"""
//| ...
//|
STATIC mp_obj_t hashlib_new(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_name, ARG_data };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_name, MP_ARG_REQUIRED | MP_ARG_OBJ },
{ MP_QSTR_data, MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
const char *algorithm = mp_obj_str_get_str(args[ARG_name].u_obj);
hashlib_hash_obj_t *self = m_new_obj(hashlib_hash_obj_t);
self->base.type = &hashlib_hash_type;
if (!common_hal_hashlib_new(self, algorithm)) {
mp_raise_ValueError(translate("Unsupported hash algorithm"));
}
if (args[ARG_data].u_obj != mp_const_none) {
hashlib_hash_update(self, args[ARG_data].u_obj);
}
return self;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(hashlib_new_obj, 1, hashlib_new);
STATIC const mp_rom_map_elem_t hashlib_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) },
{ MP_ROM_QSTR(MP_QSTR_new), MP_ROM_PTR(&hashlib_new_obj) },
// Hash is deliberately omitted here because CPython doesn't expose the
// object on `hashlib` only the internal `_hashlib`.
};
STATIC MP_DEFINE_CONST_DICT(hashlib_module_globals, hashlib_module_globals_table);
const mp_obj_module_t hashlib_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&hashlib_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_hashlib, hashlib_module, CIRCUITPY_HASHLIB);

View File

@ -0,0 +1,36 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2022 Scott Shawcroft for Adafruit Industries
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB___INIT___H
#define MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB___INIT___H
#include <stdbool.h>
#include "shared-bindings/hashlib/Hash.h"
bool common_hal_hashlib_new(hashlib_hash_obj_t *self, const char *algorithm);
#endif // MICROPY_INCLUDED_SHARED_BINDINGS_HASHLIB___INIT___H

View File

@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<title>Simple client</title>
<script src="/serial.js" defer=true></script>
</head>
<body>
<pre id="log"></pre>
<form onsubmit="onSubmit(); return false;">
<input type="text" id="input">
<input type="submit" value="Send">
<button onclick="onCloseClick(); return false;">close</button>
</form>
</body>
</html>

View File

@ -0,0 +1,43 @@
var ws;
function onSubmit() {
var input = document.getElementById("input");
// You can send message to the Web Socket using ws.send.
ws.send(input.value);
output("send: " + input.value);
input.value = "";
input.focus();
}
function onCloseClick() {
ws.close();
}
function output(str) {
var log = document.getElementById("log");
log.innerHTML += str;
}
// Connect to Web Socket
ws = new WebSocket("ws://cpy-f57ce8.local/cp/serial/");
// ws = new WebSocket("ws://127.0.0.1:9001")
// Set event handlers.
ws.onopen = function() {
output("onopen");
};
ws.onmessage = function(e) {
// e.data contains received string.
output("onmessage: " + e.data);
};
ws.onclose = function() {
output("onclose");
};
ws.onerror = function(e) {
output("onerror");
console.log(e)
};

View File

@ -3,8 +3,8 @@
<head>
<title>CircuitPython</title>
<meta charset="UTF-8">
<script src="/welcome.js" defer=true></script>
</head>
<script src="/welcome.js" defer=true></script>
<body>
<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.

View File

@ -86,6 +86,10 @@ typedef struct {
bool authenticated;
bool expect;
bool json;
bool websocket;
uint32_t websocket_version;
// RFC6455 for websockets says this header should be 24 base64 characters long.
char websocket_key[24 + 1];
} _request;
static wifi_radio_error_t wifi_status = WIFI_RADIO_ERROR_NONE;
@ -519,6 +523,7 @@ static void _reply_redirect(socketpool_socket_obj_t *socket, _request *request,
"Location: http://", hostname, ".local", path, "\r\n", NULL);
_cors_header(socket, request);
_send_str(socket, "\r\n");
ESP_LOGI(TAG, "redirect");
}
static void _reply_directory_json(socketpool_socket_obj_t *socket, _request *request, FF_DIR *dir, const char *request_path, const char *path) {
@ -826,6 +831,8 @@ STATIC_FILE(directory_html);
STATIC_FILE(directory_js);
STATIC_FILE(welcome_html);
STATIC_FILE(welcome_js);
STATIC_FILE(serial_html);
STATIC_FILE(serial_js);
STATIC_FILE(blinka_16x16_ico);
static void _reply_static(socketpool_socket_obj_t *socket, _request *request, const uint8_t *response, size_t response_len, const char *content_type) {
@ -844,6 +851,13 @@ static void _reply_static(socketpool_socket_obj_t *socket, _request *request, co
#define _REPLY_STATIC(socket, request, filename) _reply_static(socket, request, filename, filename##_length, filename##_content_type)
static void _reply_websocket_upgrade(socketpool_socket_obj_t *socket, _request *request) {
ESP_LOGI(TAG, "websocket!");
// Compute accept key
// Reply with upgrade
// Copy socket state into websocket and mark given socket as closed even though it isn't actually.
}
static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
if (request->redirect) {
_reply_redirect(socket, request, request->path);
@ -980,6 +994,22 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
_reply_with_devices_json(socket, request);
} else if (strcmp(path, "/version.json") == 0) {
_reply_with_version_json(socket, request);
} else if (strcmp(path, "/serial/") == 0) {
if (!request->authenticated) {
if (_api_password[0] != '\0') {
_reply_unauthorized(socket, request);
} else {
_reply_forbidden(socket, request);
}
} else if (request->websocket) {
ESP_LOGI(TAG, "websocket!");
_reply_websocket_upgrade(socket, request);
} else {
_REPLY_STATIC(socket, request, serial_html);
}
_reply_with_version_json(socket, request);
} else {
_reply_missing(socket, request);
}
} else if (strcmp(request->method, "GET") != 0) {
_reply_method_not_allowed(socket, request);
@ -992,6 +1022,8 @@ static bool _reply(socketpool_socket_obj_t *socket, _request *request) {
_REPLY_STATIC(socket, request, directory_js);
} else if (strcmp(request->path, "/welcome.js") == 0) {
_REPLY_STATIC(socket, request, welcome_js);
} else if (strcmp(request->path, "/serial.js") == 0) {
_REPLY_STATIC(socket, request, serial_js);
} else if (strcmp(request->path, "/favicon.ico") == 0) {
// TODO: Autogenerate this based on the blinka bitmap and change the
// palette based on MAC address.
@ -1015,6 +1047,7 @@ static void _reset_request(_request *request) {
request->authenticated = false;
request->expect = false;
request->json = false;
request->websocket = false;
}
static void _process_request(socketpool_socket_obj_t *socket, _request *request) {
@ -1111,6 +1144,13 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request)
strcpy(request->origin, request->header_value);
} else if (strcmp(request->header_key, "X-Timestamp") == 0) {
request->timestamp_ms = strtoull(request->header_value, NULL, 10);
} else if (strcmp(request->header_key, "Upgrade") == 0) {
request->websocket = strcmp(request->header_value, "websocket") == 0;
} else if (strcmp(request->header_key, "Sec-WebSocket-Version") == 0) {
request->websocket_version = strtoul(request->header_value, NULL, 10);
} else if (strcmp(request->header_key, "Sec-WebSocket-Key") == 0 &&
strlen(request->header_value) == 24) {
strcpy(request->websocket_key, request->header_value);
}
ESP_LOGI(TAG, "Header %s %s", request->header_key, request->header_value);
} else if (request->offset > sizeof(request->header_value) - 1) {