php carddav客户端未经授权

时间:2021-01-05 12:52:49

标签: php

我想使用 php 连接到我自己的 cardDAV 服务器。 这就是我现在所拥有的:

<?php

$carddav = new carddav_backend('https://localhost/contacts/carddav/SynoContacts/');
$carddav->set_auth('myUsername', 'myPassword');

 // CardDAV add query
$vcard = 'BEGIN:VCARD
VERSION:3.0
UID:1f5ea45f-b28a-4b96-25as-ed4f10edf57b
FN:Max Mustermann
N:Max;Mustermann;;;
EMAIL;TYPE=OTHER:max.mustermann@mail.de
END:VCARD';
    
echo '<pre>';
var_dump($carddav->add($vcard));
echo '</pre>';

// CARDDAV
class carddav_backend {
    
    const VERSION = '0.6';
    const USERAGENT = 'CardDAV PHP/';
    private $url = null;
    private $auth = null;
    private $username = null;
    private $password = null;
    private $vcard_id_chars = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f');
    const EXCEPTION_WRONG_HTTP_STATUS_CODE_ADD          = 1004;
    const EXCEPTION_MALFORMED_XML_RESPONSE              = 1006;
    const EXCEPTION_COULD_NOT_GENERATE_NEW_VCARD_ID     = 1007;
        
    
    
    // Gets a clean vCard from the CardDAV server
    public function get_vcard($vcard_id) {
        $result = $this->query($this->url . $vcard_id . '.vcf', 'GET');

        switch ($result['http_code']) {
            case 200:
            case 207:
                return $result['response'];
            break;

            default:
                throw new Exception('Error ' . $result['http_code'] . '.', self::EXCEPTION_WRONG_HTTP_STATUS_CODE_GET_VCARD);
            break;
        }
    }
    

    
    // Sets the CardDAV server url
    public function __construct($url = null) {
        $this->url = $url;
    }
    
    
    // Sets authentication information
    public function set_auth($username, $password) {
        $this->username = $username;
        $this->password = $password;
        $this->auth     = $username . ':' . $password;
    }
    
        
    // Checks if the CardDAV server is reachable
    public function check_connection() {
        $result = $this->query($this->url, 'OPTIONS');
    
        if ($result['http_code'] === 200) {
            return true;
        } else {
            return false;
        }
    }
    

        
    // Add Contact
    public function add($vcard) {
        $vcard_id   = $this->generate_vcard_id();
        $result     = $this->query($this->url . $vcard_id . '.vcf', 'PUT', $vcard, 'text/vcard');
        return $result;
    }
        
    
        
    // Returns a valid and unused vCard id
    private function generate_vcard_id() {
        $vcard_id = null;
            
        for ($number = 0; $number <= 35; $number ++) {
            if ($number == 8 || $number == 13 || $number == 18 || $number == 23) {
                $vcard_id .= '-';
            } else {
                $vcard_id .= $this->vcard_id_chars[mt_rand(0, (count($this->vcard_id_chars) - 1))];
            }
        }
            
        try {
            $carddav = new carddav_backend($this->url);
            $carddav->set_auth($this->username, $this->password);
            $result = $carddav->query($this->url . $vcard_id . '.vcf', 'GET');
    
                
            if ($result['http_code'] !== 404) {
                $vcard_id = $this->generate_vcard_id();
            }
    
            return $vcard_id;
        }
        catch (Exception $e) {
            throw new Exception($e->getMessage(), self::EXCEPTION_COULD_NOT_GENERATE_NEW_VCARD_ID);
        }
    }
    
        

    // Curl initialization
    public function curl_init() {
        if (empty($this->curl)) {
            $this->curl = curl_init();
            curl_setopt($this->curl, CURLOPT_HEADER, true);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYHOST, false);
            curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($this->curl, CURLOPT_USERAGENT, self::USERAGENT.self::VERSION);
    
            if ($this->auth !== null) {
                curl_setopt($this->curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
                curl_setopt($this->curl, CURLOPT_USERPWD, $this->auth);
            }
        }
    }
    
    // Query the CardDAV server via curl and returns the response
    private function query($url, $method, $content = null, $content_type = null) {
        $this->curl_init();
    
        curl_setopt($this->curl, CURLOPT_URL, $url);
        curl_setopt($this->curl, CURLOPT_CUSTOMREQUEST, $method);
    
        if ($content !== null) {
            curl_setopt($this->curl, CURLOPT_POST, true);
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, $content);
        } else {
            curl_setopt($this->curl, CURLOPT_POST, false);
            curl_setopt($this->curl, CURLOPT_POSTFIELDS, null);
        }
    
        if ($content_type !== null) {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, array('Content-type: '.$content_type));
        } else {
            curl_setopt($this->curl, CURLOPT_HTTPHEADER, array());
        }
    
        $complete_response  = curl_exec($this->curl);
        $header_size        = curl_getinfo($this->curl, CURLINFO_HEADER_SIZE);
        $http_code          = curl_getinfo($this->curl, CURLINFO_HTTP_CODE);
        $header             = trim(substr($complete_response, 0, $header_size));
        
    
        $return = array(
            'response'  => $complete_response,
            'http_code' => $http_code
        );
    
        return $return;
    }
    
        
    
    // Close curl connection if it's open
    public function __destruct() {
        if (!empty($this->curl)) {
            curl_close($this->curl);
        }
    }
    
}
?>

结果: 连接应该没问题,因为php代码成功创建了一个新的联系人“Max Mustermann”。

但是输出 var_dump($carddav->add($vcard)); 显示了这一点:

array(2) {
  ["response"]=>
  string(412) "HTTP/1.1 401 Unauthorized
Server: nginx
Date: Tue, 05 Jan 2021 12:49:06 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 43
Connection: keep-alive
Keep-Alive: timeout=20
WWW-Authenticate: Basic realm="Radicale - Password Required"

HTTP/1.1 201 Created
Server: nginx
Date: Tue, 05 Jan 2021 12:49:07 GMT
Content-Length: 0
Connection: keep-alive
Keep-Alive: timeout=20
ETag: "43_1144"

"
  ["http_code"]=>
  int(201)
}

为什么我得到 HTTP/1.1 401 Unauthorized

0 个答案:

没有答案