Browse Source

query-string unescape moved to js land

v0.7.4-release
Ryan Dahl 14 years ago
parent
commit
57d8172906
  1. 72
      lib/querystring.js
  2. 81
      src/node_http_parser.cc

72
lib/querystring.js

@ -3,8 +3,78 @@
var QueryString = exports; var QueryString = exports;
var urlDecode = process.binding("http_parser").urlDecode; var urlDecode = process.binding("http_parser").urlDecode;
function charCode (c) {
return c.charCodeAt(0);
}
// a safe fast alternative to decodeURIComponent // a safe fast alternative to decodeURIComponent
QueryString.unescape = urlDecode; QueryString.unescape = function (s, decodeSpaces) {
var out = new Buffer(s.length);
var state = "CHAR"; // states: CHAR, HEX0, HEX1
var n, m, hexchar;
for (var inIndex = 0, outIndex = 0; inIndex <= s.length; inIndex++) {
var c = s.charCodeAt(inIndex);
switch (state) {
case 'CHAR':
switch (c) {
case charCode('%'):
n = 0;
m = 0;
state = 'HEX0';
break;
case charCode('+'):
if (decodeSpaces) c = charCode(' ');
// pass thru
default:
out[outIndex++] = c;
break;
}
break;
case 'HEX0':
state = 'HEX1';
hexchar = c;
if (charCode('0') <= c && c <= charCode('9')) {
n = c - charCode('0');
} else if (charCode('a') <= c && c <= charCode('f')) {
n = c - charCode('a') + 10;
} else if (charCode('A') <= c && c <= charCode('F')) {
n = c - charCode('A') + 10;
} else {
out[outIndex++] = charCode('%');
out[outIndex++] = c;
state = 'CHAR';
break;
}
break;
case 'HEX1':
state = 'CHAR';
if (charCode('0') <= c && c <= charCode('9')) {
m = c - charCode('0');
} else if (charCode('a') <= c && c <= charCode('f')) {
m = c - charCode('a') + 10;
} else if (charCode('A') <= c && c <= charCode('F')) {
m = c - charCode('A') + 10;
} else {
out[outIndex++] = charCode('%');
out[outIndex++] = hexchar;
out[outIndex++] = c;
break;
}
out[outIndex++] = 16*n + m;
break;
}
}
// TODO support returning arbitrary buffers.
return out.toString('utf8', 0, outIndex-1);
};
QueryString.escape = function (str) { QueryString.escape = function (str) {
return encodeURIComponent(str); return encodeURIComponent(str);

81
src/node_http_parser.cc

@ -338,86 +338,6 @@ class Parser : public ObjectWrap {
}; };
static Handle<Value> UrlDecode (const Arguments& args) {
HandleScope scope;
if (!args[0]->IsString()) {
return ThrowException(Exception::TypeError(
String::New("First arg must be a string")));
}
bool decode_spaces = args[1]->IsTrue();
String::Utf8Value in_v(args[0]->ToString());
size_t l = in_v.length();
char* out = strdup(*in_v);
enum { CHAR, HEX0, HEX1 } state = CHAR;
int n, m, hexchar;
size_t in_index = 0, out_index = 0;
char c;
for (; in_index <= l; in_index++) {
c = out[in_index];
switch (state) {
case CHAR:
switch (c) {
case '%':
n = 0;
m = 0;
state = HEX0;
break;
case '+':
if (decode_spaces) c = ' ';
// pass thru
default:
out[out_index++] = c;
break;
}
break;
case HEX0:
state = HEX1;
hexchar = c;
if ('0' <= c && c <= '9') {
n = c - '0';
} else if ('a' <= c && c <= 'f') {
n = c - 'a' + 10;
} else if ('A' <= c && c <= 'F') {
n = c - 'A' + 10;
} else {
out[out_index++] = '%';
out[out_index++] = c;
state = CHAR;
break;
}
break;
case HEX1:
state = CHAR;
if ('0' <= c && c <= '9') {
m = c - '0';
} else if ('a' <= c && c <= 'f') {
m = c - 'a' + 10;
} else if ('A' <= c && c <= 'F') {
m = c - 'A' + 10;
} else {
out[out_index++] = '%';
out[out_index++] = hexchar;
out[out_index++] = c;
break;
}
out[out_index++] = 16*n + m;
break;
}
}
Local<String> out_v = String::New(out, out_index-1);
free(out);
return scope.Close(out_v);
}
void InitHttpParser(Handle<Object> target) { void InitHttpParser(Handle<Object> target) {
HandleScope scope; HandleScope scope;
@ -430,7 +350,6 @@ void InitHttpParser(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(t, "reinitialize", Parser::Reinitialize); NODE_SET_PROTOTYPE_METHOD(t, "reinitialize", Parser::Reinitialize);
target->Set(String::NewSymbol("HTTPParser"), t->GetFunction()); target->Set(String::NewSymbol("HTTPParser"), t->GetFunction());
NODE_SET_METHOD(target, "urlDecode", UrlDecode);
on_message_begin_sym = NODE_PSYMBOL("onMessageBegin"); on_message_begin_sym = NODE_PSYMBOL("onMessageBegin");
on_path_sym = NODE_PSYMBOL("onPath"); on_path_sym = NODE_PSYMBOL("onPath");

Loading…
Cancel
Save