/** * @param $url: url of the requested resource * * @param $http_opts: Options for the HTTP request, keys: * - method: request method (GET, PROPFIND, etc.) * - content: request body * - header: array of HTTP request headers as simple strings * * @param $carddav: config array containing at least the keys * - url: base url, used if $url is a relative url * - username * - password: password (encoded/encrypted form as stored in DB) */ public function cdfopen($url, $http_opts, $carddav) { $redirect_limit = 5; $rcmail = rcmail::get_instance(); $username = $carddav['username']; $password = self::decrypt_password($carddav['password']); $baseurl = $carddav['url']; // determine calling function for debug output $caller = self::getCaller(); $local = $rcmail->user->get_username('local'); $domain = $rcmail->user->get_username('domain'); // Substitute Placeholders if ($username == '%u') { $username = $_SESSION['username']; } if ($username == '%l') { $username = $local; } if ($password == '%p') { $password = $rcmail->decrypt($_SESSION['password']); } $baseurl = str_replace("%u", $username, $carddav['url']); $url = str_replace("%u", $username, $url); $baseurl = str_replace("%l", $local, $baseurl); $url = str_replace("%l", $local, $url); $baseurl = str_replace("%d", $domain, $baseurl); $url = str_replace("%d", $domain, $url); // if $url is relative, prepend the base url $url = self::concaturl($baseurl, $url); do { $isRedirect = false; if (self::DEBUG) { $this->debug("{$caller} requesting {$url} [RL {$redirect_limit}]"); } $httpful = \Httpful\Request::init(); $scheme = strtolower($carddav['authentication_scheme']); if ($scheme != "basic" && $scheme != "digest") { /* figure out authentication */ $httpful->addHeader("User-Agent", "RCM CardDAV plugin/1.0.0"); $httpful->uri($url); $httpful->method($http_opts['method']); $error = $httpful->send(); $httpful = \Httpful\Request::init(); $scheme = "unknown"; if (preg_match("/\\bDigest\\b/i", $error->headers["www-authenticate"])) { $httpful->digestAuth($username, $password); $scheme = "digest"; } else { if (preg_match("/\\bBasic\\b/i", $error->headers["www-authenticate"])) { $httpful->basicAuth($username, $password); $scheme = "basic"; } } if ($scheme != "unknown") { carddav_backend::update_addressbook($carddav['abookid'], array("authentication_scheme"), array($scheme)); } } else { if (strtolower($scheme) == "digest") { $httpful->digestAuth($username, $password); } else { if (strtolower($scheme) == "basic") { $httpful->basicAuth($username, $password); } } } $httpful->addHeader("User-Agent", "RCM CardDAV plugin/1.0.0"); $httpful->uri($url); $httpful->method($http_opts['method']); if (array_key_exists('content', $http_opts) && strlen($http_opts['content']) > 0 && $http_opts['method'] != "GET") { $httpful->body($http_opts['content']); } if (array_key_exists('header', $http_opts)) { foreach ($http_opts['header'] as $header) { $h = explode(": ", $header); if (strlen($h[0]) > 0 && strlen($h[1]) > 0) { // Only append headers with key AND value $httpful->addHeader($h[0], $h[1]); } } } $reply = $httpful->send(); $scode = $reply->code; if (self::DEBUG) { $this->debug("Code: {$scode}"); } $isRedirect = $scode > 300 && $scode < 304 || $scode == 307; if ($isRedirect && strlen($reply->headers['location']) > 0) { $url = self::concaturl($baseurl, $reply->headers['location']); } else { $retVal["status"] = $scode; $retVal["headers"] = $reply->headers; $retVal["body"] = $reply->raw_body; if (self::DEBUG_HTTP) { $this->debug_http("success: " . var_export($retVal, true)); } return $retVal; } } while ($redirect_limit-- > 0 && $isRedirect); return $reply->code; }