/* Map options to an attribute string. Remove all internal control specific options and transparently handle URI link options. WARNING: this returns a non-cloned reference and relies on no GC yield until the returned value is used or cloned. This is done as an optimization to reduce memeory allocations. */ static cchar *map(HttpConn *conn, MprHash *options) { Esp *esp; EspReq *req; MprHash *params; MprKey *kp; MprBuf *buf; cchar *value; char *pstr; if (options == 0 || mprGetHashLength(options) == 0) { return MPR->emptyString; } req = conn->data; if (httpGetOption(options, EDATA("refresh"), 0) && !httpGetOption(options, "id", 0)) { httpAddOption(options, "id", sfmt("id_%d", req->lastDomID++)); } esp = MPR->espService; buf = mprCreateBuf(-1, -1); for (kp = 0; (kp = mprGetNextKey(options, kp)) != 0; ) { if (kp->type != MPR_JSON_OBJ && kp->type != MPR_JSON_ARRAY && !mprLookupKey(esp->internalOptions, kp->key)) { mprPutCharToBuf(buf, ' '); value = kp->data; /* Support link template resolution for these options */ if (smatch(kp->key, EDATA("click")) || smatch(kp->key, EDATA("remote")) || smatch(kp->key, EDATA("refresh"))) { value = httpUriEx(conn, value, options); if ((params = httpGetOptionHash(options, "params")) != 0) { pstr = (char*) ""; for (kp = 0; (kp = mprGetNextKey(params, kp)) != 0; ) { pstr = sjoin(pstr, mprUriEncode(kp->key, MPR_ENCODE_URI_COMPONENT), "=", mprUriEncode(kp->data, MPR_ENCODE_URI_COMPONENT), "&", NULL); } if (pstr[0]) { /* Trim last "&" */ pstr[strlen(pstr) - 1] = '\0'; } mprPutToBuf(buf, "%s-params='%s", params); } } mprPutStringToBuf(buf, kp->key); mprPutStringToBuf(buf, "='"); mprPutStringToBuf(buf, value); mprPutCharToBuf(buf, '\''); } } mprAddNullToBuf(buf); return mprGetBufStart(buf); }
/* Encode a Uri component (ECMA Standard) static function encodeComponent(str: String): String */ static EjsObj *encodeURIComponent(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { char *encoded; encoded = mprUriEncode(ejsToMulti(ejs, argv[0]), MPR_ENCODE_JS_URI_COMPONENT); return (EjsObj*) ejsCreateStringFromAsc(ejs, encoded); }
/* Prepare form data using json encoding. The objects are json encoded then URI encoded to be safe. */ static void prepForm(Ejs *ejs, EjsHttp *hp, char *prefix, EjsObj *data) { EjsName qname; EjsObj *vp; EjsString *value; cchar *key, *sep; char *encodedKey, *encodedValue, *newPrefix, *newKey; int i, count; jdata = ejsToJSON(ejs, data, NULL); if (prefix) { newKey = sjoin(prefix, ".", key, NULL); encodedKey = mprUriEncode(newKey, MPR_ENCODE_URI_COMPONENT); } else { encodedKey = mprUriEncode(key, MPR_ENCODE_URI_COMPONENT); } encodedValue = mprUriEncode(value->value, MPR_ENCODE_URI_COMPONENT); mprPutToBuf(hp->requestContent, "%s%s=%s", sep, encodedKey, encodedValue); }
/* Prepare form data as a series of key-value pairs. Data is formatted according to www-url-encoded specs by mprSetHttpFormData. Objects are flattened into a one level key/value pairs. Keys can have embedded "." separators. E.g. name=value&address=77%20Park%20Lane */ static void prepForm(Ejs *ejs, EjsHttp *hp, cchar *prefix, EjsObj *data) { EjsName qname; EjsObj *vp; EjsString *value; cchar *key, *sep, *vstr; char *encodedKey, *encodedValue, *newPrefix, *newKey; int i, count; count = ejsGetLength(ejs, data); for (i = 0; i < count; i++) { if (ejsIs(ejs, data, Array)) { key = itos(i); } else { qname = ejsGetPropertyName(ejs, data, i); key = ejsToMulti(ejs, qname.name); } vp = ejsGetProperty(ejs, data, i); if (vp == 0) { continue; } if (ejsGetLength(ejs, vp) > 0) { if (prefix) { newPrefix = sfmt("%s.%s", prefix, key); prepForm(ejs, hp, newPrefix, vp); } else { prepForm(ejs, hp, key, vp); } } else { value = ejsToString(ejs, vp); sep = (mprGetBufLength(hp->requestContent) > 0) ? "&" : ""; if (prefix) { newKey = sjoin(prefix, ".", key, NULL); encodedKey = mprUriEncode(newKey, MPR_ENCODE_URI_COMPONENT); } else { encodedKey = mprUriEncode(key, MPR_ENCODE_URI_COMPONENT); } vstr = ejsToMulti(ejs, value); encodedValue = mprUriEncode(vstr, MPR_ENCODE_URI_COMPONENT); mprPutToBuf(hp->requestContent, "%s%s=%s", sep, encodedKey, encodedValue); } } }
static bool okEscapeUri(MprTestGroup *gp, char *uri, char *expectedUri, int map) { char *escaped; escaped = mprUriEncode(uri, map); if (strcmp(expectedUri, escaped) == 0) { return 1; } mprLog(0, "Uri \"%s\" is escaped to be \n" "\"%s\" instead of \n\"%s\"\n", uri, escaped, expectedUri); return 0; }
/* Encode a Uri component static function encodeComponent(str: String): String */ static EjsString *uri_encodeComponent(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { return ejsCreateStringFromAsc(ejs, mprUriEncode(ejsToMulti(ejs, argv[0]), MPR_ENCODE_URI_COMPONENT)); }
/* Uri Encode a string (ECMA Standard) function encodeURI(str: String): String */ static EjsObj *encodeURI(Ejs *ejs, EjsObj *unused, int argc, EjsObj **argv) { return (EjsObj*) ejsCreateStringFromAsc(ejs, mprUriEncode(ejsToMulti(ejs, argv[0]), MPR_ENCODE_JS_URI)); }