diff --git a/react/src/PiPedalModel.tsx b/react/src/PiPedalModel.tsx index 9fc9da2..897d60b 100644 --- a/react/src/PiPedalModel.tsx +++ b/react/src/PiPedalModel.tsx @@ -836,7 +836,11 @@ class PiPedalModelImpl implements PiPedalModel { }) .then((data) => { this.banks.set(new BankIndex().deserialize(data)); - + if (this.webSocket) + { + // MUST not allow reconnect until at least one complete load has finished. + this.webSocket.canReconnect = true; + } return true; }) .catch((error) => { @@ -848,23 +852,6 @@ class PiPedalModelImpl implements PiPedalModel { ; } - // requestPlugins(): Promise { - // const myRequest = new Request(this.varRequest('uiplugins.json')); - // return fetch(myRequest) - // .then( - // response => response.json() - // ) - // .then(data => { - // let plugins = UiPlugin.deserialize_array(data); - // this.ui_plugins.set(plugins); - // return true; - // }) - // .catch((error) => { - // this.setError("Can't contact server.\n\n" + error); - // return false; - // }); - - // } requestCurrentPedalBoard(): Promise { const myRequest = new Request(this.varRequest('current_pedalboard.json')); return fetch(myRequest) diff --git a/react/src/PiPedalSocket.tsx b/react/src/PiPedalSocket.tsx index 557debc..bfc88ac 100644 --- a/react/src/PiPedalSocket.tsx +++ b/react/src/PiPedalSocket.tsx @@ -178,6 +178,9 @@ class PiPedalSocket { throw new PiPedalStateError("Server connection lost."); } } + + canReconnect: boolean = false; + handleClose(_event: any): any { if (this.retrying) { // treat this as a fatal error. @@ -189,7 +192,10 @@ class PiPedalSocket { return; } - this._reconnect(); + if (this.canReconnect) + { + this._reconnect(); + } } _reconnect() { this._discardReplyReservations(); diff --git a/react/src/SettingsDialog.tsx b/react/src/SettingsDialog.tsx index 7a5b817..7da42b7 100644 --- a/react/src/SettingsDialog.tsx +++ b/react/src/SettingsDialog.tsx @@ -561,6 +561,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })( + + this.handleRestart()} > diff --git a/src/BeastServer.cpp b/src/BeastServer.cpp index 1c3daa8..c4ed56c 100644 --- a/src/BeastServer.cpp +++ b/src/BeastServer.cpp @@ -385,11 +385,18 @@ namespace pipedal } std::shared_ptr connectionUri = con->get_uri(); - uri requestUri(con->get_uri()->str().c_str()); - HttpRequestImpl req(con->get_request()); HttpResponseImpl res((*con)); + uri requestUri; + try { + requestUri.set(con->get_uri()->str().c_str()); + } catch (const std::exception &e) + { + ServerError(*con, SS("Unexpected error. " << e.what())); + return; + } + if (req.method() == HttpVerb::options) { res.set(HttpField::access_control_allow_origin, origin); diff --git a/src/Ipv6Helpers.cpp b/src/Ipv6Helpers.cpp index f347426..6bb2f04 100644 --- a/src/Ipv6Helpers.cpp +++ b/src/Ipv6Helpers.cpp @@ -85,6 +85,67 @@ static bool IsIpv4OnLocalSubnet(uint32_t ipv4Addres) return result; } +bool pipedal::ParseHttpAddress(const std::string address, + std::string *pUser, + std::string *pServer, + int *pPort, + int defaultPort) +{ + // strip user. + auto start = address.find_first_of('@'); + if (start != std::string::npos) + { + if (pUser) + { + *pUser = address.substr(0,start); + } + start = start+1; + } else { + start = 0; + if (pUser) + { + *pUser = ""; + } + } + // find the port address. + int port = address.length(); + while (port > 0 && address[port-1] != ':') + { + if (address[port-1] != ']') + { + port = address.length(); + break; + } + --port; + } + int portNumber = defaultPort; + if (port < address.length() && address[port] == ':') + { + const char*p = address.c_str()+port+1; + if (*p) + { + portNumber = 0; + while (*p) + { + if (*p >= '0' && *p <= '9') + { + portNumber = portNumber*10 + *p -'0'; + } else { + return false; + } + } + } + } + if (pPort) + { + *pPort = portNumber; + } + if (pServer) + { + *pServer = address.substr(start,port-start); + } + return true; +} static std::string StripPortNumber(const std::string &fromAddress) { std::string address = fromAddress; diff --git a/src/Ipv6Helpers.hpp b/src/Ipv6Helpers.hpp index db8f3ac..d790c2e 100644 --- a/src/Ipv6Helpers.hpp +++ b/src/Ipv6Helpers.hpp @@ -27,5 +27,11 @@ namespace pipedal { bool IsOnLocalSubnet(const std::string&fromAddress); + bool ParseHttpAddress(const std::string address, + std::string *pUser, + std::string *pServer, + int *pPort, + int defaultPort); + } \ No newline at end of file diff --git a/src/Uri.cpp b/src/Uri.cpp index b5a8ed9..1219e56 100644 --- a/src/Uri.cpp +++ b/src/Uri.cpp @@ -140,6 +140,9 @@ void uri::set_() { authority_end = p; port_start = p+1; + } else if (c == ']') // ignore colon inside ipv6 address. + { + port_start = nullptr; } if (c == '/' || c == '?' || c == '#') {