static PRBool IsInNoProxyList(const nsACString& aHost, PRInt32 aPort, const char* noProxyVal) { NS_ASSERTION(aPort >= 0, "Negative port?"); nsCAutoString noProxy(noProxyVal); if (noProxy.EqualsLiteral("*")) return PR_TRUE; noProxy.StripWhitespace(); nsReadingIterator<char> pos; nsReadingIterator<char> end; noProxy.BeginReading(pos); noProxy.EndReading(end); while (pos != end) { nsReadingIterator<char> last = pos; nsReadingIterator<char> nextPos; if (FindCharInReadable(',', last, end)) { nextPos = last; ++nextPos; } else { last = end; nextPos = end; } nsReadingIterator<char> colon = pos; PRInt32 port = -1; if (FindCharInReadable(':', colon, last)) { ++colon; nsDependentCSubstring portStr(colon, last); nsCAutoString portStr2(portStr); // We need this for ToInteger. String API's suck. PRInt32 err; port = portStr2.ToInteger(&err); if (NS_FAILED(err)) { port = -2; // don't match any port, so we ignore this pattern } --colon; } else { colon = last; } if (port == -1 || port == aPort) { nsDependentCSubstring hostStr(pos, colon); // By using StringEndsWith instead of an equality comparator, we can include sub-domains if (StringEndsWith(aHost, hostStr, nsCaseInsensitiveCStringComparator())) return PR_TRUE; } pos = nextPos; } return PR_FALSE; }
Variant f_call_user_func_rpc(int _argc, CStrRef host, int port, CStrRef auth, int timeout, CVarRef function, CArrRef _argv /* = null_array */) { string url = "http://"; url += host.data(); url += ":"; url += lexical_cast<string>(port); url += "/call_user_func_serialized?auth="; url += auth.data(); Array blob = CREATE_MAP2("func", function, "args", _argv); String message = f_serialize(blob); string hostStr(host.data()); vector<string> headers; LibEventHttpClientPtr http = LibEventHttpClient::Get(hostStr, port); if (!http->send(url, headers, timeout < 0 ? 0 : timeout, false, message.data(), message.size())) { raise_warning("Unable to send RPC request"); return false; } int code = http->getCode(); if (code <= 0) { raise_warning("Server timed out or unable to find specified URL: %s", url.c_str()); return false; } int len = 0; char *response = http->recv(len); String sresponse(response, len, AttachString); if (code != 200) { raise_warning("Internal server error: %d %s", code, HttpProtocol::GetReasonString(code)); return false; } // This double decoding can be avoided by modifying RPC server to directly // take PHP serialization format. Variant res = f_unserialize(f_json_decode(sresponse)); if (!res.isArray()) { raise_warning("Internal protocol error"); return false; } if (res.toArray().exists("exception")) { throw res["exception"]; } return res["ret"]; }
bool XboxServer::PostMessage(const String& message, const String& host /* = "localhost" */) { if (isLocalHost(host)) { Lock l(s_dispatchMutex); if (!s_dispatcher) { return false; } XboxTransport *job = new XboxTransport(message.toCppString()); job->incRefCount(); // paired with worker's decRefCount() assert(s_dispatcher); s_dispatcher->enqueue(job); return true; } else { // remote string url = "http://"; url += host.data(); url += "/xbox_post_message"; std::vector<std::string> headers; std::string hostStr(host.data()); LibEventHttpClientPtr http = LibEventHttpClient::Get(hostStr, RuntimeOption::XboxServerPort); if (http->send(url, headers, 0, false, message.data(), message.size())) { int code = http->getCode(); if (code > 0) { int len = 0; char *response = http->recv(len); String sresponse(response, len, AttachString); if (code == 200 && same( unserialize_from_string( sresponse, VariableUnserializer::Type::Internal ), true ) ) { return true; } } } } return false; }
bool XboxServer::SendMessage(const String& message, Array& ret, int timeout_ms, const String& host /* = "localhost" */) { if (isLocalHost(host)) { XboxTransport *job; { Lock l(s_dispatchMutex); if (!s_dispatcher) { return false; } job = new XboxTransport(message); job->incRefCount(); // paired with worker's decRefCount() job->incRefCount(); // paired with decRefCount() at below assert(s_dispatcher); s_dispatcher->enqueue(job); } if (timeout_ms <= 0) { timeout_ms = RuntimeOption::XboxDefaultLocalTimeoutMilliSeconds; } int code = 0; String response = job->getResults(code, timeout_ms); job->decRefCount(); // i'm done with this job if (code > 0) { ret.set(s_code, code); if (code == 200) { ret.set(s_response, unserialize_from_string(response)); } else { ret.set(s_error, response); } return true; } } else { // remote string url = "http://"; url += host.data(); url += '/'; url += RuntimeOption::XboxProcessMessageFunc; int timeoutSeconds = timeout_ms / 1000; if (timeoutSeconds <= 0) { timeoutSeconds = RuntimeOption::XboxDefaultRemoteTimeoutSeconds; } string hostStr(host.data()); std::vector<std::string> headers; LibEventHttpClientPtr http = LibEventHttpClient::Get(hostStr, RuntimeOption::XboxServerPort); if (http->send(url, headers, timeoutSeconds, false, message.data(), message.size())) { int code = http->getCode(); if (code > 0) { int len = 0; char *response = http->recv(len); String sresponse(response, len, AttachString); ret.set(s_code, code); if (code == 200) { ret.set(s_response, unserialize_from_string(sresponse)); } else { ret.set(s_error, sresponse); } return true; } // code wasn't correctly set by http client, treat it as not found ret.set(s_code, 404); ret.set(s_error, "http client failed"); } } return false; }