c646a30002
Many callsites of Array.set(litstr, ...)
289 linhas
8.9 KiB
C++
289 linhas
8.9 KiB
C++
/*
|
|
+----------------------------------------------------------------------+
|
|
| HipHop for PHP |
|
|
+----------------------------------------------------------------------+
|
|
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
|
|
| Copyright (c) 1997-2010 The PHP Group |
|
|
+----------------------------------------------------------------------+
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
|
| that is bundled with this package in the file LICENSE, and is |
|
|
| available through the world-wide-web at the following url: |
|
|
| http://www.php.net/license/3_01.txt |
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
+----------------------------------------------------------------------+
|
|
*/
|
|
|
|
#include <runtime/ext/ext_url.h>
|
|
#include <runtime/base/string_util.h>
|
|
#include <runtime/base/zend/zend_url.h>
|
|
#include <runtime/base/util/string_buffer.h>
|
|
#include <runtime/ext/ext_curl.h>
|
|
#include <runtime/ext/ext_string.h>
|
|
#include <runtime/ext/ext_file.h>
|
|
#include <runtime/ext/ext_preg.h>
|
|
#include <runtime/ext/ext_options.h>
|
|
|
|
namespace HPHP {
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
Variant f_base64_decode(CStrRef data, bool strict /* = false */) {
|
|
String decoded = StringUtil::Base64Decode(data, strict);
|
|
if (decoded.isNull()) {
|
|
return false;
|
|
}
|
|
return decoded;
|
|
}
|
|
|
|
String f_base64_encode(CStrRef data) {
|
|
String encoded = StringUtil::Base64Encode(data);
|
|
if (encoded.isNull()) {
|
|
return false;
|
|
}
|
|
return encoded;
|
|
}
|
|
|
|
Variant f_get_headers(CStrRef url, int format /* = 0 */) {
|
|
Variant c = f_curl_init();
|
|
f_curl_setopt(c, k_CURLOPT_URL, url);
|
|
f_curl_setopt(c, k_CURLOPT_RETURNTRANSFER, true);
|
|
f_curl_setopt(c, k_CURLOPT_HEADER, 1);
|
|
Variant res = f_curl_exec(c);
|
|
if (same(res, false)) {
|
|
return false;
|
|
}
|
|
|
|
String response = res.toString();
|
|
int pos = response.find("\r\n\r\n");
|
|
if (pos != String::npos) {
|
|
response = response.substr(0, pos);
|
|
}
|
|
|
|
Array ret = f_explode("\r\n", response);
|
|
if (!format) {
|
|
return ret;
|
|
}
|
|
|
|
Array assoc;
|
|
for (ArrayIter iter(ret); iter; ++iter) {
|
|
Array tokens = f_explode(": ", iter.second(), 2);
|
|
if (tokens.size() == 2) {
|
|
assoc.set(tokens[0], tokens[1]);
|
|
} else {
|
|
assoc.append(iter.second());
|
|
}
|
|
}
|
|
return assoc;
|
|
}
|
|
|
|
static String normalize_variable_name(CStrRef name) {
|
|
StringBuffer sb;
|
|
for (int i = 0; i < name.size(); i++) {
|
|
char ch = name.charAt(i);
|
|
if ((i > 0 && ch >= '0' && ch <= '9') ||
|
|
(ch >= 'a' && ch <= 'z') ||
|
|
(ch == '_')) {
|
|
sb.append(ch);
|
|
} else if (ch >= 'A' && ch <= 'Z') {
|
|
sb.append((char)(ch + 'a' - 'A'));
|
|
} else {
|
|
sb.append('_');
|
|
}
|
|
}
|
|
return sb.detach();
|
|
}
|
|
|
|
Array f_get_meta_tags(CStrRef filename, bool use_include_path /* = false */) {
|
|
String f = f_file_get_contents(filename);
|
|
|
|
Variant matches;
|
|
f_preg_match_all("/<meta\\s+name=\"(.*?)\"\\s+content=\"(.*?)\".*?>/s",
|
|
f, ref(matches), k_PREG_SET_ORDER);
|
|
|
|
Array ret = Array::Create();
|
|
for (ArrayIter iter(matches); iter; ++iter) {
|
|
Array pair = iter.second();
|
|
ret.set(normalize_variable_name(pair[1].toString()), pair[2]);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
static void url_encode_array(StringBuffer &ret, CVarRef varr,
|
|
std::set<void*> &seen_arrs,
|
|
CStrRef num_prefix, CStrRef key_prefix,
|
|
CStrRef key_suffix, CStrRef arg_sep) {
|
|
void *id = varr.is(KindOfArray) ?
|
|
(void*)varr.getArrayData() : (void*)varr.getObjectData();
|
|
if (!seen_arrs.insert(id).second) {
|
|
return; // recursive
|
|
}
|
|
|
|
Array arr = varr.toArray();
|
|
|
|
for (ArrayIter iter(arr); iter; ++iter) {
|
|
Variant data = iter.second();
|
|
if (data.isNull() || data.isResource()) continue;
|
|
|
|
String key = iter.first();
|
|
bool numeric = key.isNumeric();
|
|
|
|
if (data.is(KindOfArray) || data.is(KindOfObject)) {
|
|
String encoded;
|
|
if (numeric) {
|
|
encoded = key;
|
|
} else {
|
|
encoded = StringUtil::UrlEncode(key);
|
|
}
|
|
StringBuffer new_prefix(key_prefix.size() + num_prefix.size() +
|
|
encoded.size() + key_suffix.size() + 4);
|
|
new_prefix += key_prefix;
|
|
if (numeric) new_prefix += num_prefix;
|
|
new_prefix += encoded;
|
|
new_prefix += key_suffix;
|
|
new_prefix += "%5B";
|
|
url_encode_array(ret, data, seen_arrs, String(),
|
|
new_prefix.detach(), String("%5D", AttachLiteral),
|
|
arg_sep);
|
|
} else {
|
|
if (!ret.empty()) {
|
|
ret += arg_sep;
|
|
}
|
|
ret += key_prefix;
|
|
if (numeric) {
|
|
ret += num_prefix;
|
|
ret += key;
|
|
} else {
|
|
ret += StringUtil::UrlEncode(key);
|
|
}
|
|
ret += key_suffix;
|
|
ret += "=";
|
|
if (data.isInteger() || data.is(KindOfBoolean)) {
|
|
ret += String(data.toInt64());
|
|
} else if (data.is(KindOfDouble)) {
|
|
ret += String(data.toDouble());
|
|
} else {
|
|
ret += StringUtil::UrlEncode(data.toString());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Variant f_http_build_query(CVarRef formdata,
|
|
CStrRef numeric_prefix /* = null_string */,
|
|
CStrRef arg_separator /* = null_string */) {
|
|
if (!formdata.is(KindOfArray) && !formdata.is(KindOfObject)) {
|
|
throw_invalid_argument("formdata: (need Array or Object)");
|
|
return false;
|
|
}
|
|
|
|
String arg_sep;
|
|
if (arg_separator.isNull()) {
|
|
arg_sep = f_ini_get("arg_separator.output");
|
|
} else {
|
|
arg_sep = arg_separator;
|
|
}
|
|
|
|
StringBuffer ret(1024);
|
|
std::set<void*> seen_arrs;
|
|
url_encode_array(ret, formdata, seen_arrs,
|
|
numeric_prefix, String(), String(), arg_sep);
|
|
return ret.detach();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
static const StaticString s_scheme("scheme");
|
|
static const StaticString s_host("host");
|
|
static const StaticString s_user("user");
|
|
static const StaticString s_pass("pass");
|
|
static const StaticString s_path("path");
|
|
static const StaticString s_query("query");
|
|
static const StaticString s_fragment("fragment");
|
|
static const StaticString s_port("port");
|
|
|
|
#define RETURN_COMPONENT(name) \
|
|
if (resource.name != NULL) { \
|
|
String ret(resource.name, AttachString); \
|
|
resource.name = NULL; \
|
|
return ret; \
|
|
} \
|
|
|
|
#define SET_COMPONENT(name) \
|
|
if (resource.name != NULL) { \
|
|
ret.set(s_ ## name, String(resource.name, AttachString)); \
|
|
resource.name = NULL; \
|
|
} \
|
|
|
|
#define PHP_URL_SCHEME 0
|
|
#define PHP_URL_HOST 1
|
|
#define PHP_URL_PORT 2
|
|
#define PHP_URL_USER 3
|
|
#define PHP_URL_PASS 4
|
|
#define PHP_URL_PATH 5
|
|
#define PHP_URL_QUERY 6
|
|
#define PHP_URL_FRAGMENT 7
|
|
|
|
Variant f_parse_url(CStrRef url, int component /* = -1 */) {
|
|
Url resource;
|
|
if (!url_parse(resource, url.data(), url.size())) {
|
|
raise_notice("invalid url: %s", url.data());
|
|
return false;
|
|
}
|
|
|
|
if (component > -1) {
|
|
switch (component) {
|
|
case PHP_URL_SCHEME: RETURN_COMPONENT(scheme); break;
|
|
case PHP_URL_HOST: RETURN_COMPONENT(host); break;
|
|
case PHP_URL_USER: RETURN_COMPONENT(user); break;
|
|
case PHP_URL_PASS: RETURN_COMPONENT(pass); break;
|
|
case PHP_URL_PATH: RETURN_COMPONENT(path); break;
|
|
case PHP_URL_QUERY: RETURN_COMPONENT(query); break;
|
|
case PHP_URL_FRAGMENT: RETURN_COMPONENT(fragment); break;
|
|
case PHP_URL_PORT:
|
|
if (resource.port) {
|
|
return resource.port;
|
|
}
|
|
break;
|
|
default:
|
|
throw_invalid_argument("component: %d", component);
|
|
return false;
|
|
}
|
|
return uninit_null();
|
|
}
|
|
|
|
ArrayInit ret(8);
|
|
SET_COMPONENT(scheme);
|
|
SET_COMPONENT(host);
|
|
SET_COMPONENT(user);
|
|
SET_COMPONENT(pass);
|
|
SET_COMPONENT(path);
|
|
SET_COMPONENT(query);
|
|
SET_COMPONENT(fragment);
|
|
if (resource.port) {
|
|
ret.set("port", (int64_t)resource.port);
|
|
}
|
|
return ret.create();
|
|
}
|
|
|
|
String f_rawurldecode(CStrRef str) {
|
|
return StringUtil::UrlDecode(str, false);
|
|
}
|
|
|
|
String f_rawurlencode(CStrRef str) {
|
|
return StringUtil::UrlEncode(str, false);
|
|
}
|
|
|
|
String f_urldecode(CStrRef str) {
|
|
return StringUtil::UrlDecode(str, true);
|
|
}
|
|
|
|
String f_urlencode(CStrRef str) {
|
|
return StringUtil::UrlEncode(str, true);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
}
|