mirror of
https://github.com/espruino/Espruino.git
synced 2025-12-08 19:06:15 +00:00
Added handling of query in url.parse - still not fully compatible though (fix #205)
This commit is contained in:
parent
2015b467da
commit
6d5136f325
@ -10,6 +10,7 @@
|
||||
Lower USB interrupt priority, remove pesky PriorityGroupConfig that was breaking other IRQ priorities
|
||||
Until we sort out SPI RX and IRQs, lower default SPI baud rate to stop timeouts
|
||||
console.log and print output JSON now (part of #206)
|
||||
Added handling of query in url.parse (fix #205)
|
||||
|
||||
1v48 : Fix issue where the size of command history is being reported wrong and so process.memory().free is reported wrong too
|
||||
We now loop without a seek to position inside the string (much faster if loop is not near the start of a fn) (fix #53)
|
||||
|
||||
@ -105,7 +105,7 @@ JsVar *jswrap_http_request(JsVar *options, JsVar *callback) {
|
||||
if (!checkOnline()) return 0;
|
||||
bool unlockOptions = false;
|
||||
if (jsvIsString(options)) {
|
||||
options = jswrap_url_parse(options);
|
||||
options = jswrap_url_parse(options, false);
|
||||
unlockOptions = true;
|
||||
}
|
||||
if (!jsvIsObject(options)) {
|
||||
@ -237,10 +237,11 @@ void jswrap_httpCRq_end(JsVar *parent, JsVar *data) {
|
||||
/*JSON{ "type":"staticmethod",
|
||||
"class" : "url", "name" : "parse",
|
||||
"generate" : "jswrap_url_parse",
|
||||
"params" : [ [ "urlStr", "JsVar", "A URL to be parsed"] ],
|
||||
"return" : ["JsVar", "An object containing options for ```http.request``` or ```http.get```"]
|
||||
"params" : [ [ "urlStr", "JsVar", "A URL to be parsed"],
|
||||
[ "parseQuery", "bool", "Whether to parse the query string or not (default = false)"] ],
|
||||
"return" : ["JsVar", ["An object containing options for ```http.request``` or ```http.get```"] ]
|
||||
}*/
|
||||
JsVar *jswrap_url_parse(JsVar *url) {
|
||||
JsVar *jswrap_url_parse(JsVar *url, bool parseQuery) {
|
||||
if (!jsvIsString(url)) return 0;
|
||||
JsVar *obj = jsvNewWithFlags(JSV_OBJECT);
|
||||
if (!obj) return 0; // out of memory
|
||||
@ -253,16 +254,19 @@ JsVar *jswrap_url_parse(JsVar *url) {
|
||||
int addrStart = -1;
|
||||
int portStart = -1;
|
||||
int pathStart = -1;
|
||||
int searchStart = -1;
|
||||
int charIdx = 0;
|
||||
int portNumber = 0;
|
||||
while (jsvStringIteratorHasChar(&it)) {
|
||||
char ch = jsvStringIteratorGetChar(&it);
|
||||
if (ch == '/') {
|
||||
slashes++;
|
||||
if (addrStart>=0)
|
||||
pathStart = charIdx;
|
||||
if (colons==1 && slashes==2 && addrStart<0)
|
||||
pathStart = charIdx;
|
||||
if (colons==1 && slashes==2 && addrStart<0) {
|
||||
addrStart = charIdx;
|
||||
pathStart = -1;
|
||||
searchStart = -1;
|
||||
}
|
||||
}
|
||||
if (ch == ':') {
|
||||
colons++;
|
||||
@ -274,6 +278,10 @@ JsVar *jswrap_url_parse(JsVar *url) {
|
||||
portNumber = portNumber*10 + (ch-'0');
|
||||
}
|
||||
|
||||
if (ch == '?' && pathStart>=0) {
|
||||
searchStart = charIdx;
|
||||
}
|
||||
|
||||
jsvStringIteratorNext(&it);
|
||||
charIdx++;
|
||||
}
|
||||
@ -283,23 +291,67 @@ JsVar *jswrap_url_parse(JsVar *url) {
|
||||
if (pathStart<0) pathStart = charIdx;
|
||||
int addrEnd = (portStart>=0) ? portStart : pathStart;
|
||||
// pull out details
|
||||
JsVar *method = jsvNewFromString("GET");
|
||||
jsvUnLock(jsvAddNamedChild(obj, method, "method"));
|
||||
jsvUnLock(method);
|
||||
JsVar *host = jsvNewFromEmptyString();
|
||||
jsvAppendStringVar(host, url, addrStart+1, addrEnd-(addrStart+1));
|
||||
jsvUnLock(jsvAddNamedChild(obj, host, "host"));
|
||||
jsvUnLock(host);
|
||||
JsVar *path = jsvNewFromEmptyString();
|
||||
jsvAppendStringVar(path, url, pathStart, JSVAPPENDSTRINGVAR_MAXLENGTH);
|
||||
if (jsvGetStringLength(path)==0) jsvAppendString(path, "/");
|
||||
jsvUnLock(jsvAddNamedChild(obj, path, "path"));
|
||||
jsvUnLock(path);
|
||||
jsvUnLock(jsvObjectSetChild(obj, "method", jsvNewFromString("GET")));
|
||||
jsvUnLock(jsvObjectSetChild(obj, "host", jsvNewFromStringVar(url, addrStart+1, addrEnd-(addrStart+1))));
|
||||
|
||||
JsVar *v;
|
||||
|
||||
v= jsvNewFromStringVar(url, pathStart, JSVAPPENDSTRINGVAR_MAXLENGTH);
|
||||
if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
|
||||
jsvUnLock(jsvObjectSetChild(obj, "path", v));
|
||||
|
||||
v = jsvNewFromStringVar(url, pathStart, (searchStart>=0)?(searchStart-pathStart):JSVAPPENDSTRINGVAR_MAXLENGTH);
|
||||
if (jsvGetStringLength(v)==0) jsvAppendString(v, "/");
|
||||
jsvUnLock(jsvObjectSetChild(obj, "pathname", v));
|
||||
|
||||
jsvUnLock(jsvObjectSetChild(obj, "search", (searchStart>=0)?jsvNewFromStringVar(url, searchStart, JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull()));
|
||||
|
||||
if (portNumber<=0 || portNumber>65535) portNumber=80;
|
||||
JsVar *port = jsvNewFromInteger(portNumber);
|
||||
jsvUnLock(jsvAddNamedChild(obj, port, "port"));
|
||||
jsvUnLock(port);
|
||||
jsvUnLock(jsvObjectSetChild(obj, "port", jsvNewFromInteger(portNumber)));
|
||||
|
||||
JsVar *query = (searchStart>=0)?jsvNewFromStringVar(url, searchStart+1, JSVAPPENDSTRINGVAR_MAXLENGTH):jsvNewNull();
|
||||
if (parseQuery && !jsvIsNull(query)) {
|
||||
jsvStringIteratorNew(&it, query, 0);
|
||||
jsvUnLock(query);
|
||||
query = jsvNewWithFlags(JSV_OBJECT);
|
||||
|
||||
JsVar *key = jsvNewFromEmptyString();
|
||||
JsVar *val = jsvNewFromEmptyString();
|
||||
bool hadEquals = false;
|
||||
|
||||
while (jsvStringIteratorHasChar(&it)) {
|
||||
char ch = jsvStringIteratorGetChar(&it);
|
||||
if (ch=='&') {
|
||||
if (jsvGetStringLength(key)>0 || jsvGetStringLength(val)>0) {
|
||||
jsvMakeIntoVariableName(key, val);
|
||||
jsvAddName(query, key);
|
||||
jsvUnLock(key);
|
||||
jsvUnLock(val);
|
||||
key = jsvNewFromEmptyString();
|
||||
val = jsvNewFromEmptyString();
|
||||
hadEquals = false;
|
||||
}
|
||||
} else if (!hadEquals && ch=='=') {
|
||||
hadEquals = true;
|
||||
} else {
|
||||
if (hadEquals) jsvAppendCharacter(val, ch);
|
||||
else jsvAppendCharacter(key, ch);
|
||||
}
|
||||
jsvStringIteratorNext(&it);
|
||||
charIdx++;
|
||||
}
|
||||
jsvStringIteratorFree(&it);
|
||||
|
||||
if (jsvGetStringLength(key)>0 || jsvGetStringLength(val)>0) {
|
||||
jsvMakeIntoVariableName(key, val);
|
||||
jsvAddName(query, key);
|
||||
}
|
||||
jsvUnLock(key);
|
||||
jsvUnLock(val);
|
||||
}
|
||||
jsvUnLock(jsvObjectSetChild(obj, "query", query));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -30,4 +30,4 @@ void jswrap_httpCRq_end(JsVar *parent, JsVar *data);
|
||||
|
||||
void jswrap_httpCRs_on(JsVar *parent, JsVar *event, JsVar *callback);
|
||||
|
||||
JsVar *jswrap_url_parse(JsVar *url);
|
||||
JsVar *jswrap_url_parse(JsVar *url, bool parseQuery);
|
||||
|
||||
@ -934,6 +934,14 @@ void jsvAppendStringVar(JsVar *var, const JsVar *str, int stridx, int maxLength)
|
||||
jsvUnLock(block);
|
||||
}
|
||||
|
||||
/** Create a new variable from a substring. argument must be a string. stridx = start char or str, maxLength = max number of characters (can be JSVAPPENDSTRINGVAR_MAXLENGTH).
|
||||
* stridx can be negative to go from end of string */
|
||||
JsVar *jsvNewFromStringVar(const JsVar *str, int stridx, int maxLength) {
|
||||
JsVar *var = jsvNewFromEmptyString();
|
||||
if (var) jsvAppendStringVar(var, str, stridx, maxLength);
|
||||
return var;
|
||||
}
|
||||
|
||||
/** Append all of str to var. Both must be strings. */
|
||||
void jsvAppendStringVarComplete(JsVar *var, const JsVar *str) {
|
||||
jsvAppendStringVar(var, str, 0, JSVAPPENDSTRINGVAR_MAXLENGTH);
|
||||
|
||||
@ -141,6 +141,10 @@ JsVar *jsvNewWithFlags(JsVarFlags flags);
|
||||
JsVar *jsvNewFromString(const char *str); ///< Create a new string
|
||||
JsVar *jsvNewStringOfLength(unsigned int byteLength); ///< Create a new string of the given length - full of 0s
|
||||
static inline JsVar *jsvNewFromEmptyString() { return jsvNewWithFlags(JSV_STRING); } ;///< Create a new empty string
|
||||
static inline JsVar *jsvNewNull() { return jsvNewWithFlags(JSV_NULL); } ;///< Create a new null variable
|
||||
/** Create a new variable from a substring. argument must be a string. stridx = start char or str, maxLength = max number of characters (can be JSVAPPENDSTRINGVAR_MAXLENGTH).
|
||||
* stridx can be negative to go from end of string */
|
||||
JsVar *jsvNewFromStringVar(const JsVar *str, int stridx, int maxLength);
|
||||
JsVar *jsvNewFromInteger(JsVarInt value);
|
||||
JsVar *jsvNewFromBool(bool value);
|
||||
JsVar *jsvNewFromFloat(JsVarFloat value);
|
||||
|
||||
13
tests/test_url_parse.js
Normal file
13
tests/test_url_parse.js
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
result=1;
|
||||
|
||||
function test(a,b) {
|
||||
if (JSON.stringify(a)!=JSON.stringify(b)) {
|
||||
console.log("FAIL",a,"vs",b);
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
|
||||
test(url.parse("/hello?a=b"), {"method":"GET","host":"","path":"/hello?a=b","pathname":"/hello","search":"?a=b","port":80,"query":"a=b"})
|
||||
test(url.parse("/hello?a=b&c=dd",false), {"method":"GET","host":"","path":"/hello?a=b&c=dd","pathname":"/hello","search":"?a=b&c=dd","port":80,"query":"a=b&c=dd"})
|
||||
test(url.parse("/hello?a=b&c=dd",true), {"method":"GET","host":"","path":"/hello?a=b&c=dd","pathname":"/hello","search":"?a=b&c=dd","port":80,"query":{"a":"b","c":"dd"}})
|
||||
Loading…
x
Reference in New Issue
Block a user