function RetrieveWebpage($url, $options = array()) { $startts = microtime(true); $timeout = isset($options["timeout"]) ? $options["timeout"] : false; if (!function_exists("stream_socket_client") && !function_exists("fsockopen")) { return array("success" => false, "error" => HTTPTranslate("The functions 'stream_socket_client' and 'fsockopen' do not exist."), "errorcode" => "function_check"); } // Process the URL. $url = trim($url); $url = ExtractURL($url); if ($url["scheme"] != "http" && $url["scheme"] != "https") { return array("success" => false, "error" => HTTPTranslate("RetrieveWebpage() only supports the 'http' and 'https' protocols."), "errorcode" => "protocol_check"); } $secure = $url["scheme"] == "https"; $protocol = $secure ? isset($options["protocol"]) && strtolower($options["protocol"]) == "ssl" ? "ssl" : "tls" : "tcp"; if (function_exists("stream_get_transports") && !in_array($protocol, stream_get_transports())) { return array("success" => false, "error" => HTTPTranslate("The desired transport protocol '%s' is not installed.", $protocol), "errorcode" => "transport_not_installed"); } $host = str_replace(" ", "-", HTTPHeaderValueCleanup($url["host"])); if ($host == "") { return array("success" => false, "error" => HTTPTranslate("Invalid URL.")); } $port = (int) $url["port"] ? (int) $url["port"] : ($secure ? 443 : 80); $defaultport = !$secure && $port == 80 || $secure && $port == 443; $path = $url["path"] == "" ? "/" : $url["path"]; $query = $url["query"]; $username = $url["loginusername"]; $password = $url["loginpassword"]; // Cleanup input headers. if (!isset($options["headers"])) { $options["headers"] = array(); } $options["headers"] = HTTPNormalizeHeaders($options["headers"]); // Process the proxy URL (if specified). $useproxy = isset($options["proxyurl"]) && trim($options["proxyurl"]) != ""; if ($useproxy) { $proxyurl = trim($options["proxyurl"]); $proxyurl = ExtractURL($proxyurl); $proxysecure = $proxyurl["scheme"] == "https"; $proxyprotocol = $proxysecure ? isset($options["proxyprotocol"]) && strtolower($options["proxyprotocol"]) == "ssl" ? "ssl" : "tls" : "tcp"; if (function_exists("stream_get_transports") && !in_array($proxyprotocol, stream_get_transports())) { return array("success" => false, "error" => HTTPTranslate("The desired transport proxy protocol '%s' is not installed.", $proxyprotocol), "errorcode" => "proxy_transport_not_installed"); } $proxyhost = str_replace(" ", "-", HTTPHeaderValueCleanup($proxyurl["host"])); $proxyport = (int) $proxyurl["port"] ? (int) $proxyurl["port"] : ($proxysecure ? 443 : 80); $proxypath = $proxyurl["path"] == "" ? "/" : $proxyurl["path"]; $proxyusername = $proxyurl["loginusername"]; $proxypassword = $proxyurl["loginpassword"]; // Open a tunnel instead of letting the proxy modify the request (HTTP CONNECT). $proxyconnect = isset($options["proxyconnect"]) && $options["proxyconnect"] ? $options["proxyconnect"] : false; if ($proxyconnect) { $proxydata = "CONNECT " . $host . ":" . $port . " HTTP/1.1\r\n"; if (isset($options["headers"]["User-Agent"])) { $data .= "User-Agent: " . $options["headers"]["User-Agent"] . "\r\n"; } $proxydata .= "Host: " . $host . ($defaultport ? "" : ":" . $port) . "\r\n"; $proxydata .= "Proxy-Connection: keep-alive\r\n"; if ($proxyusername != "") { $proxydata .= "Proxy-Authorization: BASIC " . base64_encode($proxyusername . ":" . $proxypassword) . "\r\n"; } if (isset($options["proxyheaders"])) { $options["proxyheaders"] = HTTPNormalizeHeaders($options["proxyheaders"]); unset($options["proxyheaders"]["Accept-Encoding"]); foreach ($options["proxyheaders"] as $name => $val) { if ($name != "Content-Type" && $name != "Content-Length" && $name != "Proxy-Connection" && $name != "Host") { $proxydata .= $name . ": " . $val . "\r\n"; } } } $proxydata .= "\r\n"; if (isset($options["debug_callback"])) { $options["debug_callback"]("rawproxyheaders", $proxydata, $options["debug_callback_opts"]); } } } // Process the method. if (!isset($options["method"])) { if (isset($options["write_body_callback"]) || isset($options["body"])) { $options["method"] = "PUT"; } else { if (isset($options["postvars"]) || isset($options["files"]) && count($options["files"])) { $options["method"] = "POST"; } else { $options["method"] = "GET"; } } } $options["method"] = preg_replace('/[^A-Z]/', "", strtoupper($options["method"])); // Process the HTTP version. if (!isset($options["httpver"])) { $options["httpver"] = "1.1"; } $options["httpver"] = preg_replace('/[^0-9.]/', "", $options["httpver"]); // Process the request. $data = $options["method"] . " "; $data .= ($useproxy && !$proxyconnect ? $url["scheme"] . "://" . $host . ":" . $port : "") . $path . ($query != "" ? "?" . $query : ""); $data .= " HTTP/" . $options["httpver"] . "\r\n"; // Process the headers. if ($useproxy && !$proxyconnect && $proxyusername != "") { $data .= "Proxy-Authorization: BASIC " . base64_encode($proxyusername . ":" . $proxypassword) . "\r\n"; } if ($username != "") { $data .= "Authorization: BASIC " . base64_encode($username . ":" . $password) . "\r\n"; } $ver = explode(".", $options["httpver"]); if ((int) $ver[0] > 1 || (int) $ver[0] == 1 && (int) $ver[1] >= 1) { if (!isset($options["headers"]["Host"])) { $options["headers"]["Host"] = $host . ($defaultport ? "" : ":" . $port); } $data .= "Host: " . $options["headers"]["Host"] . "\r\n"; } $data .= "Connection: close\r\n"; if (isset($options["headers"])) { foreach ($options["headers"] as $name => $val) { if ($name != "Content-Type" && $name != "Content-Length" && $name != "Connection" && $name != "Host") { $data .= $name . ": " . $val . "\r\n"; } } } // Process the body. $body = ""; $bodysize = 0; if (isset($options["write_body_callback"])) { $options["write_body_callback"]($body, $bodysize, $options["write_body_callback_opts"]); } else { if (isset($options["body"])) { if (isset($options["headers"]["Content-Type"])) { $data .= "Content-Type: " . $options["headers"]["Content-Type"] . "\r\n"; } $body = $options["body"]; $bodysize = strlen($body); unset($options["body"]); } else { if (isset($options["files"]) && count($options["files"])) { $mime = "--------" . substr(sha1(uniqid(mt_rand(), true)), 0, 25); $data .= "Content-Type: multipart/form-data; boundary=" . $mime . "\r\n"; if (isset($options["postvars"])) { foreach ($options["postvars"] as $name => $val) { $name = HTTPHeaderValueCleanup($name); $name = str_replace("\"", "", $name); if (is_string($val) || is_numeric($val)) { $val = array($val); } foreach ($val as $val2) { $body .= "--" . $mime . "\r\n"; $body .= "Content-Disposition: form-data; name=\"" . $name . "\"\r\n"; $body .= "\r\n"; $body .= $val2 . "\r\n"; } } unset($options["postvars"]); } $bodysize = strlen($body); // Only count the amount of data to send. foreach ($options["files"] as $num => $info) { $name = HTTPHeaderValueCleanup($info["name"]); $name = str_replace("\"", "", $name); $filename = HTTPFilenameSafe(HTTPExtractFilename($info["filename"])); $type = HTTPHeaderValueCleanup($info["type"]); $body2 = "--" . $mime . "\r\n"; $body2 .= "Content-Disposition: form-data; name=\"" . $name . "\"; filename=\"" . $filename . "\"\r\n"; $body2 .= "Content-Type: " . $type . "\r\n"; $body2 .= "\r\n"; $info["filesize"] = isset($info["datafile"]) ? filesize($info["datafile"]) : strlen($info["data"]); $bodysize += strlen($body2) + $info["filesize"] + 2; $options["files"][$num] = $info; } $body2 = "--" . $mime . "--\r\n"; $bodysize += strlen($body2); } else { if (isset($options["postvars"])) { foreach ($options["postvars"] as $name => $val) { $name = HTTPHeaderValueCleanup($name); if (is_string($val) || is_numeric($val)) { $val = array($val); } foreach ($val as $val2) { $body .= ($body != "" ? "&" : "") . urlencode($name) . "=" . urlencode($val2); } } unset($options["postvars"]); } if ($body != "") { $data .= "Content-Type: application/x-www-form-urlencoded\r\n"; } $bodysize = strlen($body); } } } if ($bodysize < strlen($body)) { $bodysize = strlen($body); } // Finalize the headers. if ($bodysize || $body != "" || $options["method"] == "POST") { $data .= "Content-Length: " . $bodysize . "\r\n"; } $data .= "\r\n"; if (isset($options["debug_callback"])) { $options["debug_callback"]("rawheaders", $data, $options["debug_callback_opts"]); } // Finalize the initial data to be sent. $data .= $body; $bodysize -= strlen($body); $body = ""; $result = array("success" => true, "rawsendsize" => 0, "rawrecvsize" => 0, "rawrecvheadersize" => 0, "startts" => $startts); $debug = isset($options["debug"]) && $options["debug"]; if ($debug) { $result["rawsend"] = ""; $result["rawrecv"] = ""; } if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } // Connect to the target server. $errornum = 0; $errorstr = ""; if ($useproxy) { if (!isset($options["proxyconnecttimeout"])) { $options["proxyconnecttimeout"] = 10; } $timeleft = HTTPGetTimeLeft($startts, $timeout); if ($timeleft !== false) { $options["proxyconnecttimeout"] = min($options["proxyconnecttimeout"], $timeleft); } if (!function_exists("stream_socket_client")) { $fp = @fsockopen($proxyprotocol . "://" . $proxyhost, $proxyport, $errornum, $errorstr, $options["proxyconnecttimeout"]); } else { $context = @stream_context_create(); if ($proxysecure && isset($options["proxysslopts"]) && is_array($options["proxysslopts"])) { HTTPProcessSSLOptions($options, "proxysslopts", $host); foreach ($options["proxysslopts"] as $key => $val) { @stream_context_set_option($context, "ssl", $key, $val); } } $fp = @stream_socket_client($proxyprotocol . "://" . $host . ":" . $port, $errornum, $errorstr, $options["proxyconnecttimeout"], STREAM_CLIENT_CONNECT, $context); $contextopts = stream_context_get_options($context); if ($proxysecure && isset($options["proxysslopts"]) && is_array($options["proxysslopts"]) && ($protocol == "ssl" || $protocol == "tls") && isset($contextopts["ssl"]["peer_certificate"])) { if (isset($options["debug_callback"])) { $options["debug_callback"]("proxypeercert", @openssl_x509_parse($contextopts["ssl"]["peer_certificate"]), $options["debug_callback_opts"]); } } } if ($fp === false) { return array("success" => false, "error" => HTTPTranslate("Unable to establish a connection to '%s'.", ($proxysecure ? $proxyprotocol . "://" : "") . $proxyhost . ":" . $proxyport), "info" => $errorstr . " (" . $errornum . ")", "errorcode" => "proxy_connect"); } $result["connected"] = microtime(true); if ($proxyconnect) { // Send the HTTP CONNECT request. fwrite($fp, $proxydata); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($proxydata); $result["rawsendproxyheadersize"] = strlen($proxydata); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $proxydata, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $proxydata; } } // Get the response - success is a 2xx code. $options2 = array(); if (isset($options["recvratelimit"])) { $options2["recvratelimit"] = $options["recvratelimit"]; } if (isset($options["debug_callback"])) { $options2["debug_callback"] = $options["debug_callback"]; $options2["debug_callback_opts"] = $options["debug_callback_opts"]; } $info = HTTPGetResponse($fp, $debug, $options2, $startts, $timeout); if (!$info["success"]) { fclose($fp); return $info; } if (substr($info["response"]["code"], 0, 1) != "2") { fclose($fp); return array("success" => false, "error" => HTTPTranslate("Expected a 200 response from the CONNECT request. Received: %s.", $info["response"]["line"]), "info" => $info, "errorcode" => "proxy_connect_tunnel"); } $result["rawrecvsize"] += $info["rawrecvsize"]; $result["rawrecvheadersize"] += $info["rawrecvheadersize"]; if (isset($options["debug_callback"])) { $options["debug_callback"]("rawrecv", $info["rawrecv"], $options["debug_callback_opts"]); } else { if ($debug) { $result["rawrecv"] .= $info["rawrecv"]; } } } } else { if (!isset($options["connecttimeout"])) { $options["connecttimeout"] = 10; } $timeleft = HTTPGetTimeLeft($startts, $timeout); if ($timeleft !== false) { $options["connecttimeout"] = min($options["connecttimeout"], $timeleft); } if (!function_exists("stream_socket_client")) { $fp = @fsockopen($protocol . "://" . $host, $port, $errornum, $errorstr, $options["connecttimeout"]); } else { $context = @stream_context_create(); if ($secure && isset($options["sslopts"]) && is_array($options["sslopts"]) && ($protocol == "ssl" || $protocol == "tls")) { HTTPProcessSSLOptions($options, "sslopts", $host); foreach ($options["sslopts"] as $key => $val) { @stream_context_set_option($context, "ssl", $key, $val); } } $fp = @stream_socket_client($protocol . "://" . $host . ":" . $port, $errornum, $errorstr, $options["connecttimeout"], STREAM_CLIENT_CONNECT, $context); $contextopts = stream_context_get_options($context); if ($secure && isset($options["sslopts"]) && is_array($options["sslopts"]) && ($protocol == "ssl" || $protocol == "tls") && isset($contextopts["ssl"]["peer_certificate"])) { if (isset($options["debug_callback"])) { $options["debug_callback"]("peercert", @openssl_x509_parse($contextopts["ssl"]["peer_certificate"]), $options["debug_callback_opts"]); } } } if ($fp === false) { return array("success" => false, "error" => HTTPTranslate("Unable to establish a connection to '%s'.", ($secure ? $protocol . "://" : "") . $host . ":" . $port), "info" => $errorstr . " (" . $errornum . ")", "errorcode" => "connect_failed"); } $result["connected"] = microtime(true); } // Send the initial data. $result["sendstart"] = microtime(true); fwrite($fp, $data); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($data); $result["rawsendheadersize"] = strlen($data); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $data, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $data; } } // Send extra data. if (isset($options["write_body_callback"])) { while ($bodysize > 0) { $bodysize2 = $bodysize; if (!$options["write_body_callback"]($body, $bodysize2, $options["write_body_callback_opts"]) || strlen($body) > $bodysize) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP write body callback function failed."), "errorcode" => "write_body_callback"); } fwrite($fp, $body); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($body); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $body, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $body; } } $bodysize -= strlen($body); $body = ""; } unset($options["write_body_callback"]); unset($options["write_body_callback_opts"]); } else { if (isset($options["files"]) && count($options["files"])) { foreach ($options["files"] as $info) { $name = HTTPHeaderValueCleanup($info["name"]); $name = str_replace("\"", "", $name); $filename = HTTPFilenameSafe(HTTPExtractFilename($info["filename"])); $type = HTTPHeaderValueCleanup($info["type"]); $body = "--" . $mime . "\r\n"; $body .= "Content-Disposition: form-data; name=\"" . $name . "\"; filename=\"" . $filename . "\"\r\n"; $body .= "Content-Type: " . $type . "\r\n"; $body .= "\r\n"; fwrite($fp, $body); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($body); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $body, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $body; } } if (isset($info["datafile"])) { $fp2 = @fopen($info["datafile"], "rb"); if ($fp2 === false) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("The file '%s' does not exist.", $info["datafile"]), "errorcode" => "file_open"); } // Read/Write 65K at a time. while ($info["filesize"] >= 65536) { $body = fread($fp2, 65536); if ($body === false || strlen($body) != 65536) { fclose($fp2); fclose($fp); return array("success" => false, "error" => HTTPTranslate("A read error was encountered with the file '%s'.", $info["datafile"]), "errorcode" => "file_read"); } fwrite($fp, $body); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($body); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $body, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $body; } } $info["filesize"] -= 65536; } if ($info["filesize"] > 0) { $body = fread($fp2, $info["filesize"]); if ($body === false || strlen($body) != $info["filesize"]) { fclose($fp2); fclose($fp); return array("success" => false, "error" => HTTPTranslate("A read error was encountered with the file '%s'.", $info["datafile"]), "errorcode" => "file_read"); } } else { $body = ""; } fclose($fp2); } else { $body = $info["data"]; } $body .= "\r\n"; fwrite($fp, $body); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($body); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $body, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $body; } } } $body = "--" . $mime . "--\r\n"; fwrite($fp, $body); if ($timeout !== false && HTTPGetTimeLeft($startts, $timeout) == 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("HTTP timeout exceeded."), "errorcode" => "timeout_exceeded"); } $result["rawsendsize"] += strlen($body); if (isset($options["sendratelimit"])) { HTTPRateLimit($result["rawsendsize"], $result["sendstart"], $options["sendratelimit"]); } if (isset($options["debug_callback"])) { $options["debug_callback"]("rawsend", $body, $options["debug_callback_opts"]); } else { if ($debug) { $result["rawsend"] .= $body; } } unset($options["files"]); } else { if ($bodysize > 0) { fclose($fp); return array("success" => false, "error" => HTTPTranslate("A weird internal HTTP error that should never, ever happen...just happened."), "errorcode" => "impossible"); } } } // Get the response. $info = HTTPGetResponse($fp, $debug, $options, $startts, $timeout); fclose($fp); $info["rawsendsize"] = $result["rawsendsize"]; if (!$info["success"]) { return $info; } $result["rawrecvsize"] += $info["rawrecvsize"]; $result["rawrecvheadersize"] += $info["rawrecvheadersize"]; if ($debug) { $result["rawrecv"] .= $info["rawrecv"]; } $result["recvstart"] = $info["recvstart"]; $result["response"] = $info["response"]; $result["headers"] = $info["headers"]; $result["body"] = (string) $info["body"]; $result["endts"] = microtime(true); return $result; }
public function Process($url, $profile = "auto", $tempoptions = array()) { $startts = microtime(true); $redirectts = $startts; if (isset($tempoptions["timeout"])) { $timeout = $tempoptions["timeout"]; } else { if (isset($this->data["httpopts"]["timeout"])) { $timeout = $this->data["httpopts"]["timeout"]; } else { $timeout = false; } } if (!isset($this->data["httpopts"]["headers"])) { $this->data["httpopts"]["headers"] = array(); } $this->data["httpopts"]["headers"] = HTTPNormalizeHeaders($this->data["httpopts"]["headers"]); unset($this->data["httpopts"]["method"]); unset($this->data["httpopts"]["write_body_callback"]); unset($this->data["httpopts"]["body"]); unset($this->data["httpopts"]["postvars"]); unset($this->data["httpopts"]["files"]); $httpopts = $this->data["httpopts"]; $numfollow = $this->data["maxfollow"]; $numredirects = 0; $totalrawsendsize = 0; if (!isset($tempoptions["headers"])) { $tempoptions["headers"] = array(); } $tempoptions["headers"] = HTTPNormalizeHeaders($tempoptions["headers"]); if (isset($tempoptions["headers"]["Referer"])) { $this->data["referer"] = $tempoptions["headers"]["Referer"]; } // If a referrer is specified, use it to generate an absolute URL. if ($this->data["referer"] != "") { $url = ConvertRelativeToAbsoluteURL($this->data["referer"], $url); } $urlinfo = ExtractURL($url); do { if (!isset($this->data["allowedprotocols"][$urlinfo["scheme"]]) || !$this->data["allowedprotocols"][$urlinfo["scheme"]]) { return array("success" => false, "error" => HTTPTranslate("Protocol '%s' is not allowed in '%s'.", $urlinfo["scheme"], $url), "errorcode" => "allowed_protocols"); } $filename = HTTPExtractFilename($urlinfo["path"]); $pos = strrpos($filename, "."); $fileext = $pos !== false ? strtolower(substr($filename, $pos + 1)) : ""; // Set up some standard headers. $headers = array(); $profile = strtolower($profile); $tempprofile = explode("-", $profile); if (count($tempprofile) == 2) { $profile = $tempprofile[0]; $fileext = $tempprofile[1]; } if (substr($profile, 0, 2) == "ie" || $profile == "auto" && substr($this->data["useragent"], 0, 2) == "ie") { if ($fileext == "css") { $headers["Accept"] = "text/css"; } else { if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg") { $headers["Accept"] = "image/png, image/svg+xml, image/*;q=0.8, */*;q=0.5"; } else { if ($fileext == "js") { $headers["Accept"] = "application/javascript, */*;q=0.8"; } else { if ($this->data["referer"] != "" || $fileext == "" || $fileext == "html" || $fileext == "xhtml" || $fileext == "xml") { $headers["Accept"] = "text/html, application/xhtml+xml, */*"; } else { $headers["Accept"] = "*/*"; } } } } $headers["Accept-Language"] = "en-US"; $headers["User-Agent"] = GetWebUserAgent(substr($profile, 0, 2) == "ie" ? $profile : $this->data["useragent"]); } else { if ($profile == "firefox" || $profile == "auto" && $this->data["useragent"] == "firefox") { if ($fileext == "css") { $headers["Accept"] = "text/css,*/*;q=0.1"; } else { if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg") { $headers["Accept"] = "image/png,image/*;q=0.8,*/*;q=0.5"; } else { if ($fileext == "js") { $headers["Accept"] = "*/*"; } else { $headers["Accept"] = "text/html, application/xhtml+xml, */*"; } } } $headers["Accept-Language"] = "en-us,en;q=0.5"; $headers["Cache-Control"] = "max-age=0"; $headers["User-Agent"] = GetWebUserAgent("firefox"); } else { if ($profile == "opera" || $profile == "auto" && $this->data["useragent"] == "opera") { // Opera has the right idea: Just send the same thing regardless of the request type. $headers["Accept"] = "text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/webp, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1"; $headers["Accept-Language"] = "en-US,en;q=0.9"; $headers["Cache-Control"] = "no-cache"; $headers["User-Agent"] = GetWebUserAgent("opera"); } else { if ($profile == "safari" || $profile == "chrome" || $profile == "auto" && ($this->data["useragent"] == "safari" || $this->data["useragent"] == "chrome")) { if ($fileext == "css") { $headers["Accept"] = "text/css,*/*;q=0.1"; } else { if ($fileext == "png" || $fileext == "jpg" || $fileext == "jpeg" || $fileext == "gif" || $fileext == "svg" || $fileext == "js") { $headers["Accept"] = "*/*"; } else { $headers["Accept"] = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"; } } $headers["Accept-Charset"] = "ISO-8859-1,utf-8;q=0.7,*;q=0.3"; $headers["Accept-Language"] = "en-US,en;q=0.8"; $headers["User-Agent"] = GetWebUserAgent($profile == "safari" || $profile == "chrome" ? $profile : $this->data["useragent"]); } } } } if ($this->data["referer"] != "") { $headers["Referer"] = $this->data["referer"]; } // Generate the final headers array. $headers = array_merge($headers, $httpopts["headers"], $tempoptions["headers"]); // Calculate the host and reverse host and remove port information. $host = isset($headers["Host"]) ? $headers["Host"] : $urlinfo["host"]; $pos = strpos($host, "]"); if (substr($host, 0, 1) == "[" && $pos !== false) { $host = substr($host, 0, $pos + 1); } else { $pos = strpos($host, ":"); if ($pos !== false) { $host = substr($host, 0, $pos); } } $dothost = $host; if (substr($dothost, 0, 1) != ".") { $dothost = "." . $dothost; } // Append cookies and delete old, invalid cookies. $secure = $urlinfo["scheme"] == "https"; $cookiepath = $urlinfo["path"]; if ($cookiepath == "") { $cookiepath = "/"; } $pos = strrpos($cookiepath, "/"); if ($pos !== false) { $cookiepath = substr($cookiepath, 0, $pos + 1); } $cookies = array(); foreach ($this->data["cookies"] as $domain => $paths) { if (substr($domain, -strlen($dothost)) == $dothost) { foreach ($paths as $path => $cookies2) { if (substr($cookiepath, 0, strlen($path)) == $path) { foreach ($cookies2 as $num => $info) { if (isset($info["expires_ts"]) && $this->GetExpiresTimestamp($info["expires_ts"]) < time()) { unset($this->data["cookies"][$domain][$path][$num]); } else { if ($secure || !isset($info["secure"])) { $cookies[$info["name"]] = $info["value"]; } } } if (!count($this->data["cookies"][$domain][$path])) { unset($this->data["cookies"][$domain][$path]); } } } if (!count($this->data["cookies"][$domain])) { unset($this->data["cookies"][$domain]); } } } $cookies2 = array(); foreach ($cookies as $name => $value) { $cookies2[] = rawurlencode($name) . "=" . rawurlencode($value); } $headers["Cookie"] = implode("; ", $cookies2); if ($headers["Cookie"] == "") { unset($headers["Cookie"]); } // Generate the final options array. $options = array_merge($httpopts, $tempoptions); $options["headers"] = $headers; if ($timeout !== false) { $options["timeout"] = HTTPGetTimeLeft($startts, $timeout); } // Process the request. $result = RetrieveWebpage($url, $options); $result["url"] = $url; $result["options"] = $options; $result["firstreqts"] = $startts; $result["numredirects"] = $numredirects; $result["redirectts"] = $redirectts; if (isset($result["rawsendsize"])) { $totalrawsendsize += $result["rawsendsize"]; } $result["totalrawsendsize"] = $totalrawsendsize; unset($result["options"]["files"]); unset($result["options"]["body"]); if (!$result["success"]) { return array("success" => false, "error" => HTTPTranslate("Unable to retrieve content. %s", $result["error"]), "info" => $result, "errorcode" => "retrievewebpage"); } // Set up structures for another round. if ($this->data["autoreferer"]) { $this->data["referer"] = $url; } if (isset($result["headers"]["Location"]) && $this->data["followlocation"]) { $redirectts = microtime(true); unset($tempoptions["method"]); unset($tempoptions["write_body_callback"]); unset($tempoptions["body"]); unset($tempoptions["postvars"]); unset($tempoptions["files"]); $tempoptions["headers"]["Referer"] = $url; $url = $result["headers"]["Location"][0]; // Generate an absolute URL. if ($this->data["referer"] != "") { $url = ConvertRelativeToAbsoluteURL($this->data["referer"], $url); } $urlinfo2 = ExtractURL($url); if (!isset($this->data["allowedredirprotocols"][$urlinfo2["scheme"]]) || !$this->data["allowedredirprotocols"][$urlinfo2["scheme"]]) { return array("success" => false, "error" => HTTPTranslate("Protocol '%s' is not allowed. Server attempted to redirect to '%s'.", $urlinfo2["scheme"], $url), "info" => $result, "errorcode" => "allowed_redir_protocols"); } if ($urlinfo2["host"] != $urlinfo["host"]) { unset($tempoptions["headers"]["Host"]); unset($httpopts["headers"]["Host"]); } $urlinfo = $urlinfo2; $numredirects++; } // Handle any 'Set-Cookie' headers. if (isset($result["headers"]["Set-Cookie"])) { foreach ($result["headers"]["Set-Cookie"] as $cookie) { $items = explode("; ", $cookie); $item = trim(array_shift($items)); if ($item != "") { $cookie2 = array(); $pos = strpos($item, "="); if ($pos === false) { $cookie2["name"] = urldecode($item); $cookie2["value"] = ""; } else { $cookie2["name"] = urldecode(substr($item, 0, $pos)); $cookie2["value"] = urldecode(substr($item, $pos + 1)); } $cookie = array(); foreach ($items as $item) { $item = trim($item); if ($item != "") { $pos = strpos($item, "="); if ($pos === false) { $cookie[strtolower(trim(urldecode($item)))] = ""; } else { $cookie[strtolower(trim(urldecode(substr($item, 0, $pos))))] = urldecode(substr($item, $pos + 1)); } } } $cookie = array_merge($cookie, $cookie2); if (isset($cookie["expires"])) { $ts = GetHTTPDateTimestamp($cookie["expires"]); $cookie["expires_ts"] = gmdate("Y-m-d H:i:s", $ts === false ? time() - 24 * 60 * 60 : $ts); } else { if (isset($cookie["max-age"])) { $cookie["expires_ts"] = gmdate("Y-m-d H:i:s", time() + (int) $cookie["max-age"]); } else { unset($cookie["expires_ts"]); } } if (!isset($cookie["domain"])) { $cookie["domain"] = $dothost; } if (substr($cookie["domain"], 0, 1) != ".") { $cookie["domain"] = "." . $cookie["domain"]; } if (!isset($cookie["path"])) { $cookie["path"] = $cookiepath; } $cookie["path"] = str_replace("\\", "/", $cookie["path"]); if (substr($cookie["path"], -1) != "/") { $cookie["path"] = "/"; } if (!isset($this->data["cookies"][$cookie["domain"]])) { $this->data["cookies"][$cookie["domain"]] = array(); } if (!isset($this->data["cookies"][$cookie["domain"]][$cookie["path"]])) { $this->data["cookies"][$cookie["domain"]][$cookie["path"]] = array(); } $this->data["cookies"][$cookie["domain"]][$cookie["path"]][] = $cookie; } } } if ($numfollow > 0) { $numfollow--; } } while (isset($result["headers"]["Location"]) && $this->data["followlocation"] && $numfollow); $result["numredirects"] = $numredirects; $result["redirectts"] = $redirectts; // Extract the forms from the page in a parsed format. // Call WebBrowser::GenerateFormRequest() to prepare an actual request for Process(). if ($this->data["extractforms"]) { $result["forms"] = $this->ExtractForms($result["url"], $result["body"]); } return $result; }
function curl_exec($ch) { global $curl_init__map; $key = get_check_curl_init_key($ch); // Set allowed protocols. $allowedprotocols = array("http" => true, "https" => true); if (isset($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS])) { $allowedprotocols["http"] = (bool) ($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS] & CURLPROTO_HTTP); $allowedprotocols["https"] = (bool) ($curl_init__map[$key]["options"][CURLOPT_PROTOCOLS] & CURLPROTO_HTTPS); } $curl_init__map[$key]["browser"]->SetState(array("allowedprotocols" => $allowedprotocols)); // Set allowed redirect protocols. $allowedprotocols = array("http" => true, "https" => true); if (isset($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS])) { $allowedprotocols["http"] = (bool) ($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS] & CURLPROTO_HTTP); $allowedprotocols["https"] = (bool) ($curl_init__map[$key]["options"][CURLOPT_REDIR_PROTOCOLS] & CURLPROTO_HTTPS); } $curl_init__map[$key]["browser"]->SetState(array("allowedredirprotocols" => $allowedprotocols)); // Load cookies. Violates the PHP/cURL definition a lot. Whatever. if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) && is_string($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) && $curl_init__map[$key]["options"][CURLOPT_COOKIEFILE] != "") { $data = @unserialize(@file_get_contents($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE])); if ($data !== false && is_array($data)) { // Load the WebBrowser() object with the cookies. $curl_init__map[$key]["browser"]->SetState(array("cookies" => $data)); } $curl_init__map[$key]["options"][CURLOPT_COOKIEFILE] = ""; } if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIESESSION]) && $curl_init__map[$key]["options"][CURLOPT_COOKIESESSION]) { $curl_init__map[$key]["browser"]->DeleteSessionCookies(); } // Set the autoreferer setting. $curl_init__map[$key]["browser"]->SetState(array("autoreferer" => isset($curl_init__map[$key]["options"][CURLOPT_AUTOREFERER]) && $curl_init__map[$key]["options"][CURLOPT_AUTOREFERER])); // Set the Referer. if (isset($curl_init__map[$key]["options"][CURLOPT_REFERER]) && is_string($curl_init__map[$key]["options"][CURLOPT_REFERER])) { $curl_init__map[$key]["browser"]->SetState(array("referer" => $curl_init__map[$key]["options"][CURLOPT_REFERER])); } // Set the followlocation and maxfollow settings. $curl_init__map[$key]["browser"]->SetState(array("followlocation" => isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) && $curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION])); $curl_init__map[$key]["browser"]->SetState(array("maxfollow" => isset($curl_init__map[$key]["options"][CURLOPT_MAXREDIRS]) ? $curl_init__map[$key]["options"][CURLOPT_MAXREDIRS] : 20)); // Set up the options array. $options = array(); // Set connect and total timeout options. if (isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT]) || isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS])) { $timeout = (isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT]) ? $curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT] : 0) + (isset($curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS]) ? $curl_init__map[$key]["options"][CURLOPT_CONNECTTIMEOUT_MS] : 0) / 1000; if ($timeout > 0) { $options["connecttimeout"] = $timeout; $options["proxyconnecttimeout"] = $timeout; } } if (isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT]) || isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS])) { $timeout = (isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT]) ? $curl_init__map[$key]["options"][CURLOPT_TIMEOUT] : 0) + (isset($curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS]) ? $curl_init__map[$key]["options"][CURLOPT_TIMEOUT_MS] : 0) / 1000; if ($timeout > 0) { $options["connecttimeout"] = $timeout; $options["proxyconnecttimeout"] = $timeout; } } // Set proxy options. if (isset($curl_init__map[$key]["options"][CURLOPT_PROXY])) { if (isset($curl_init__map[$key]["options"][CURLOPT_PROXYTYPE]) && $curl_init__map[$key]["options"][CURLOPT_PROXYTYPE] != CURLPROXY_HTTP) { $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_PROXYTYPE option is unsupported."); return false; } $proxyurl = $curl_init__map[$key]["options"][CURLOPT_PROXY]; $proxyport = (int) (isset($curl_init__map[$key]["options"][CURLOPT_PROXYPORT]) ? $curl_init__map[$key]["options"][CURLOPT_PROXYPORT] : false); if ($proxyport < 1 || $proxyport > 65535) { $proxyport = false; } if (strpos($proxyurl, "://") === false) { $proxyurl = ($proxyport == 443 ? "https://" : "http://") . $proxyurl; } $proxyurl = ExtractURL($proxyurl); if ($proxyport !== false) { $proxyurl["port"] = $proxyport; } if (isset($curl_init__map[$key]["options"][CURLOPT_PROXYUSERPWD])) { $userpass = explode(":", $curl_init__map[$key]["options"][CURLOPT_PROXYUSERPWD]); if (count($userpass) == 2) { $proxyurl["loginusername"] = urldecode($userpass[0]); $proxyurl["loginpassword"] = urldecode($userpass[1]); } } $options["proxyurl"] = CondenseURL($proxyurl); if (isset($curl_init__map[$key]["options"][CURLOPT_HTTPPROXYTUNNEL])) { $options["proxyconnect"] = $curl_init__map[$key]["options"][CURLOPT_HTTPPROXYTUNNEL]; } } // Set SSL options. $options["sslopts"] = array(); $options["sslopts"]["verify_peer"] = isset($curl_init__map[$key]["options"][CURLOPT_SSL_VERIFYPEER]) ? $curl_init__map[$key]["options"][CURLOPT_SSL_VERIFYPEER] : true; if (isset($curl_init__map[$key]["options"][CURLOPT_CAINFO])) { $options["sslopts"]["cafile"] = $curl_init__map[$key]["options"][CURLOPT_CAINFO]; } if (isset($curl_init__map[$key]["options"][CURLOPT_CAPATH])) { $options["sslopts"]["capath"] = $curl_init__map[$key]["options"][CURLOPT_CAPATH]; } if (!isset($options["sslopts"]["cafile"]) && !isset($options["sslopts"]["capath"])) { $options["sslopts"]["auto_cainfo"] = true; } if (isset($curl_init__map[$key]["options"][CURLOPT_SSLCERT]) && isset($curl_init__map[$key]["options"][CURLOPT_SSLKEY])) { if ($curl_init__map[$key]["options"][CURLOPT_SSLCERT] !== $curl_init__map[$key]["options"][CURLOPT_SSLKEY]) { $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_SSLCERT and CURLOPT_SSLKEY must be identical."); return false; } $certpass = isset($curl_init__map[$key]["options"][CURLOPT_SSLCERTPASSWD]) ? $curl_init__map[$key]["options"][CURLOPT_SSLCERTPASSWD] : false; $keypass = isset($curl_init__map[$key]["options"][CURLOPT_SSLKEYPASSWD]) ? $curl_init__map[$key]["options"][CURLOPT_SSLKEYPASSWD] : false; if ($certpass !== $keypass) { $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_SSLCERTPASSWD and CURLOPT_SSLKEYPASSWD must be identical."); return false; } $certtype = strtoupper(isset($curl_init__map[$key]["options"][CURLOPT_SSLCERTTYPE]) ? $curl_init__map[$key]["options"][CURLOPT_SSLCERTTYPE] : "PEM"); $keytype = strtoupper(isset($curl_init__map[$key]["options"][CURLOPT_SSLKEYTYPE]) ? $curl_init__map[$key]["options"][CURLOPT_SSLKEYTYPE] : "PEM"); if ($certpass !== $keypass || $cert !== "PEM") { $curl_init__map[$key]["errorno"] = CURLE_SSL_CONNECT_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_SSLCERTTYPE and CURLOPT_SSLKEYTYPE must be PEM format."); return false; } $options["sslopts"]["local_cert"] = $curl_init__map[$key]["options"][CURLOPT_SSLCERT]; if ($certpass !== false) { $options["sslopts"]["passphrase"] = $certpass; } } if (isset($curl_init__map[$key]["options"][CURLOPT_SSL_CIPHER_LIST])) { $options["sslopts"]["ciphers"] = $curl_init__map[$key]["options"][CURLOPT_SSL_CIPHER_LIST]; } $options["sslopts"]["auto_cn_match"] = true; $options["sslopts"]["auto_sni"] = true; $options["sslopts"]["capture_peer_cert"] = isset($curl_init__map[$key]["options"][CURLOPT_CERTINFO]) ? $curl_init__map[$key]["options"][CURLOPT_CERTINFO] : false; // Set the method. if (isset($curl_init__map[$key]["options"][CURLOPT_UPLOAD]) && (bool) $curl_init__map[$key]["options"][CURLOPT_UPLOAD]) { $options["method"] = "PUT"; } else { $options["method"] = $curl_init__map[$key]["method"]; } // Set the HTTP version. if (isset($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION])) { if ($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION] == CURL_HTTP_VERSION_1_0) { $options["httpver"] = "1.0"; } else { if ($curl_init__map[$key]["options"][CURLOPT_HTTP_VERSION] == CURL_HTTP_VERSION_1_1) { $options["httpver"] = "1.1"; } } } // Set rate limits. if (isset($curl_init__map[$key]["options"][CURLOPT_MAX_RECV_SPEED_LARGE])) { $options["recvratelimit"] = $curl_init__map[$key]["options"][CURLOPT_MAX_RECV_SPEED_LARGE]; } if (isset($curl_init__map[$key]["options"][CURLOPT_MAX_SEND_SPEED_LARGE])) { $options["sendratelimit"] = $curl_init__map[$key]["options"][CURLOPT_MAX_SEND_SPEED_LARGE]; } // Set headers. $options["headers"] = array(); $options["headers"]["Accept"] = "*/*"; if (isset($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER]) && is_array($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER])) { foreach ($curl_init__map[$key]["options"][CURLOPT_HTTPHEADER] as $header) { $pos = strpos($header, ":"); if ($pos !== false) { $val = ltrim(substr($header, $pos + 1)); if ($val == "") { unset($options["headers"][HTTPHeaderNameCleanup(substr($header, 0, $pos))]); } else { $options["headers"][HTTPHeaderNameCleanup(substr($header, 0, $pos))] = $val; } } } } if (isset($curl_init__map[$key]["options"][CURLOPT_USERAGENT])) { $options["headers"]["User-Agent"] = $curl_init__map[$key]["options"][CURLOPT_USERAGENT]; } if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIE])) { $options["headers"]["Cookie"] = $curl_init__map[$key]["options"][CURLOPT_COOKIE]; } if (isset($curl_init__map[$key]["options"][CURLOPT_RANGE])) { $options["headers"]["Range"] = "bytes=" . $curl_init__map[$key]["options"][CURLOPT_RANGE]; } if (isset($curl_init__map[$key]["options"][CURLOPT_RESUME_FROM])) { $options["headers"]["Range"] = "bytes=" . $curl_init__map[$key]["options"][CURLOPT_RESUME_FROM] . "-"; } if (isset($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION]) && isset($curl_init__map[$key]["options"][CURLOPT_TIMEVALUE])) { if ($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION] == CURL_TIMECOND_IFMODSINCE) { $options["headers"]["If-Modified-Since"] = gmdate("D, d M Y H:i:s", $curl_init__map[$key]["options"][CURLOPT_TIMEVALUE]) . " GMT"; } else { if ($curl_init__map[$key]["options"][CURLOPT_TIMECONDITION] == CURL_TIMECOND_IFUNMODSINCE) { $options["headers"]["If-Unmodified-Since"] = gmdate("D, d M Y H:i:s", $curl_init__map[$key]["options"][CURLOPT_TIMEVALUE]) . " GMT"; } } } // Set POST variables and files. if (isset($curl_init__map[$key]["options"][CURLOPT_POSTFIELDS])) { $postvars = $curl_init__map[$key]["options"][CURLOPT_POSTFIELDS]; if (is_string($postvars)) { $postvars2 = array(); $postvars = explode("&", $postvars); foreach ($postvars as $postvar) { $pos = strpos($postvar, "="); if ($pos === false) { $name = urldecode($postvar); $val = ""; } else { $name = urldecode(substr($postvar, 0, $pos)); $val = urldecode(substr($postvar, $pos + 1)); } if (!isset($postvars2[$name])) { $postvars2[$name] = array(); } $postvars2[$name][] = $val; } $postvars = $postvars2; unset($postvars2); } foreach ($postvars as $name => $vals) { if (is_string($vals) || is_numeric($vals)) { $vals = array($vals); } foreach ($vals as $num => $val) { // Move files to their own array. if (substr($val, 0, 1) == "@") { $pos = strrpos($val, ";type="); if ($pos === false) { $mimetype = ""; } else { $mimetype = substr($val, $pos + 6); $val = substr($val, 0, $pos); } $val = substr($val, 1); if (file_exists($val)) { if (!isset($options["files"])) { $options["files"] = array(); } $options["files"][] = array("name" => $name, "filename" => HTTPFilenameSafe(HTTPExtractFilename($val)), "type" => $mimetype, "datafile" => $val); unset($vals[$num]); } } } if (!count($vals)) { unset($postvars[$name]); } else { $postvars[$name] = $vals; } } $options["postvars"] = $postvars; $options["method"] = "POST"; } // Process the URL. if (!isset($curl_init__map[$key]["options"][CURLOPT_URL]) || !is_string($curl_init__map[$key]["options"][CURLOPT_URL]) || $curl_init__map[$key]["options"][CURLOPT_URL] == "") { $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("No CURLOPT_URL option specified."); return false; } $url = ExtractURL($curl_init__map[$key]["options"][CURLOPT_URL]); if ($url["scheme"] == "") { $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_URL does not have a scheme."); return false; } if ($url["host"] == "") { $curl_init__map[$key]["errorno"] = CURLE_URL_MALFORMAT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("CURLOPT_URL does not specify a valid host."); return false; } if (isset($curl_init__map[$key]["options"][CURLOPT_PORT]) && (int) $curl_init__map[$key]["options"][CURLOPT_PORT] > 0 && (int) $curl_init__map[$key]["options"][CURLOPT_PORT] < 65536) { $url["port"] = (int) $curl_init__map[$key]["options"][CURLOPT_PORT]; } if (isset($curl_init__map[$key]["options"][CURLOPT_USERPWD])) { $userpass = explode(":", $curl_init__map[$key]["options"][CURLOPT_USERPWD]); if (count($userpass) == 2) { $url["loginusername"] = urldecode($userpass[0]); $url["loginpassword"] = urldecode($userpass[1]); } } else { if (isset($curl_init__map[$key]["options"][CURLOPT_NETRC]) && $curl_init__map[$key]["options"][CURLOPT_NETRC]) { $data = @file_get_contents("~/.netrc"); if ($data !== false) { $lines = explode("\n", $data); unset($data); $host = false; $user = false; $password = false; foreach ($lines as $line) { $line = trim($line); if (substr($line, 0, 8) == "machine ") { $host = trim(substr($line, 8)); } if (substr($line, 0, 6) == "login ") { $user = trim(substr($line, 6)); } if (substr($line, 0, 9) == "password ") { $password = trim(substr($line, 9)); } if ($host !== false && $user !== false && $password !== false) { if ($host === $url["host"] || isset($options["headers"]["Host"]) && $host === $options["headers"]["Host"]) { $url["loginusername"] = $user; $url["loginpassword"] = $password; } $host = false; $user = false; $password = false; } } unset($lines); } } } // Condense URL. $url = CondenseURL($url); // Set up internal callbacks. $options["read_headers_callback"] = "internal_curl_read_headers_callback"; $options["read_headers_callback_opts"] = $key; if (!isset($curl_init__map[$key]["options"][CURLOPT_NOBODY]) || !$curl_init__map[$key]["options"][CURLOPT_NOBODY]) { $options["read_body_callback"] = "internal_curl_read_body_callback"; $options["read_body_callback_opts"] = $key; } if ($options["method"] != "GET" && $options["method"] != "POST") { $options["write_body_callback"] = "internal_curl_write_body_callback"; $options["write_body_callback_opts"] = $key; } $options["debug_callback"] = "internal_curl_debug_callback"; $options["debug_callback_opts"] = $key; // Remove weird callback results. unset($curl_init__map[$key]["rawproxyheaders"]); unset($curl_init__map[$key]["rawheaders"]); unset($curl_init__map[$key]["returnresponse"]); unset($curl_init__map[$key]["returnheader"]); unset($curl_init__map[$key]["returnbody"]); unset($curl_init__map[$key]["filetime"]); $curl_init__map[$key]["outputbody"] = false; // Process the request. $result = $curl_init__map[$key]["browser"]->Process($url, "", $options); $curl_init__map[$key]["lastresult"] = $result; // Deal with cookies. if (!isset($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE]) || !is_string($curl_init__map[$key]["options"][CURLOPT_COOKIEFILE])) { // Delete all cookies for another run later. $curl_init__map[$key]["browser"]->SetState(array("cookies" => array())); } else { if (isset($curl_init__map[$key]["options"][CURLOPT_COOKIEJAR])) { // Write out cookies here. Another violation of how cURL does things. Another - whatever. $state = $curl_init__map[$key]["browser"]->GetState(); file_put_contents($curl_init__map[$key]["options"][CURLOPT_COOKIEJAR], serialize($state["cookies"])); } } // Process the response. if (!$result["success"]) { if ($result["errorcode"] == "allowed_protocols") { $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The cURL emulation layer does not support the protocol or was redirected to an unsupported protocol by the host. %s", $result["error"]); } else { if ($result["errorcode"] == "allowed_redir_protocols") { $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The cURL emulation layer was redirected to an unsupported protocol by the host. %s", $result["error"]); } else { if ($result["errorcode"] == "retrievewebpage") { if ($result["info"]["errorcode"] == "timeout_exceeded") { $curl_init__map[$key]["errorno"] = CURLE_OPERATION_TIMEDOUT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The operation timed out. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "get_response_line") { $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Unable to get the response line. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "read_header_callback") { $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A read error occurred in the read header callback. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "read_body_callback") { $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A read error occurred in the read body callback. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "function_check") { $curl_init__map[$key]["errorno"] = CURLE_FUNCTION_NOT_FOUND; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A required function was not found. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "protocol_check") { $curl_init__map[$key]["errorno"] = CURLE_UNSUPPORTED_PROTOCOL; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The cURL emulation layer does not support the protocol or was redirected to an unsupported protocol by the host. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "transport_not_installed") { $curl_init__map[$key]["errorno"] = CURLE_NOT_BUILT_IN; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The cURL emulation layer attempted to use a required transport to connect to a host but failed. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "proxy_transport_not_installed") { $curl_init__map[$key]["errorno"] = CURLE_NOT_BUILT_IN; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("The cURL emulation layer attempted to use a required transport to connect to a proxy but failed. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "proxy_connect") { $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Unable to connect to the proxy. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "proxy_connect_tunnel") { $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Unable to open a tunnel through the connected proxy. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "connect_failed") { $curl_init__map[$key]["errorno"] = CURLE_COULDNT_CONNECT; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Unable to connect to the host. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "write_body_callback") { $curl_init__map[$key]["errorno"] = CURLE_WRITE_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A write error occurred in the write body callback. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "file_open") { $curl_init__map[$key]["errorno"] = CURLE_FILE_COULDNT_READ_FILE; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Unable to open file for upload. %s", $result["error"]); } else { if ($result["info"]["errorcode"] == "file_read") { $curl_init__map[$key]["errorno"] = CURLE_READ_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A read error occurred while uploading a file. %s", $result["error"]); } else { $curl_init__map[$key]["errorno"] = CURLE_HTTP_RETURNED_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("An error occurred. %s", $result["error"]); } } } } } } } } } } } } } } } } } return false; } if (isset($curl_init__map[$key]["returnresponse"]) && $curl_init__map[$key]["returnresponse"]["code"] >= 400 && isset($curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) && $curl_init__map[$key]["options"][CURLOPT_FAILONERROR]) { $curl_init__map[$key]["errorno"] = CURLE_HTTP_RETURNED_ERROR; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("A HTTP error occurred. %s", $curl_init__map[$key]["returnresponse"]["line"]); return false; } if (isset($curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION]) && $curl_init__map[$key]["options"][CURLOPT_FOLLOWLOCATION] && isset($result["headers"]["Location"])) { $curl_init__map[$key]["errorno"] = CURLE_TOO_MANY_REDIRECTS; $curl_init__map[$key]["errorinfo"] = HTTPTranslate("Too many redirects took place."); return false; } if (isset($curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) && $curl_init__map[$key]["options"][CURLOPT_RETURNTRANSFER]) { return (isset($curl_init__map[$key]["returnheader"]) ? $curl_init__map[$key]["returnheader"] . "\r\n" : "") . (isset($curl_init__map[$key]["returnbody"]) ? $curl_init__map[$key]["returnbody"] : ""); } return true; }