inline boost::system::error_code connect( boost::asio::ip::tcp::socket::lowest_layer_type& socket, boost::asio::ip::tcp::resolver& resolver, const url& u, boost::system::error_code& ec) { // Create a query that corresponds to the url. std::ostringstream port_string; port_string << u.port(); // Get a list of endpoints corresponding to the query. boost::asio::ip::tcp::resolver::results_type endpoints = resolver.resolve(u.host(), port_string.str(), ec); if (ec) return ec; // Try each endpoint until we successfully establish a connection. ec = boost::asio::error::host_not_found; boost::asio::connect(socket, endpoints, ec); if (ec) return ec; // Disable the Nagle algorithm on all sockets. ec = boost::system::error_code(); socket.set_option(boost::asio::ip::tcp::no_delay(true), ec); return ec; }
void readsome(const boost::system::error_code& ec, std::size_t bytes_transferred) { if (ec == error::eof) { file.close(); if (!file) { ERROR "Cannot write to file " << filename; onerror(); } else if (filesize == 0) { ERROR "Empty segment " << file_url.to_string(); onerror(); } else { downloading = false; complete = true; auto download_duration = duration_cast<milliseconds>(steady_clock::now() - download_start).count(); INFO "Completed segment " << file_url.to_string() << " (" << std::setprecision(1) << std::fixed << (filesize / 1024.0 / 1024.0) << " MB) in " << download_duration << " ms (" << (filesize * 8000 / 1024.0 / 1024.0 / download_duration) << "Mbps)"; } } else if (ec) { ERROR "Error reading URL " << file_url.to_string() << ": " << ec.message(); onerror(); } else { file.write(&buffer[0], bytes_transferred); filesize += bytes_transferred; segment_stream.async_read_some(boost::asio::buffer(buffer), std::bind(&Segment::readsome, this, _1, _2)); } }
vector<url> get_config(const url &dst) throw (runtime_error) { map<string,string>::const_iterator it = _data.find("PROXY_ENABLED"); vector<url> response; if (it != _data.end() && it->second == "no") { response.push_back(url("direct://")); return response; } string key; string proxy; // If the URL is an ftp url, try to read the ftp proxy if (dst.get_scheme() == "ftp") key = "FTP_PROXY"; else if (dst.get_scheme() == "http") key = "HTTP_PROXY"; else if (dst.get_scheme() == "https") key = "HTTPS_PROXY"; it = _data.find(key); if (it != _data.end()) proxy = it->second; if (proxy.empty()) throw runtime_error("Unable to read configuration"); response.push_back(url(proxy)); return response; }
void async_connect(boost::asio::ip::tcp::socket::lowest_layer_type& socket, boost::asio::ip::tcp::resolver& resolver, const url& u, Handler handler) { std::ostringstream port_string; port_string << u.port(); connect_coro<Handler>(handler, socket, resolver)( boost::system::error_code(), u.host(), port_string.str()); }
string run(const url& url_) throw (bad_alloc) { vector<Value> args; args.push_back(glb.newString(url_.to_string())); args.push_back(glb.newString(url_.get_host())); Value res = glb.call("FindProxyForURL", args); if (res.isString() && !res.isException()) return res.toString(); return ""; }
vector<url> get_config(const url &dest) throw (runtime_error) { // Check for changes in the config fd_set rfds; struct timeval timeout = { 0, 0 }; vector<url> response; FD_ZERO(&rfds); FD_SET(fileno(this->read), &rfds); if (select(fileno(this->read)+1, &rfds, NULL, NULL, &timeout) > 0) this->read_data(); // Mode is wpad:// or pac+http://... if (this->data[PROXY_MODE] == "auto") { string pac = this->data[PROXY_AUTOCONFIG_URL]; response.push_back(url::is_valid(pac) ? url(string("pac+") + pac) : url("wpad://")); return response; } // Mode is http://... or socks://... else if (this->data[PROXY_MODE] == "manual") { bool auth = this->data[PROXY_USE_AUTHENTICATION] == "true"; string username = url::encode(this->data[PROXY_AUTH_USER], URL_ALLOWED_IN_USERINFO_ELEMENT); string password = url::encode(this->data[PROXY_AUTH_PASSWORD], URL_ALLOWED_IN_USERINFO_ELEMENT); // Get the per-scheme proxy settings if (dest.get_scheme() == "http") store_response("http", this->data[PROXY_HTTP_HOST], this->data[PROXY_HTTP_PORT], auth, username, password, response); else if (dest.get_scheme() == "https") // It is expected that the configured server is an // HTTP server that support CONNECT method. store_response("http", this->data[PROXY_SECURE_HOST], this->data[PROXY_SECURE_PORT], auth, username, password, response); else if (dest.get_scheme() == "ftp") // It is expected that the configured server is an // HTTP server that handles proxying FTP URLs // (e.g. request with header "Host: ftp://ftp.host.org") store_response("http", this->data[PROXY_FTP_HOST], this->data[PROXY_FTP_PORT], auth, username, password, response); store_response("socks", this->data[PROXY_SOCKS_HOST], this->data[PROXY_SOCKS_PORT], auth, username, password, response); // In case nothing matched, try HTTP Connect and fallback to direct. // If there is not secure HTTP proxy, this will only add direct:// to // the response if (response.size() == 0 && dest.get_scheme() != "http") { store_response("http", this->data[PROXY_SECURE_HOST], this->data[PROXY_SECURE_PORT], auth, username, password, response); response.push_back(url("direct://")); } } return response; }
natus_pacrunner(string pac, const url& pacurl) throw (bad_alloc) : pacrunner(pac, pacurl) { Value exc; // Create the basic context if (!eng.initialize()) goto error; glb = this->eng.newGlobal(); if (glb.isException()) goto error; // Add dnsResolve into the context if (!glb.set("dnsResolve", glb.newFunction(dnsResolve))) goto error; // Add myIpAddress into the context if (!glb.set("myIpAddress", glb.newFunction(myIpAddress))) goto error; // Add all other routines into the context exc = glb.evaluate(JAVASCRIPT_ROUTINES); if (exc.isException()) goto error; // Add the PAC into the context exc = glb.evaluate(pac.c_str(), pacurl.to_string()); if (exc.isException()) goto error; return; error: throw bad_alloc(); }
void websocket::connect(url const& target) { state_ = CONNECTING; if ( target.scheme() != "ws" && target.scheme() != "wss" ) { throw std::invalid_argument("Unsupported URL " + target.to_string()); } tcp_conn_.reset(new pion::tcp::connection(rt_.io_service(), target.is_scheme_secured())); // tcp_conn_->getSocket().set_option(boost::asio::ip::tcp::no_delay(true)); // disable ngale // create resolver and start async resolve boost::shared_ptr<tcp::resolver> resolver = boost::make_shared<tcp::resolver>(rt_.io_service()); tcp::resolver::query query(target.host(), std::to_string(static_cast<unsigned long long>(target.effective_port())), tcp::resolver::query::numeric_service); resolver->async_resolve(query, boost::bind(&websocket::handle_resolve, this, target, resolver, boost::asio::placeholders::error, boost::asio::placeholders::iterator)); }
string run(const url& url_) throw (bad_alloc) { JSStringRef str = NULL; JSValueRef val = NULL; string tmp; // Run the PAC tmp = string("FindProxyForURL(\"") + url_.to_string() + string("\", \"") + url_.get_host() + "\");"; str = JSStringCreateWithUTF8CString(tmp.c_str()); if (!str) throw bad_alloc(); if (!JSCheckScriptSyntax(this->jsctx, str, NULL, 0, NULL)) goto error; if (!(val = JSEvaluateScript(this->jsctx, str, NULL, NULL, 1, NULL))) goto error; if (!JSValueIsString(this->jsctx, val)) goto error; JSStringRelease(str); // Convert the return value to a string return jstr2str(JSValueToStringCopy(this->jsctx, val, NULL), true); error: JSStringRelease(str); return ""; }
boost::system::error_code open(const url& u, boost::system::error_code& ec) { file_.clear(); std::string path = u.path(); #if defined(BOOST_WINDOWS) if (path.length() >= 3 && path[0] == '/' && std::isalpha(path[1]) && path[2] == ':') path = path.substr(1); #endif // defined(BOOST_WINDOWS) file_.open(path.c_str(), std::ios_base::in | std::ios_base::binary); if (!file_) { ec = make_error_code(boost::system::errc::no_such_file_or_directory); return ec; } ec = boost::system::error_code(); return ec; }
bool url::operator==(const url& url) const { return m_orig == url.to_string(); }
std::string to_string(const url &url) { return { url.begin(), url.end() }; }
acceptor reactor::listen(const url& url){ return make_wrapper(pn_reactor_acceptor(pn_object(), url.host().c_str(), url.port().c_str(), 0)); }
bool websocket_hybi_17::handshake(url const& target) { _aspect_assert(state() == CONNECTING); // create websocket handshake request pion::http::request req(target.path_for_request()); req.add_header("Connection", "Upgrade"); req.add_header("Upgrade", "WebSocket"); req.add_header("Host", target.hostport()); req.add_header("Origin", target.origin()); string key(16, 0); std::generate(key.begin(), key.end(), rand_byte); string encoded_key; if ( !pion::algorithm::base64_encode(key, encoded_key) ) { return false; } req.add_header("Sec-WebSocket-Key", encoded_key); req.add_header("Sec-WebSocket-Version", "13"); // send request, recieve response error_code err = send_message(req); if ( !check_err(err, "send request") ) { return false; } pion::http::response resp(req); resp.receive(*tcp_conn_, err); if ( !check_err(err, "recieve response") ) { return false; } // check response if ( !is_websocket_upgrade(resp) ) { // it is not a hybi connection upgrade, give a chance for another protocol return false; } // Check reply key encoded_key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; encoded_key = crypto::sha1_digest(encoded_key.data(), encoded_key.size()); string resp_key; if ( !pion::algorithm::base64_encode(encoded_key, resp_key) ) { return false; } if ( resp_key != resp.get_header("Sec-WebSocket-Accept") ) { return false; } state_ = OPEN; on_connect(target.to_string()); wait_data(); return true; }
virtual bool ignore(url& url, const string &ignore) { bool result = false; uint16_t port = 0; const struct sockaddr *dst_ip = url.get_ips(false) ? url.get_ips(false)[0] : NULL; struct sockaddr *ign_ip = NULL, *net_ip = NULL; /* * IPv4 * IPv6 */ if ((ign_ip = sockaddr_from_string(ignore))) goto out; /* * IPv4/CIDR * IPv4/IPv4 * IPv6/CIDR * IPv6/IPv6 */ if (ignore.find('/') != string::npos) { ign_ip = sockaddr_from_string(ignore.substr(0, ignore.find('/'))); uint32_t cidr = 0; string mask = ignore.substr(ignore.find('/') + 1); if (mask.find('.') != string::npos) { /* A dotted netmask was used */ net_ip = sockaddr_from_string(mask); } else { /* If CIDR notation was used, get the netmask */ if (ign_ip && sscanf(mask.c_str(), "%d", &cidr) == 1) net_ip = sockaddr_from_cidr(ign_ip->sa_family, cidr); } if (ign_ip && net_ip && ign_ip->sa_family == net_ip->sa_family) goto out; delete[] ign_ip; delete[] net_ip; ign_ip = NULL; net_ip = NULL; } /* * IPv4:port * [IPv6]:port */ if (ignore.rfind(':') != string::npos && sscanf(ignore.substr(ignore.rfind(':')).c_str(), ":%hu", &port) == 1 && port > 0) { ign_ip = sockaddr_from_string(ignore.substr(ignore.rfind(':')).c_str()); /* Make sure this really is just a port and not just an IPv6 address */ if (ign_ip && (ign_ip->sa_family != AF_INET6 || ignore[0] == '[')) goto out; delete[] ign_ip; ign_ip = NULL; port = 0; } out: result = sockaddr_equals(dst_ip, ign_ip, net_ip); delete[] ign_ip; delete[] net_ip; return port != 0 ? (port == url.get_port() && result) : result; }