File: caldav.php

package info (click to toggle)
davical 1.1.12-2.3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,020 kB
  • sloc: php: 19,361; sql: 4,514; perl: 3,524; sh: 554; javascript: 162; makefile: 85
file content (158 lines) | stat: -rw-r--r-- 6,119 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
<?php
/**
* CalDAV Server - main program
*
* @package   davical
* @subpackage   caldav
* @author    Andrew McMillan <andrew@mcmillan.net.nz>
* @copyright Catalyst .Net Ltd, Morphoss Ltd <http://www.morphoss.com/>
* @license   http://gnu.org/copyleft/gpl.html GNU GPL v2 or later
*/

require_once('./always.php');

if ( isset($_SERVER['PATH_INFO']) && preg_match( '{^/\.well-known/(.+)$}', $_SERVER['PATH_INFO'], $matches ) ) {
  require ('well-known.php');
  @ob_flush(); exit(0);
}
elseif ( isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] == '/autodiscover/autodiscover.xml' ) {
  require ('autodiscover-handler.php');
  @ob_flush(); exit(0);
}

function logRequestHeaders() {
  global $c;

  /** Log the request headers */
  $lines = apache_request_headers();
  dbg_error_log( "LOG ", "***************** Request Header ****************" );
  dbg_error_log( "LOG ", "%s %s", $_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI'] );
  foreach( $lines AS $k => $v ) {
    if ( $k != 'Authorization' || (isset($c->dbg['password']) && $c->dbg['password'] ) )
      dbg_error_log( "LOG headers", "-->%s: %s", $k, $v );
    else
      dbg_error_log( "LOG headers", "-->%s: %s", $k, 'Delicious tasty password eaten by debugging monster!' );
  }
  dbg_error_log( "LOG ", "******************** Request ********************" );

  // Log the request in all it's gory detail.
  $lines = preg_split( '#[\r\n]+#', $c->raw_post );
  foreach( $lines AS $v ) {
    dbg_error_log( "LOG request", "-->%s", $v );
  }
  unset($lines);
}

if ( !isset($c->raw_post) ) $c->raw_post = file_get_contents( 'php://input');
if ( (isset($c->dbg['ALL']) && $c->dbg['ALL']) || (isset($c->dbg['request']) && $c->dbg['request']) )
  logRequestHeaders();


require_once('HTTPAuthSession.php');
$session = new HTTPAuthSession();

function send_dav_header() {
  global $c;

  /**
  * access-control is rfc3744, we do most of it, but no way to say that.
  * calendar-schedule is another one we do most of, but the spec is not final yet either.
  */
  if ( isset($c->override_dav_header) ) {
    $dav = $c->override_dav_header;
  }
  else {
    $dav = '1, 2, 3, access-control, calendar-access, calendar-schedule, extended-mkcol, bind, addressbook';
    if ( $c->enable_auto_schedule ) $dav .= ', calendar-auto-schedule';
    if ( !isset($c->disable_caldav_proxy) || $c->disable_caldav_proxy == false) $dav .= ', calendar-proxy';
  }
  $dav = explode( "\n", wordwrap( $dav ) );
  foreach( $dav AS $v ) {
    header( 'DAV: '.trim($v, ', '), false);
  }
}

require_once('CalDAVRequest.php');
$request = new CalDAVRequest();

function late_catch_fatal_error() {
  global $request;

  // Getting Last Error
  $e =  error_get_last();
  if (isset($e['type']) && $e['type'] == E_ERROR) {
    $request->DoResponse(500, "Fatal PHP Error");
  }
}
register_shutdown_function('late_catch_fatal_error');

//if ( $request->method == 'OPTIONS' || $c->always_send_dav_header )
    send_dav_header();  // Avoid polluting global namespace

if ( ! ($request->IsPrincipal() || isset($request->collection) || $request->method == 'PUT' || $request->method == 'MKCALENDAR' || $request->method == 'MKCOL' ) ) {
  if ( preg_match( '#^/principals/users(/.*/)$#', $request->path, $matches ) ) {
    // Although this doesn't work with the iPhone, perhaps it will with iCal...
    // This is better handled by a RewriteRule, see config/apache-davical.conf
    $redirect_url = ConstructURL('/caldav.php'.$matches[1]);
    dbg_error_log( 'LOG WARNING', 'Redirecting %s for "%s" to "%s", consider using rewrites in the webserver instead!', $request->method, $request->path, $redirect_url );
    header('Location: '.$redirect_url );
    @ob_flush(); exit(0);
  }
}
param_to_global('add_member', null, 'add-member');
$add_member = isset($add_member);

try {

  switch ( $request->method ) {
    case 'OPTIONS':    include_once('caldav-OPTIONS.php');   break;
    case 'REPORT':     include_once('caldav-REPORT.php');    break;
    case 'PROPFIND':   include('caldav-PROPFIND.php');       break;
    case 'GET':        include('caldav-GET.php');            break;
    case 'HEAD':       include('caldav-GET.php');            break;
    case 'PROPPATCH':  include('caldav-PROPPATCH.php');      break;
    case 'POST':
      if ( $request->content_type != 'text/vcard' && !$add_member ) {
        include('caldav-POST.php');
        break;
      }
      // fall through if POST add member
    case 'PUT':
      switch( $request->content_type ) {
        case 'text/calendar':
          include('caldav-PUT-vcalendar.php');
          break;
        case 'text/vcard':
        case 'text/x-vcard':
          include('caldav-PUT-vcard.php');
          break;
        default:
          include('caldav-PUT-default.php');
          break;
      }
      break;
    case 'MKCALENDAR': include('caldav-MKCOL.php');          break;
    case 'MKCOL':      include('caldav-MKCOL.php');          break;
    case 'DELETE':     include('caldav-DELETE.php');         break;
    case 'MOVE':       include('caldav-MOVE.php');           break;
    case 'ACL':        include('caldav-ACL.php');            break;
    case 'LOCK':       include('caldav-LOCK.php');           break;
    case 'UNLOCK':     include('caldav-LOCK.php');           break;
    case 'MKTICKET':   include('caldav-MKTICKET.php');       break;
    case 'DELTICKET':  include('caldav-DELTICKET.php');      break;
    case 'BIND':       include('caldav-BIND.php');           break;

    case 'TESTRRULE':  include('test-RRULE-v2.php');         break;

    default:
      dbg_error_log( 'caldav', 'Unhandled request method >>%s<<', $request->method );
      dbg_log_array( 'caldav', '_SERVER', $_SERVER, true );
      dbg_error_log( 'caldav', 'RAW: %s', str_replace("\n", '',str_replace("\r", '', $request->raw_post)) );
  }

} catch (Exception $e) {
  trace_bug( 'DAViCal Fatal Error: ['.$e->getCode().'] '.$e->getmessage().' at '.$e->getFile().':'.$e->getLine() );
  $request->DoResponse( 500, translate('DAViCal Fatal Error') );
}

$request->DoResponse( 400, translate('The application program does not understand that request.') );