quick proxy test

This commit is contained in:
proddy
2021-04-01 17:49:43 +02:00
parent 3bacfc3361
commit d553542206
12 changed files with 3212 additions and 191 deletions

2
.gitignore vendored
View File

@@ -23,6 +23,6 @@ emsesp
/data/www /data/www
/lib/framework/WWWData.h /lib/framework/WWWData.h
/interface/build /interface/build
/interface/node_modules node_modules
/interface/.eslintcache /interface/.eslintcache

2864
api/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

16
api/package.json Normal file
View File

@@ -0,0 +1,16 @@
{
"name": "api",
"version": "1.0.0",
"description": "mock api for EMS-ESP",
"main": "server.js",
"scripts": {
"dev": "nodemon ./server.js localhost 3080",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "proddy",
"license": "ISC",
"dependencies": {
"express": "^4.17.1",
"nodemon": "^2.0.4"
}
}

84
api/server.js Normal file
View File

@@ -0,0 +1,84 @@
const ENDPOINT_ROOT = "/rest/";
const FEATURES_ENDPOINT = ENDPOINT_ROOT + "features";
const NTP_STATUS_ENDPOINT = ENDPOINT_ROOT + "ntpStatus";
const NTP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "ntpSettings";
const TIME_ENDPOINT = ENDPOINT_ROOT + "time";
const AP_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "apSettings";
const AP_STATUS_ENDPOINT = ENDPOINT_ROOT + "apStatus";
const SCAN_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "scanNetworks";
const LIST_NETWORKS_ENDPOINT = ENDPOINT_ROOT + "listNetworks";
const NETWORK_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "networkSettings";
const NETWORK_STATUS_ENDPOINT = ENDPOINT_ROOT + "networkStatus";
const OTA_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "otaSettings";
const UPLOAD_FIRMWARE_ENDPOINT = ENDPOINT_ROOT + "uploadFirmware";
const MQTT_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "mqttSettings";
const MQTT_STATUS_ENDPOINT = ENDPOINT_ROOT + "mqttStatus";
const SYSTEM_STATUS_ENDPOINT = ENDPOINT_ROOT + "systemStatus";
const SIGN_IN_ENDPOINT = ENDPOINT_ROOT + "signIn";
const VERIFY_AUTHORIZATION_ENDPOINT = ENDPOINT_ROOT + "verifyAuthorization";
const SECURITY_SETTINGS_ENDPOINT = ENDPOINT_ROOT + "securitySettings";
const RESTART_ENDPOINT = ENDPOINT_ROOT + "restart";
const FACTORY_RESET_ENDPOINT = ENDPOINT_ROOT + "factoryReset";
const express = require('express');
const path = require('path');
const app = express(),
bodyParser = require("body-parser");
const port = process.env.PORT || 3080;
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '../interface/build')));
app.get(FEATURES_ENDPOINT, (req, res) => {
// const stuff = req.body.stuff;
console.log('features')
res.json({
security: false,
project: false,
mqtt: false,
ntp: false,
ota: false,
upload_firmware: false
});
});
app.get(VERIFY_AUTHORIZATION_ENDPOINT, (req, res) => {
console.log('verifyAuthentication')
res.json({
access_token: '1234'
});
});
app.get(NETWORK_STATUS_ENDPOINT, (req, res) => {
console.log('networkStatus')
res.json({
status: 3,
local_ip: '10.10.10.2',
mac_address: '00:11:22:33:44',
rssi: 12,
ssid: "myWifi",
bssid: "adsfds",
channel: 3,
submnet_mask: "255.255.255.0"
});
});
app.get(NETWORK_SETTINGS_ENDPOINT, (req, res) => {
console.log('networkSettings')
res.json({
ssid: "myWifi",
password: 'myPassword',
hostname: 'ems-esp',
static_ip_config: false
});
});
app.listen(port);
console.log(`Server listening on port::${port}`);

View File

@@ -1,11 +1,7 @@
# Change the IP address to that of your ESP device to enable local development of the UI. # Change the IP address to that of your ESP device to enable local development of the UI
# Remember to also enable CORS in platformio.ini before uploading the code to the device
# with -DENABLE_CORS
# my Wifi REACT_APP_HTTP_ROOT=http://localhost:3000
#REACT_APP_HTTP_ROOT=http://10.10.10.101
#REACT_APP_WEB_SOCKET_ROOT=ws://10.10.10.101
# my Ethernet # REACT_APP_HTTP_ROOT=http://172.17.233.73:3000
REACT_APP_HTTP_ROOT=http://192.168.1.134
REACT_APP_WEB_SOCKET_ROOT=ws://http://192.168.1.134 # REACT_APP_WEB_SOCKET_ROOT=ws://localhost:3000

View File

@@ -36,6 +36,7 @@
"zlib": "^1.0.5" "zlib": "^1.0.5"
}, },
"devDependencies": { "devDependencies": {
"http-proxy-middleware": "^0.19.1",
"react-app-rewired": "^2.1.8" "react-app-rewired": "^2.1.8"
} }
}, },

View File

@@ -51,6 +51,8 @@
] ]
}, },
"devDependencies": { "devDependencies": {
"react-app-rewired": "^2.1.8" "http-proxy-middleware": "^0.19.1",
"react-app-rewired": "^2.1.8",
"concurrently": "^4.1.0"
} }
} }

View File

@@ -0,0 +1,15 @@
const createProxyMiddleware = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/rest/*',
createProxyMiddleware({
target: 'http://localhost:3080',
secure: false,
changeOrigin: true,
// pathRewrite: {
// '^/api/settings': '/api/app/settings'
// },
})
);
};

11
interface/x Normal file
View File

@@ -0,0 +1,11 @@
> esp8266-react@0.1.0 start
> react-app-rewired start
[HPM] Proxy created: / -> http://localhost:3080
 「wds」: Project is running at http://172.17.233.73/
 「wds」: webpack output is served from
 「wds」: Content not from webpack is served from /home/paul/dev/EMS-ESP32/interface/public
 「wds」: 404s will fallback to /
Starting the development server...

View File

@@ -39,12 +39,12 @@
#include <Print.h> #include <Print.h>
#if ARDUINOJSON_VERSION_MAJOR == 5 #if ARDUINOJSON_VERSION_MAJOR == 5
#define ARDUINOJSON_5_COMPATIBILITY #define ARDUINOJSON_5_COMPATIBILITY
#else #else
#define DYNAMIC_JSON_DOCUMENT_SIZE 1024 #define DYNAMIC_JSON_DOCUMENT_SIZE 1024
#endif #endif
constexpr const char* JSON_MIMETYPE = "application/json"; constexpr const char * JSON_MIMETYPE = "application/json";
/* /*
* Json Response * Json Response
@@ -52,15 +52,21 @@ constexpr const char* JSON_MIMETYPE = "application/json";
class ChunkPrint : public Print { class ChunkPrint : public Print {
private: private:
uint8_t* _destination; uint8_t * _destination;
size_t _to_skip; size_t _to_skip;
size_t _to_write; size_t _to_write;
size_t _pos; size_t _pos;
public: public:
ChunkPrint(uint8_t* destination, size_t from, size_t len) ChunkPrint(uint8_t * destination, size_t from, size_t len)
: _destination(destination), _to_skip(from), _to_write(len), _pos{0} {} : _destination(destination)
virtual ~ChunkPrint(){} , _to_skip(from)
size_t write(uint8_t c){ , _to_write(len)
, _pos{0} {
}
virtual ~ChunkPrint() {
}
size_t write(uint8_t c) {
if (_to_skip > 0) { if (_to_skip > 0) {
_to_skip--; _to_skip--;
return 1; return 1;
@@ -71,15 +77,13 @@ class ChunkPrint : public Print {
} }
return 0; return 0;
} }
size_t write(const uint8_t *buffer, size_t size) size_t write(const uint8_t * buffer, size_t size) {
{
return this->Print::write(buffer, size); return this->Print::write(buffer, size);
} }
}; };
class AsyncJsonResponse: public AsyncAbstractResponse { class AsyncJsonResponse : public AsyncAbstractResponse {
protected: protected:
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
DynamicJsonBuffer _jsonBuffer; DynamicJsonBuffer _jsonBuffer;
#else #else
@@ -90,49 +94,59 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
bool _isValid; bool _isValid;
public: public:
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
AsyncJsonResponse(bool isArray=false): _isValid{false} { AsyncJsonResponse(bool isArray = false)
: _isValid{false} {
_code = 200; _code = 200;
_contentType = JSON_MIMETYPE; _contentType = JSON_MIMETYPE;
if(isArray) if (isArray)
_root = _jsonBuffer.createArray(); _root = _jsonBuffer.createArray();
else else
_root = _jsonBuffer.createObject(); _root = _jsonBuffer.createObject();
} }
#else #else
AsyncJsonResponse(bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : _jsonBuffer(maxJsonBufferSize), _isValid{false} { AsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE)
: _jsonBuffer(maxJsonBufferSize)
, _isValid{false} {
_code = 200; _code = 200;
_contentType = JSON_MIMETYPE; _contentType = JSON_MIMETYPE;
if(isArray) if (isArray)
_root = _jsonBuffer.createNestedArray(); _root = _jsonBuffer.createNestedArray();
else else
_root = _jsonBuffer.createNestedObject(); _root = _jsonBuffer.createNestedObject();
} }
#endif #endif
~AsyncJsonResponse() {} ~AsyncJsonResponse() {
JsonVariant & getRoot() { return _root; } }
bool _sourceValid() const { return _isValid; } JsonVariant & getRoot() {
return _root;
}
bool _sourceValid() const {
return _isValid;
}
size_t setLength() { size_t setLength() {
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
_contentLength = _root.measureLength(); _contentLength = _root.measureLength();
#else #else
_contentLength = measureJson(_root); _contentLength = measureJson(_root);
#endif #endif
if (_contentLength) { _isValid = true; } if (_contentLength) {
_isValid = true;
}
return _contentLength; return _contentLength;
} }
size_t getSize() { return _jsonBuffer.size(); } size_t getSize() {
return _jsonBuffer.size();
}
size_t _fillBuffer(uint8_t *data, size_t len){ size_t _fillBuffer(uint8_t * data, size_t len) {
ChunkPrint dest(data, _sentLength, len); ChunkPrint dest(data, _sentLength, len);
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
_root.printTo( dest ) ; _root.printTo(dest);
#else #else
serializeJson(_root, dest); serializeJson(_root, dest);
#endif #endif
@@ -140,38 +154,46 @@ class AsyncJsonResponse: public AsyncAbstractResponse {
} }
}; };
class PrettyAsyncJsonResponse: public AsyncJsonResponse { class PrettyAsyncJsonResponse : public AsyncJsonResponse {
public: public:
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
PrettyAsyncJsonResponse (bool isArray=false) : AsyncJsonResponse{isArray} {} PrettyAsyncJsonResponse(bool isArray = false)
: AsyncJsonResponse{isArray} {
}
#else #else
PrettyAsyncJsonResponse (bool isArray=false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE) : AsyncJsonResponse{isArray, maxJsonBufferSize} {} PrettyAsyncJsonResponse(bool isArray = false, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE)
: AsyncJsonResponse{isArray, maxJsonBufferSize} {
}
#endif #endif
size_t setLength () { size_t setLength() {
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
_contentLength = _root.measurePrettyLength (); _contentLength = _root.measurePrettyLength();
#else #else
_contentLength = measureJsonPretty(_root); _contentLength = measureJsonPretty(_root);
#endif #endif
if (_contentLength) {_isValid = true;} if (_contentLength) {
_isValid = true;
}
return _contentLength; return _contentLength;
} }
size_t _fillBuffer (uint8_t *data, size_t len) { size_t _fillBuffer(uint8_t * data, size_t len) {
ChunkPrint dest (data, _sentLength, len); ChunkPrint dest(data, _sentLength, len);
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
_root.prettyPrintTo (dest); _root.prettyPrintTo(dest);
#else #else
serializeJsonPretty(_root, dest); serializeJsonPretty(_root, dest);
// serializeJson(_root, Serial); // for testing
// Serial.println();
#endif #endif
return len; return len;
} }
}; };
typedef std::function<void(AsyncWebServerRequest *request, JsonVariant &json)> ArJsonRequestHandlerFunction; typedef std::function<void(AsyncWebServerRequest * request, JsonVariant & json)> ArJsonRequestHandlerFunction;
class AsyncCallbackJsonWebHandler: public AsyncWebHandler { class AsyncCallbackJsonWebHandler : public AsyncWebHandler {
private: private:
protected: protected:
const String _uri; const String _uri;
WebRequestMethodComposite _method; WebRequestMethodComposite _method;
ArJsonRequestHandlerFunction _onRequest; ArJsonRequestHandlerFunction _onRequest;
@@ -180,48 +202,63 @@ protected:
const size_t maxJsonBufferSize; const size_t maxJsonBufferSize;
#endif #endif
size_t _maxContentLength; size_t _maxContentLength;
public:
public:
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest) AsyncCallbackJsonWebHandler(const String & uri, ArJsonRequestHandlerFunction onRequest)
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), _maxContentLength(16384) {} : _uri(uri)
, _method(HTTP_POST | HTTP_PUT | HTTP_PATCH)
, _onRequest(onRequest)
, _maxContentLength(16384) {
}
#else #else
AsyncCallbackJsonWebHandler(const String& uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize=DYNAMIC_JSON_DOCUMENT_SIZE) AsyncCallbackJsonWebHandler(const String & uri, ArJsonRequestHandlerFunction onRequest, size_t maxJsonBufferSize = DYNAMIC_JSON_DOCUMENT_SIZE)
: _uri(uri), _method(HTTP_POST|HTTP_PUT|HTTP_PATCH), _onRequest(onRequest), maxJsonBufferSize(maxJsonBufferSize), _maxContentLength(16384) {} : _uri(uri)
, _method(HTTP_POST | HTTP_PUT | HTTP_PATCH)
, _onRequest(onRequest)
, maxJsonBufferSize(maxJsonBufferSize)
, _maxContentLength(16384) {
}
#endif #endif
void setMethod(WebRequestMethodComposite method){ _method = method; } void setMethod(WebRequestMethodComposite method) {
void setMaxContentLength(int maxContentLength){ _maxContentLength = maxContentLength; } _method = method;
void onRequest(ArJsonRequestHandlerFunction fn){ _onRequest = fn; } }
void setMaxContentLength(int maxContentLength) {
_maxContentLength = maxContentLength;
}
void onRequest(ArJsonRequestHandlerFunction fn) {
_onRequest = fn;
}
virtual bool canHandle(AsyncWebServerRequest *request) override final{ virtual bool canHandle(AsyncWebServerRequest * request) override final {
if(!_onRequest) if (!_onRequest)
return false; return false;
if(!(_method & request->method())) if (!(_method & request->method()))
return false; return false;
if(_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri+"/"))) if (_uri.length() && (_uri != request->url() && !request->url().startsWith(_uri + "/")))
return false; return false;
if ( !request->contentType().equalsIgnoreCase(JSON_MIMETYPE) ) if (!request->contentType().equalsIgnoreCase(JSON_MIMETYPE))
return false; return false;
request->addInterestingHeader("ANY"); request->addInterestingHeader("ANY");
return true; return true;
} }
virtual void handleRequest(AsyncWebServerRequest *request) override final { virtual void handleRequest(AsyncWebServerRequest * request) override final {
if(_onRequest) { if (_onRequest) {
if (request->_tempObject != NULL) { if (request->_tempObject != NULL) {
#ifdef ARDUINOJSON_5_COMPATIBILITY #ifdef ARDUINOJSON_5_COMPATIBILITY
DynamicJsonBuffer jsonBuffer; DynamicJsonBuffer jsonBuffer;
JsonVariant json = jsonBuffer.parse((uint8_t*)(request->_tempObject)); JsonVariant json = jsonBuffer.parse((uint8_t *)(request->_tempObject));
if (json.success()) { if (json.success()) {
#else #else
DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize); DynamicJsonDocument jsonBuffer(this->maxJsonBufferSize);
DeserializationError error = deserializeJson(jsonBuffer, (uint8_t*)(request->_tempObject)); DeserializationError error = deserializeJson(jsonBuffer, (uint8_t *)(request->_tempObject));
if(!error) { if (!error) {
JsonVariant json = jsonBuffer.as<JsonVariant>(); JsonVariant json = jsonBuffer.as<JsonVariant>();
#endif #endif
@@ -234,19 +271,21 @@ public:
request->send(500); request->send(500);
} }
} }
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final { virtual void handleUpload(AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t * data, size_t len, bool final) override final {
} }
virtual void handleBody(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) override final { virtual void handleBody(AsyncWebServerRequest * request, uint8_t * data, size_t len, size_t index, size_t total) override final {
if (_onRequest) { if (_onRequest) {
_contentLength = total; _contentLength = total;
if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) { if (total > 0 && request->_tempObject == NULL && total < _maxContentLength) {
request->_tempObject = malloc(total); request->_tempObject = malloc(total);
} }
if (request->_tempObject != NULL) { if (request->_tempObject != NULL) {
memcpy((uint8_t*)(request->_tempObject) + index, data, len); memcpy((uint8_t *)(request->_tempObject) + index, data, len);
} }
} }
} }
virtual bool isRequestHandlerTrivial() override final {return _onRequest ? false : true;} virtual bool isRequestHandlerTrivial() override final {
return _onRequest ? false : true;
}
}; };
#endif #endif

View File

@@ -40,13 +40,6 @@ ESP8266React::ESP8266React(AsyncWebServer * server, FS * fs)
}); });
} }
}); });
// Disable CORS if required
#if defined(ENABLE_CORS)
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Origin", CORS_ORIGIN);
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Headers", "Accept, Content-Type, Authorization");
DefaultHeaders::Instance().addHeader("Access-Control-Allow-Credentials", "true");
#endif
} }
void ESP8266React::begin() { void ESP8266React::begin() {

View File

@@ -8,8 +8,8 @@ upload_flags =
upload_port = 10.10.10.101 upload_port = 10.10.10.101
[common] [common]
; options are EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_TEST ENABLE_CORS DEMSESP_DEFAULT_BOARD_PROFILE ; options are EMSESP_DEBUG EMSESP_UART_DEBUG EMSESP_TEST DEMSESP_DEFAULT_BOARD_PROFILE
; debug_flags = -DENABLE_CORS -DEMSESP_DEBUG -DEMSESP_TEST -DCORS_ORIGIN=\"http://localhost:3000\" ; debug_flags = -DEMSESP_DEBUG -DEMSESP_TEST
; debug_flags = -DEMSESP_DEFAULT_BOARD_PROFILE=\"NODEMCU\" ; debug_flags = -DEMSESP_DEFAULT_BOARD_PROFILE=\"NODEMCU\"
[env:esp32] [env:esp32]