}
q.append (CharConst (" HTTP/1.0" kCRLF));
} else {
- q.append (CharConst ("?"));
if (getparams ()) {
+ q.append (CharConst ("?"));
appendQueryForm (getparams (), q);
} else if (params ()) {
+ q.append (CharConst ("?"));
appendQueryForm (params (), q);
}
q.append (CharConst (" HTTP/1.0" kCRLF));
while (e) {
if (a = e->car ()) {
if (c > 0)
- u.assign (uAmp).append (urlencode (cv (to_string (a->car ()))));
- else
- u.assign (urlencode (cv (to_string (a->car ()))));
+ u.append (uAmp);
+ u.append (percentEncode (cv (to_string (a->car ()))));
u.append (uEq);
out.write (&*u.begin (), u.length ());
- u.assign (urlencode (cv (to_string (a->cdr ()))));
+ u.assign (percentEncode (cv (to_string (a->cdr ()))));
out.write (&*u.begin (), u.length ());
c ++;
}
while (e) {
if (a = e->car ()) {
if (c > 0)
- out.append (uAmp).append (urlencode (cv (to_string (a->car ()))));
- else
- out.append (urlencode (cv (to_string (a->car ()))));
+ out.append (uAmp);
+ out.append (percentEncode (cv (to_string (a->car ()))));
out.append (uEq);
- out.append (urlencode (cv (to_string (a->cdr ()))));
+ out.append (percentEncode (cv (to_string (a->cdr ()))));
c ++;
}
nextNode (e);
while (e) {
if (a = e->car ()) {
if (c > 0)
- u.assign (uAmp).append (urlencode (cv (to_string (a->car ()))));
- else
- u.assign (urlencode (cv (to_string (a->car ()))));
+ u.append (uAmp);
+ u.append (percentEncode (cv (to_string (a->car ()))));
u.append (uEq);
ans += u.length ();
- u.assign (urlencode (cv (to_string (a->cdr ()))));
+ u.assign (percentEncode (cv (to_string (a->cdr ()))));
ans += u.length ();
c ++;
}
ustring u;
u.assign (CharConst ("--")).append (separator).append (uCRLF);
- u.append (CharConst ("Content-Disposition: form-data; name=" kQ2)).append (urlencode (cv (name))).append (CharConst (kQ2 kCRLF kCRLF));
+ u.append (CharConst ("Content-Disposition: form-data; name=" kQ2)).append (percentEncode (cv (name))).append (CharConst (kQ2 kCRLF kCRLF));
u.append (cv (val)).append (uCRLF);
if (out)
out->write (&*u.begin (), u.length ());
off_t s;
u.assign (CharConst ("--")).append (separator).append (uCRLF);
- u.append (CharConst ("Content-Disposition: form-data; name=" kQ2)).append (urlencode (cv (name))).append (CharConst (kQ2 "; filename=" kQ2)).append (slashEncode (filename)).append (CharConst (kQ2 kCRLF));
+ u.append (CharConst ("Content-Disposition: form-data; name=" kQ2)).append (percentEncode (cv (name))).append (CharConst (kQ2 "; filename=" kQ2)).append (slashEncode (filename)).append (CharConst (kQ2 kCRLF));
u.append (CharConst ("Content-Type: ")).append (mimetype (getExt (filename))).append (CharConst (kCRLF kCRLF));
if (out)
out->write (&*u.begin (), u.length ());
return '0';
}
+static char hexchar_c (int c) {
+ if (0 <= c && c <= 9)
+ return '0' + c;
+ else if (10 <= c <= 15)
+ return 'A' - 10 + c;
+ else
+ return '0';
+}
+
static ustring percentHex (int c) {
ustring ans (3, '%');
return ans;
}
+static ustring percentHEX (int c) {
+ ustring ans (3, '%');
+
+ ans[1] = hexchar_c ((c >> 4) & 0x0f);
+ ans[2] = hexchar_c (c & 0x0f);
+ return ans;
+}
+
ustring urldecode_nonul (const ustring& str) {
ustring ans;
static uregex re ("(\\+)|%([0-9a-fA-F][0-9a-fA-F])|\\x00");
}
}
+#if 0
static ustring percentEncode (const ustring& text, uregex& re) {
/* $1 -> _
$2 -> %HEX
return text;
}
}
+#endif
+
+static ustring percentEncode (uiterator b, uiterator e, const uregex& re) {
+ // $1 -> _
+ // $2 -> %HEX
+ umatch m;
+ ustring ans;
+
+ while (b < e && usearch (b, e, m, re)) {
+ if (b < m[0].first)
+ ans.append (b, m[0].first);
+ if (m[1].matched) {
+ ans.append (uUScore);
+ } else if (m[2].matched) {
+ ans.append (percentHEX (*m[2].first));
+ } else {
+ assert (0);
+ }
+ b = m[0].second;
+ }
+ if (b < e)
+ ans.append (b, e);
+
+ return ans;
+}
+#if 0
ustring urlencode (const ustring& url) {
static uregex re ("(\\x00)|([^a-zA-Z0-9_.,/\x80-\xff-])");
return percentEncode (url, re);
}
+#endif
+
+ustring percentEncode (uiterator b, uiterator e) {
+ static uregex re ("(\\x00)|([^A-Za-z0-9_.~\x80-\xff-])");
+
+ return percentEncode (b, e, re);
+}
+
+ustring percentEncode (const ustring& str) {
+ return percentEncode (str.begin (), str.end ());
+}
+
+ustring percentEncode_path (uiterator b, uiterator e) {
+ uiterator i;
+ ustring ans;
+
+ for (i = b; i < e; i ++) {
+ if (*i == '/') {
+ if (b < i)
+ ans.append (percentEncode (b, i));
+ ans.append (CharConst ("/"));
+ b = i + 1;
+ }
+ }
+ if (b < e)
+ ans.append (percentEncode (b, e));
+
+ return ans;
+}
+
+ustring percentEncode_path (const ustring& str) {
+ percentEncode_path (str.begin (), str.end ());
+}
ustring percentDecode (const ustring& str) {
ustring ans;
ustring cookieencode (const ustring& text) {
static uregex re ("([\\x00-\\x1f\\x7f])|([ ,;%\\x80-\\xff])");
- return percentEncode (text, re);
+ return percentEncode (text.begin (), text.end (), re);
}
ustring cookiedecode (const ustring& text) {
ustring omitNonAscii (const ustring& str);
ustring omitNonAsciiWord (const ustring& str);
bool to_bool (const ustring& v);
-ustring urlencode (const ustring& url);
+ustring percentEncode (uiterator b, uiterator e);
+ustring percentEncode (const ustring& str);
+ustring percentEncode_path (uiterator b, uiterator e);
+ustring percentEncode_path (const ustring& str);
ustring percentDecode (const ustring& str);
ustring cookieencode (const ustring& text);
ustring cookiedecode (const ustring& text);
nextNode (arg);
}
- return newMNode_str (new ustring (urlencode (str)));
+ return newMNode_str (new ustring (percentEncode (str)));
}
/*DOC:
static void location_sub (ustring& url, MNode* query, MNode* arg, MlEnv* mlenv) {
MNodePtr p;
MNode* a;
- ustring str;
int c;
uiterator b, e;
umatch m;
b = url.begin ();
e = url.end ();
if (usearch (b, e, m, re)) {
- str = ustring (m[0].second, e);
- url = ustring (m[0].first, m[0].second) + urlencode (str);
+ url = ustring (m[0].first, m[0].second) + percentEncode_path (m[0].second, e);
} else {
- url = urlencode (url);
+ url = percentEncode_path (url);
}
c = 0;
else
url.append (CharConst ("&"));
c ++;
- url.append (urlencode (to_string (a->car ())));
+ url.append (percentEncode (to_string (a->car ())));
url.append (uEq);
- url.append (urlencode (to_string (a->cdr ())));
+ url.append (percentEncode (to_string (a->cdr ())));
} else {
throw (to_string (a) + uErrorBadValue);
}
url.append (CharConst ("&"));
c ++;
- str = to_string (p ()->car ());
- url.append (urlencode (str));
+ url.append (percentEncode (to_string (p ()->car ())));
url.append (uEq);
a = p ()->cdr ();
if (a && a->isCons ()) {
- str = to_string (a->car ());
- url.append (urlencode (str));
+ url.append (percentEncode (to_string (a->car ())));
}
}
nextNode (arg);
http->host.port = to_uint32 (ustring (m[5].first, m[5].second));
else
http->host.port = 0;
- http->path = urlencode (ustring (m[0].second - 1, e));
+ http->path = percentEncode_path (m[0].second - 1, e);
}
} else {
// throw (str + ": bad URL.");
http->proto.resize (0);
http->host.host.resize (0);
http->host.port = 0;
- http->path = urlencode (str);
+ http->path = percentEncode_path (str);
}
}
//#MTFUNC url mf_url
void mf_url (const std::vector<ustring>& args, MlEnv* mlenv) {
MNode* v;
- ustring u;
if (args.size () == 1) {
v = mlenv->getVar (args[0]);
if (v) {
- u = v->to_string ();
- u = urlencode (u);
- mlenv->env->output->out_raw (u);
+ mlenv->env->output->out_raw (percentEncode_path (v->to_string ()));
}
} else {
throw (uErrorWrongNumber); // ***
vpath.splitCharA ('/', names);
n = names.size () - 1;
for (i = 0; i <= n; i ++) {
- u = urlencode (names[i]->textOut (wiki));
- if (i > 0) {
- path.append (uSlash).append (u);
- } else {
- path.append (u);
- }
+ u = percentEncode (names[i]->textOut (wiki));
+ if (i > 0)
+ path.append (uSlash);
+ path.append (u);
}
if (fparams) {
if (i > 0)
params.append (uAmp);
if (namevals[i].get()->splitChar (wiki, '=', name, value)) {
- params.append (urlencode (name)).append (uEq).append (urlencode (value));
+ params.append (percentEncode (name)).append (uEq).append (percentEncode (value));
} else {
- params.append (urlencode (name));
+ params.append (percentEncode (name));
}
}
}
if (fanchor) {
- anchor = urlencode (vanchor.textOut (wiki));
+ anchor = percentEncode (vanchor.textOut (wiki));
}
return true;