Skip to content

Commit faa6762

Browse files
committed
fix: http realm normalization
1 parent 28242ec commit faa6762

File tree

1 file changed

+29
-67
lines changed

1 file changed

+29
-67
lines changed

NativeScript/runtime/HMRSupport.mm

Lines changed: 29 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "HMRSupport.h"
22
#import <Foundation/Foundation.h>
33
#include <algorithm>
4+
#include <cctype>
5+
#include <cstring>
46
#include "DevFlags.h"
57

68
#include <unordered_map>
@@ -182,78 +184,38 @@ void InitializeImportMetaHot(v8::Isolate* isolate,
182184
std::string originAndPath = (qPos == std::string::npos) ? noHash : noHash.substr(0, qPos);
183185
std::string query = (qPos == std::string::npos) ? std::string() : noHash.substr(qPos + 1);
184186

185-
// Decide behavior based on path prefix
186-
std::string pathOnly = noHash.substr(pathStart, (qPos == std::string::npos) ? std::string::npos : (qPos - pathStart));
187-
bool isAppMod = pathOnly.find("/ns/m") != std::string::npos;
188-
bool isSfcMod = pathOnly.find("/ns/sfc") != std::string::npos;
189-
bool isSfcAsm = pathOnly.find("/ns/asm") != std::string::npos;
190-
bool isRt = pathOnly.find("/ns/rt") != std::string::npos;
191-
bool isCore = pathOnly.find("/ns/core") != std::string::npos;
192-
193-
if (query.empty()) return originAndPath;
194-
195-
if (isAppMod) {
196-
// Treat query params as part of module identity (browser-like),
197-
// but ignore internal `import` markers.
198-
std::vector<std::string> kept;
199-
size_t start = 0;
200-
while (start <= query.size()) {
201-
size_t amp = query.find('&', start);
202-
std::string pair = (amp == std::string::npos) ? query.substr(start) : query.substr(start, amp - start);
203-
if (!pair.empty()) {
204-
size_t eq = pair.find('=');
205-
std::string name = (eq == std::string::npos) ? pair : pair.substr(0, eq);
206-
if (!(name == "import")) kept.push_back(pair);
187+
// Normalize bridge endpoints to keep a single realm across HMR updates:
188+
// - /ns/rt/<ver> -> /ns/rt
189+
// - /ns/core/<ver> -> /ns/core
190+
// Preserve query params (e.g. /ns/core?p=...) as part of module identity.
191+
{
192+
std::string pathOnly = originAndPath.substr(pathStart);
193+
auto normalizeBridge = [&](const char* needle) {
194+
size_t nlen = strlen(needle);
195+
if (pathOnly.compare(0, nlen, needle) != 0) return;
196+
if (pathOnly.size() == nlen) return; // already canonical
197+
if (pathOnly.size() <= nlen + 1 || pathOnly[nlen] != '/') return;
198+
199+
// Only normalize exact version segment: /ns/*/<digits> (no further segments)
200+
size_t i = nlen + 1;
201+
size_t j = i;
202+
while (j < pathOnly.size() && std::isdigit(static_cast<unsigned char>(pathOnly[j]))) {
203+
j++;
207204
}
208-
if (amp == std::string::npos) break;
209-
start = amp + 1;
210-
}
211-
if (kept.empty()) return originAndPath;
212-
std::sort(kept.begin(), kept.end());
213-
std::string rebuilt = originAndPath + "?";
214-
for (size_t i = 0; i < kept.size(); i++) {
215-
if (i > 0) rebuilt += "&";
216-
rebuilt += kept[i];
217-
}
218-
return rebuilt;
219-
}
205+
if (j == i) return; // no digits
206+
if (j != pathOnly.size()) return; // has extra path
220207

221-
if (isRt || isCore) {
222-
std::string canonical = originAndPath;
223-
const char* needle = isRt ? "/ns/rt" : "/ns/core";
224-
size_t pos = canonical.find(needle);
225-
if (pos != std::string::npos) {
226-
canonical = canonical.substr(0, pos) + std::string(needle);
227-
}
228-
return canonical;
229-
}
208+
originAndPath = originAndPath.substr(0, pathStart) + std::string(needle);
209+
pathOnly = originAndPath.substr(pathStart);
210+
};
230211

231-
if (isSfcMod || isSfcAsm) {
232-
std::vector<std::string> keptParams;
233-
size_t startPos = 0;
234-
while (startPos <= query.size()) {
235-
size_t amp = query.find('&', startPos);
236-
std::string pair = (amp == std::string::npos) ? query.substr(startPos) : query.substr(startPos, amp - startPos);
237-
if (!pair.empty()) {
238-
size_t eq = pair.find('=');
239-
std::string name = (eq == std::string::npos) ? pair : pair.substr(0, eq);
240-
if (!(name == "import")) {
241-
keptParams.push_back(pair);
242-
}
243-
}
244-
if (amp == std::string::npos) break;
245-
startPos = amp + 1;
246-
}
247-
if (keptParams.empty()) return originAndPath;
248-
std::string rebuilt = originAndPath + "?";
249-
for (size_t i = 0; i < keptParams.size(); i++) {
250-
rebuilt += keptParams[i];
251-
if (i + 1 < keptParams.size()) rebuilt += "&";
252-
}
253-
return rebuilt;
212+
normalizeBridge("/ns/rt");
213+
normalizeBridge("/ns/core");
254214
}
255215

256-
// Other URLs: keep all params except Vite's import marker; sort for stability
216+
if (query.empty()) return originAndPath;
217+
218+
// Keep all params except Vite's import marker; sort for stability.
257219
std::vector<std::string> kept;
258220
size_t start = 0;
259221
while (start <= query.size()) {

0 commit comments

Comments
 (0)