Passed
Push — master ( 34e8da...f497d2 )
by
unknown
06:10 queued 02:50
created
lib/exceptions/httpreturncodeexception.php 2 patches
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -8,13 +8,13 @@
 block discarded – undo
8 8
  * to the mobile.
9 9
  */
10 10
 class HTTPReturnCodeException extends FatalException {
11
-	protected $defaultLogLevel = LOGLEVEL_ERROR;
12
-	protected $showLegal = false;
11
+    protected $defaultLogLevel = LOGLEVEL_ERROR;
12
+    protected $showLegal = false;
13 13
 
14
-	public function __construct($message = "", $code = 0, $previous = null, $logLevel = false) {
15
-		if ($code) {
16
-			$this->httpReturnCode = $code;
17
-		}
18
-		parent::__construct($message, (int) $code, $previous, $logLevel);
19
-	}
14
+    public function __construct($message = "", $code = 0, $previous = null, $logLevel = false) {
15
+        if ($code) {
16
+            $this->httpReturnCode = $code;
17
+        }
18
+        parent::__construct($message, (int) $code, $previous, $logLevel);
19
+    }
20 20
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -15,6 +15,6 @@
 block discarded – undo
15 15
 		if ($code) {
16 16
 			$this->httpReturnCode = $code;
17 17
 		}
18
-		parent::__construct($message, (int) $code, $previous, $logLevel);
18
+		parent::__construct($message, (int)$code, $previous, $logLevel);
19 19
 	}
20 20
 }
Please login to merge, or discard this patch.
lib/exceptions/nopostrequestexception.php 1 patch
Indentation   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -8,7 +8,7 @@
 block discarded – undo
8 8
  * The code indicates if the request identified was a OPTIONS or GET request
9 9
  */
10 10
 class NoPostRequestException extends FatalException {
11
-	public const OPTIONS_REQUEST = 1;
12
-	public const GET_REQUEST = 2;
13
-	protected $defaultLogLevel = LOGLEVEL_DEBUG;
11
+    public const OPTIONS_REQUEST = 1;
12
+    public const GET_REQUEST = 2;
13
+    protected $defaultLogLevel = LOGLEVEL_DEBUG;
14 14
 }
Please login to merge, or discard this patch.
lib/exceptions/serviceunavailableexception.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -8,16 +8,16 @@
 block discarded – undo
8 8
  */
9 9
 
10 10
 class ServiceUnavailableException extends HTTPReturnCodeException {
11
-	protected $defaultLogLevel = LOGLEVEL_INFO;
12
-	protected $httpReturnCode = HTTP_CODE_503;
13
-	protected $httpReturnMessage = "Service Unavailable";
14
-	protected $httpHeaders = [];
15
-	protected $showLegal = false;
11
+    protected $defaultLogLevel = LOGLEVEL_INFO;
12
+    protected $httpReturnCode = HTTP_CODE_503;
13
+    protected $httpReturnMessage = "Service Unavailable";
14
+    protected $httpHeaders = [];
15
+    protected $showLegal = false;
16 16
 
17
-	public function __construct($message = "", $code = 0, $previous = null, $logLevel = false) {
18
-		parent::__construct($message, $code, $previous, $logLevel);
19
-		if (RETRY_AFTER_DELAY !== false) {
20
-			$this->httpHeaders[] = 'Retry-After: ' . RETRY_AFTER_DELAY;
21
-		}
22
-	}
17
+    public function __construct($message = "", $code = 0, $previous = null, $logLevel = false) {
18
+        parent::__construct($message, $code, $previous, $logLevel);
19
+        if (RETRY_AFTER_DELAY !== false) {
20
+            $this->httpHeaders[] = 'Retry-After: ' . RETRY_AFTER_DELAY;
21
+        }
22
+    }
23 23
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -17,7 +17,7 @@
 block discarded – undo
17 17
 	public function __construct($message = "", $code = 0, $previous = null, $logLevel = false) {
18 18
 		parent::__construct($message, $code, $previous, $logLevel);
19 19
 		if (RETRY_AFTER_DELAY !== false) {
20
-			$this->httpHeaders[] = 'Retry-After: ' . RETRY_AFTER_DELAY;
20
+			$this->httpHeaders[] = 'Retry-After: '.RETRY_AFTER_DELAY;
21 21
 		}
22 22
 	}
23 23
 }
Please login to merge, or discard this patch.
config.php 2 patches
Indentation   +194 added lines, -194 removed lines patch added patch discarded remove patch
@@ -10,29 +10,29 @@  discard block
 block discarded – undo
10 10
 /*
11 11
  *  Default settings
12 12
  */
13
-	// Defines the default time zone, change e.g. to "Europe/London" if necessary
14
-	define('TIMEZONE', '');
13
+    // Defines the default time zone, change e.g. to "Europe/London" if necessary
14
+    define('TIMEZONE', '');
15 15
 
16
-	// Defines the base path on the server
17
-	define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . '/');
16
+    // Defines the base path on the server
17
+    define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . '/');
18 18
 
19
-	// Try to set unlimited timeout
20
-	define('SCRIPT_TIMEOUT', 0);
19
+    // Try to set unlimited timeout
20
+    define('SCRIPT_TIMEOUT', 0);
21 21
 
22
-	// This should be solved on THE webserver level if there are proxies
23
-	// between mobile client and grommunio-sync.
24
-	// Use a custom header to determinate the remote IP of a client.
25
-	// By default, the server provided REMOTE_ADDR is used. If the header here set
26
-	// is available, the provided value will be used, else REMOTE_ADDR is maintained.
27
-	// set to false to disable this behaviour.
28
-	// common values: 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP' (casing is ignored)
29
-	define('USE_CUSTOM_REMOTE_IP_HEADER', false);
22
+    // This should be solved on THE webserver level if there are proxies
23
+    // between mobile client and grommunio-sync.
24
+    // Use a custom header to determinate the remote IP of a client.
25
+    // By default, the server provided REMOTE_ADDR is used. If the header here set
26
+    // is available, the provided value will be used, else REMOTE_ADDR is maintained.
27
+    // set to false to disable this behaviour.
28
+    // common values: 'HTTP_X_FORWARDED_FOR', 'HTTP_X_REAL_IP' (casing is ignored)
29
+    define('USE_CUSTOM_REMOTE_IP_HEADER', false);
30 30
 
31
-	// When using client certificates, we can check if the login sent matches the owner of the certificate.
32
-	// This setting specifies the owner parameter in the certificate to look at.
33
-	define("CERTIFICATE_OWNER_PARAMETER", "SSL_CLIENT_S_DN_CN");
31
+    // When using client certificates, we can check if the login sent matches the owner of the certificate.
32
+    // This setting specifies the owner parameter in the certificate to look at.
33
+    define("CERTIFICATE_OWNER_PARAMETER", "SSL_CLIENT_S_DN_CN");
34 34
 
35
-	/*
35
+    /*
36 36
 	 * Whether to use the complete email address as a login name
37 37
 	 * (e.g. [email protected]) or the username only (user).
38 38
 	 * This is required for grommunio-sync to work properly after autodiscover.
@@ -40,7 +40,7 @@  discard block
 block discarded – undo
40 40
 	 *   false - use the username only.
41 41
 	 *   true  - string the mobile sends as username, e.g. full email address (default).
42 42
 	 */
43
-	define('USE_FULLEMAIL_FOR_LOGIN', true);
43
+    define('USE_FULLEMAIL_FOR_LOGIN', true);
44 44
 
45 45
 /*
46 46
  *  Logging settings
@@ -67,189 +67,189 @@  discard block
 block discarded – undo
67 67
  *
68 68
  *  LOGAUTHFAIL is logged to the LOGBACKEND.
69 69
  */
70
-	define('LOGBACKEND', 'filelog');
71
-	define('LOGLEVEL', LOGLEVEL_WBXML);
72
-	define('LOGAUTHFAIL', false);
73
-
74
-	// To save e.g. WBXML data only for selected users, add the usernames to the array
75
-	// The data will be saved into a dedicated file per user in the LOGFILEDIR
76
-	// Users have to be encapusulated in quotes, several users are comma separated, like:
77
-	//   $specialLogUsers = array('[email protected]', 'myusername');
78
-	define('LOGUSERLEVEL', LOGLEVEL_DEVICEID);
79
-	$specialLogUsers = [];
80
-
81
-	// Filelog settings
82
-	define('LOGFILEDIR', '/var/log/grommunio-sync/');
83
-	define('LOGFILE', LOGFILEDIR . 'grommunio-sync.log');
84
-	define('LOGERRORFILE', LOGFILEDIR . 'grommunio-sync-error.log');
85
-
86
-	// Syslog settings
87
-	// false will log to local syslog, otherwise put the remote syslog IP here
88
-	define('LOG_SYSLOG_HOST', false);
89
-	// Syslog port
90
-	define('LOG_SYSLOG_PORT', 514);
91
-	// Program showed in the syslog. Useful if you have more than one instance login to the same syslog
92
-	define('LOG_SYSLOG_PROGRAM', 'grommunio-sync');
93
-	// Syslog facility - use LOG_USER when running on Windows
94
-	define('LOG_SYSLOG_FACILITY', LOG_LOCAL0);
95
-
96
-	// Location of the trusted CA, e.g. '/etc/ssl/certs/EmailCA.pem'
97
-	// Uncomment and modify the following line if the validation of the certificates fails.
98
-	// define('CAINFO', '/etc/ssl/certs/EmailCA.pem');
70
+    define('LOGBACKEND', 'filelog');
71
+    define('LOGLEVEL', LOGLEVEL_WBXML);
72
+    define('LOGAUTHFAIL', false);
73
+
74
+    // To save e.g. WBXML data only for selected users, add the usernames to the array
75
+    // The data will be saved into a dedicated file per user in the LOGFILEDIR
76
+    // Users have to be encapusulated in quotes, several users are comma separated, like:
77
+    //   $specialLogUsers = array('[email protected]', 'myusername');
78
+    define('LOGUSERLEVEL', LOGLEVEL_DEVICEID);
79
+    $specialLogUsers = [];
80
+
81
+    // Filelog settings
82
+    define('LOGFILEDIR', '/var/log/grommunio-sync/');
83
+    define('LOGFILE', LOGFILEDIR . 'grommunio-sync.log');
84
+    define('LOGERRORFILE', LOGFILEDIR . 'grommunio-sync-error.log');
85
+
86
+    // Syslog settings
87
+    // false will log to local syslog, otherwise put the remote syslog IP here
88
+    define('LOG_SYSLOG_HOST', false);
89
+    // Syslog port
90
+    define('LOG_SYSLOG_PORT', 514);
91
+    // Program showed in the syslog. Useful if you have more than one instance login to the same syslog
92
+    define('LOG_SYSLOG_PROGRAM', 'grommunio-sync');
93
+    // Syslog facility - use LOG_USER when running on Windows
94
+    define('LOG_SYSLOG_FACILITY', LOG_LOCAL0);
95
+
96
+    // Location of the trusted CA, e.g. '/etc/ssl/certs/EmailCA.pem'
97
+    // Uncomment and modify the following line if the validation of the certificates fails.
98
+    // define('CAINFO', '/etc/ssl/certs/EmailCA.pem');
99 99
 
100 100
 /*
101 101
  *  Mobile settings
102 102
  */
103
-	// Device Provisioning
104
-	define('PROVISIONING', true);
105
-
106
-	// This option allows the 'loose enforcement' of the provisioning policies for older
107
-	// devices which don't support provisioning (like WM 5 and HTC Android Mail) - dw2412 contribution
108
-	// false (default) - Enforce provisioning for all devices
109
-	// true - allow older devices, but enforce policies on devices which support it
110
-	define('LOOSE_PROVISIONING', false);
111
-
112
-	// Retrieve polcies for a user from admin API using the following endpoint
113
-	define('ADMIN_API_POLICY_ENDPOINT', 'http://[::1]:8080/api/v1/service/syncPolicy/');
114
-
115
-	// Retrieve and update remote wipe status for a user and device from admin API using the following endpoint
116
-	define('ADMIN_API_WIPE_ENDPOINT', 'http://[::1]:8080/api/v1/service/wipe/');
117
-
118
-	// Default conflict preference
119
-	// Some devices allow to set if the server or PIM (mobile)
120
-	// should win in case of a synchronization conflict
121
-	//   SYNC_CONFLICT_OVERWRITE_SERVER - Server is overwritten, PIM wins
122
-	//   SYNC_CONFLICT_OVERWRITE_PIM    - PIM is overwritten, Server wins (default)
123
-	define('SYNC_CONFLICT_DEFAULT', SYNC_CONFLICT_OVERWRITE_PIM);
124
-
125
-	// Global limitation of items to be synchronized
126
-	// The mobile can define a sync back period for calendar and email items
127
-	// For large stores with many items the time period could be limited to a max value
128
-	// If the mobile transmits a wider time period, the defined max value is used
129
-	// Applicable values:
130
-	//   SYNC_FILTERTYPE_ALL (default, no limitation)
131
-	//   SYNC_FILTERTYPE_1DAY, SYNC_FILTERTYPE_3DAYS, SYNC_FILTERTYPE_1WEEK, SYNC_FILTERTYPE_2WEEKS,
132
-	//   SYNC_FILTERTYPE_1MONTH, SYNC_FILTERTYPE_3MONTHS, SYNC_FILTERTYPE_6MONTHS
133
-	define('SYNC_FILTERTIME_MAX', SYNC_FILTERTYPE_ALL);
134
-
135
-	// Interval in seconds before checking if there are changes on the server when in Ping.
136
-	// It means the highest time span before a change is pushed to a mobile. Set it to
137
-	// a higher value if you have a high load on the server.
138
-	define('PING_INTERVAL', 30);
139
-
140
-	// Set the fileas (save as) order for contacts in the webaccess/webapp/outlook.
141
-	// It will only affect new/modified contacts on the mobile which then are synced to the server.
142
-	// Possible values are:
143
-	// SYNC_FILEAS_FIRSTLAST    - fileas will be "Firstname Middlename Lastname"
144
-	// SYNC_FILEAS_LASTFIRST    - fileas will be "Lastname, Firstname Middlename"
145
-	// SYNC_FILEAS_COMPANYONLY  - fileas will be "Company"
146
-	// SYNC_FILEAS_COMPANYLAST  - fileas will be "Company (Lastname, Firstname Middlename)"
147
-	// SYNC_FILEAS_COMPANYFIRST - fileas will be "Company (Firstname Middlename Lastname)"
148
-	// SYNC_FILEAS_LASTCOMPANY  - fileas will be "Lastname, Firstname Middlename (Company)"
149
-	// SYNC_FILEAS_FIRSTCOMPANY - fileas will be "Firstname Middlename Lastname (Company)"
150
-	// The company-fileas will only be set if a contact has a company set. If one of
151
-	// company-fileas is selected and a contact doesn't have a company set, it will default
152
-	// to SYNC_FILEAS_FIRSTLAST or SYNC_FILEAS_LASTFIRST (depending on if last or first
153
-	// option is selected for company).
154
-	// If SYNC_FILEAS_COMPANYONLY is selected and company of the contact is not set
155
-	// SYNC_FILEAS_LASTFIRST will be used
156
-	define('FILEAS_ORDER', SYNC_FILEAS_LASTFIRST);
157
-
158
-	// Maximum amount of items to be synchronized per request.
159
-	// Normally this value is requested by the mobile. Common values are 5, 25, 50 or 100.
160
-	// Exporting too much items can cause mobile timeout on busy systems.
161
-	// grommunio-sync will use the lowest provided value, either set here or by the mobile.
162
-	// MS Outlook 2013+ request up to 512 items to accelerate the sync process.
163
-	// If you detect high load (also on subsystems) you could try a lower setting.
164
-	// max: 512 - value used if mobile does not limit amount of items
165
-	define('SYNC_MAX_ITEMS', 512);
166
-
167
-	// The devices usually send a list of supported properties for calendar and contact
168
-	// items. If a device does not includes such a supported property in Sync request,
169
-	// it means the property's value will be deleted on the server.
170
-	// However some devices do not send a list of supported properties. It is then impossible
171
-	// to tell if a property was deleted or it was not set at all if it does not appear in Sync.
172
-	// This parameter defines grommunio-sync behaviour during Sync if a device does not issue a list with
173
-	// supported properties.
174
-	// See also https://jira.z-hub.io/browse/ZP-302.
175
-	// Possible values:
176
-	// false - do not unset properties which are not sent during Sync (default)
177
-	// true  - unset properties which are not sent during Sync
178
-	define('UNSET_UNDEFINED_PROPERTIES', false);
179
-
180
-	// ActiveSync specifies that a contact photo may not exceed 48 KB. This value is checked
181
-	// in the semantic sanity checks and contacts with larger photos are not synchronized.
182
-	// This limitation is not being followed by the ActiveSync clients which set much bigger
183
-	// contact photos. You can override the default value of the max photo size.
184
-	// default: 5242880 - 5 MB default max photo size in bytes
185
-	define('SYNC_CONTACTS_MAXPICTURESIZE', 5242880);
186
-
187
-	// Users with many folders can use the 'partial foldersync' feature, where the server
188
-	// actively stops processing the folder list if it takes too long. Other requests are
189
-	// then redirected to the FolderSync to synchronize the remaining items.
190
-	// Device compatibility for this procedure is not fully understood.
191
-	// NOTE: THIS IS AN EXPERIMENTAL FEATURE WHICH COULD PREVENT YOUR MOBILES FROM SYNCHRONIZING.
192
-	define('USE_PARTIAL_FOLDERSYNC', false);
193
-
194
-	// The minimum accepted time in second that a ping command should last.
195
-	// It is strongly advised to keep this config to false. Some device
196
-	// might not be able to send a higher value than the one specified here and thus
197
-	// unable to start a push connection.
198
-	// If set to false, there will be no lower bound to the ping lifetime.
199
-	// The minimum accepted value is 1 second. The maximum accepted value is 3540 seconds (59 minutes).
200
-	define('PING_LOWER_BOUND_LIFETIME', false);
201
-
202
-	// The maximum accepted time in second that a ping command should last.
203
-	// If set to false, there will be no higher bound to the ping lifetime.
204
-	// The minimum accepted value is 1 second. The maximum accepted value is 3540 seconds (59 minutes).
205
-	define('PING_HIGHER_BOUND_LIFETIME', false);
206
-
207
-	// Maximum response time
208
-	// Mobiles implement different timeouts to their TCP/IP connections. Android devices for example
209
-	// have a hard timeout of 30 seconds. If the server is not able to answer a request within this timeframe,
210
-	// the answer will not be received and the device will send a new one overloading the server.
211
-	// There are three categories
212
-	//   - Short timeout  - server has up within 30 seconds - is automatically applied for not categorized types
213
-	//   - Medium timeout - server has up to 90 seconds to respond
214
-	//   - Long timeout   - server has up to 4 minutes to respond
215
-	// If a timeout is almost reached the server will break and sent the results it has until this
216
-	// point. You can add DeviceType strings to the categories.
217
-	// In general longer timeouts are better, because more data can be streamed at once.
218
-	define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI");
219
-	define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook, WindowsMail");
220
-
221
-	// Time in seconds the device should wait whenever the service is unavailable,
222
-	// e.g. when a backend service is unavailable.
223
-	// grommunio-sync sends a "Retry-After" header in the response with the here defined value.
224
-	// It is up to the device to respect or not this directive so even if this option is set,
225
-	// the device might not wait requested time frame.
226
-	// Number of seconds before retry, to disable set to: false
227
-	define('RETRY_AFTER_DELAY', 300);
103
+    // Device Provisioning
104
+    define('PROVISIONING', true);
105
+
106
+    // This option allows the 'loose enforcement' of the provisioning policies for older
107
+    // devices which don't support provisioning (like WM 5 and HTC Android Mail) - dw2412 contribution
108
+    // false (default) - Enforce provisioning for all devices
109
+    // true - allow older devices, but enforce policies on devices which support it
110
+    define('LOOSE_PROVISIONING', false);
111
+
112
+    // Retrieve polcies for a user from admin API using the following endpoint
113
+    define('ADMIN_API_POLICY_ENDPOINT', 'http://[::1]:8080/api/v1/service/syncPolicy/');
114
+
115
+    // Retrieve and update remote wipe status for a user and device from admin API using the following endpoint
116
+    define('ADMIN_API_WIPE_ENDPOINT', 'http://[::1]:8080/api/v1/service/wipe/');
117
+
118
+    // Default conflict preference
119
+    // Some devices allow to set if the server or PIM (mobile)
120
+    // should win in case of a synchronization conflict
121
+    //   SYNC_CONFLICT_OVERWRITE_SERVER - Server is overwritten, PIM wins
122
+    //   SYNC_CONFLICT_OVERWRITE_PIM    - PIM is overwritten, Server wins (default)
123
+    define('SYNC_CONFLICT_DEFAULT', SYNC_CONFLICT_OVERWRITE_PIM);
124
+
125
+    // Global limitation of items to be synchronized
126
+    // The mobile can define a sync back period for calendar and email items
127
+    // For large stores with many items the time period could be limited to a max value
128
+    // If the mobile transmits a wider time period, the defined max value is used
129
+    // Applicable values:
130
+    //   SYNC_FILTERTYPE_ALL (default, no limitation)
131
+    //   SYNC_FILTERTYPE_1DAY, SYNC_FILTERTYPE_3DAYS, SYNC_FILTERTYPE_1WEEK, SYNC_FILTERTYPE_2WEEKS,
132
+    //   SYNC_FILTERTYPE_1MONTH, SYNC_FILTERTYPE_3MONTHS, SYNC_FILTERTYPE_6MONTHS
133
+    define('SYNC_FILTERTIME_MAX', SYNC_FILTERTYPE_ALL);
134
+
135
+    // Interval in seconds before checking if there are changes on the server when in Ping.
136
+    // It means the highest time span before a change is pushed to a mobile. Set it to
137
+    // a higher value if you have a high load on the server.
138
+    define('PING_INTERVAL', 30);
139
+
140
+    // Set the fileas (save as) order for contacts in the webaccess/webapp/outlook.
141
+    // It will only affect new/modified contacts on the mobile which then are synced to the server.
142
+    // Possible values are:
143
+    // SYNC_FILEAS_FIRSTLAST    - fileas will be "Firstname Middlename Lastname"
144
+    // SYNC_FILEAS_LASTFIRST    - fileas will be "Lastname, Firstname Middlename"
145
+    // SYNC_FILEAS_COMPANYONLY  - fileas will be "Company"
146
+    // SYNC_FILEAS_COMPANYLAST  - fileas will be "Company (Lastname, Firstname Middlename)"
147
+    // SYNC_FILEAS_COMPANYFIRST - fileas will be "Company (Firstname Middlename Lastname)"
148
+    // SYNC_FILEAS_LASTCOMPANY  - fileas will be "Lastname, Firstname Middlename (Company)"
149
+    // SYNC_FILEAS_FIRSTCOMPANY - fileas will be "Firstname Middlename Lastname (Company)"
150
+    // The company-fileas will only be set if a contact has a company set. If one of
151
+    // company-fileas is selected and a contact doesn't have a company set, it will default
152
+    // to SYNC_FILEAS_FIRSTLAST or SYNC_FILEAS_LASTFIRST (depending on if last or first
153
+    // option is selected for company).
154
+    // If SYNC_FILEAS_COMPANYONLY is selected and company of the contact is not set
155
+    // SYNC_FILEAS_LASTFIRST will be used
156
+    define('FILEAS_ORDER', SYNC_FILEAS_LASTFIRST);
157
+
158
+    // Maximum amount of items to be synchronized per request.
159
+    // Normally this value is requested by the mobile. Common values are 5, 25, 50 or 100.
160
+    // Exporting too much items can cause mobile timeout on busy systems.
161
+    // grommunio-sync will use the lowest provided value, either set here or by the mobile.
162
+    // MS Outlook 2013+ request up to 512 items to accelerate the sync process.
163
+    // If you detect high load (also on subsystems) you could try a lower setting.
164
+    // max: 512 - value used if mobile does not limit amount of items
165
+    define('SYNC_MAX_ITEMS', 512);
166
+
167
+    // The devices usually send a list of supported properties for calendar and contact
168
+    // items. If a device does not includes such a supported property in Sync request,
169
+    // it means the property's value will be deleted on the server.
170
+    // However some devices do not send a list of supported properties. It is then impossible
171
+    // to tell if a property was deleted or it was not set at all if it does not appear in Sync.
172
+    // This parameter defines grommunio-sync behaviour during Sync if a device does not issue a list with
173
+    // supported properties.
174
+    // See also https://jira.z-hub.io/browse/ZP-302.
175
+    // Possible values:
176
+    // false - do not unset properties which are not sent during Sync (default)
177
+    // true  - unset properties which are not sent during Sync
178
+    define('UNSET_UNDEFINED_PROPERTIES', false);
179
+
180
+    // ActiveSync specifies that a contact photo may not exceed 48 KB. This value is checked
181
+    // in the semantic sanity checks and contacts with larger photos are not synchronized.
182
+    // This limitation is not being followed by the ActiveSync clients which set much bigger
183
+    // contact photos. You can override the default value of the max photo size.
184
+    // default: 5242880 - 5 MB default max photo size in bytes
185
+    define('SYNC_CONTACTS_MAXPICTURESIZE', 5242880);
186
+
187
+    // Users with many folders can use the 'partial foldersync' feature, where the server
188
+    // actively stops processing the folder list if it takes too long. Other requests are
189
+    // then redirected to the FolderSync to synchronize the remaining items.
190
+    // Device compatibility for this procedure is not fully understood.
191
+    // NOTE: THIS IS AN EXPERIMENTAL FEATURE WHICH COULD PREVENT YOUR MOBILES FROM SYNCHRONIZING.
192
+    define('USE_PARTIAL_FOLDERSYNC', false);
193
+
194
+    // The minimum accepted time in second that a ping command should last.
195
+    // It is strongly advised to keep this config to false. Some device
196
+    // might not be able to send a higher value than the one specified here and thus
197
+    // unable to start a push connection.
198
+    // If set to false, there will be no lower bound to the ping lifetime.
199
+    // The minimum accepted value is 1 second. The maximum accepted value is 3540 seconds (59 minutes).
200
+    define('PING_LOWER_BOUND_LIFETIME', false);
201
+
202
+    // The maximum accepted time in second that a ping command should last.
203
+    // If set to false, there will be no higher bound to the ping lifetime.
204
+    // The minimum accepted value is 1 second. The maximum accepted value is 3540 seconds (59 minutes).
205
+    define('PING_HIGHER_BOUND_LIFETIME', false);
206
+
207
+    // Maximum response time
208
+    // Mobiles implement different timeouts to their TCP/IP connections. Android devices for example
209
+    // have a hard timeout of 30 seconds. If the server is not able to answer a request within this timeframe,
210
+    // the answer will not be received and the device will send a new one overloading the server.
211
+    // There are three categories
212
+    //   - Short timeout  - server has up within 30 seconds - is automatically applied for not categorized types
213
+    //   - Medium timeout - server has up to 90 seconds to respond
214
+    //   - Long timeout   - server has up to 4 minutes to respond
215
+    // If a timeout is almost reached the server will break and sent the results it has until this
216
+    // point. You can add DeviceType strings to the categories.
217
+    // In general longer timeouts are better, because more data can be streamed at once.
218
+    define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI");
219
+    define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook, WindowsMail");
220
+
221
+    // Time in seconds the device should wait whenever the service is unavailable,
222
+    // e.g. when a backend service is unavailable.
223
+    // grommunio-sync sends a "Retry-After" header in the response with the here defined value.
224
+    // It is up to the device to respect or not this directive so even if this option is set,
225
+    // the device might not wait requested time frame.
226
+    // Number of seconds before retry, to disable set to: false
227
+    define('RETRY_AFTER_DELAY', 300);
228 228
 
229 229
 /*
230 230
  *  Grommunio settings
231 231
  */
232
-	// Defines the server to which we want to connect.
233
-	define('MAPI_SERVER', 'default:');
232
+    // Defines the server to which we want to connect.
233
+    define('MAPI_SERVER', 'default:');
234 234
 
235
-	// Hidden state folder in store
236
-	define('STORE_STATE_FOLDER', 'GS-SyncState');
235
+    // Hidden state folder in store
236
+    define('STORE_STATE_FOLDER', 'GS-SyncState');
237 237
 
238
-	// Redis host
239
-	define('REDIS_HOST', 'localhost');
238
+    // Redis host
239
+    define('REDIS_HOST', 'localhost');
240 240
 
241
-	// Redis port
242
-	define('REDIS_PORT', 6379);
241
+    // Redis port
242
+    define('REDIS_PORT', 6379);
243 243
 
244
-	// Redis authentication - leave empty to connect without authentication (default)
245
-	define('REDIS_AUTH', '');
244
+    // Redis authentication - leave empty to connect without authentication (default)
245
+    define('REDIS_AUTH', '');
246 246
 
247
-	// Time in seconds for the server search. Setting it too high might result in timeout.
248
-	// Setting it too low might not return all results. Default is 10.
249
-	define('SEARCH_WAIT', 10);
250
-	// The maximum number of results to send to the client. Setting it too high
251
-	// might result in timeout. Default is 10.
252
-	define('SEARCH_MAXRESULTS', 10);
247
+    // Time in seconds for the server search. Setting it too high might result in timeout.
248
+    // Setting it too low might not return all results. Default is 10.
249
+    define('SEARCH_WAIT', 10);
250
+    // The maximum number of results to send to the client. Setting it too high
251
+    // might result in timeout. Default is 10.
252
+    define('SEARCH_MAXRESULTS', 10);
253 253
 
254 254
 /*
255 255
  *  Synchronize additional folders to all mobiles
@@ -294,10 +294,10 @@  discard block
 block discarded – undo
294 294
  *    added/modified folders.
295 295
  */
296 296
 
297
-	$additionalFolders = [
298
-		// demo entry for the synchronization of contacts from the public folder.
299
-		// uncomment (remove '/*' '*/') and fill in the folderid
300
-		/*
297
+    $additionalFolders = [
298
+        // demo entry for the synchronization of contacts from the public folder.
299
+        // uncomment (remove '/*' '*/') and fill in the folderid
300
+        /*
301 301
 		[
302 302
 			'store'     => "SYSTEM",
303 303
 			'folderid'  => "",
@@ -306,4 +306,4 @@  discard block
 block discarded – undo
306 306
 			'flags'     => DeviceManager::FLD_FLAGS_NONE,
307 307
 		],
308 308
 		*/
309
-	];
309
+    ];
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -14,7 +14,7 @@  discard block
 block discarded – undo
14 14
 	define('TIMEZONE', '');
15 15
 
16 16
 	// Defines the base path on the server
17
-	define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . '/');
17
+	define('BASE_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');
18 18
 
19 19
 	// Try to set unlimited timeout
20 20
 	define('SCRIPT_TIMEOUT', 0);
@@ -80,8 +80,8 @@  discard block
 block discarded – undo
80 80
 
81 81
 	// Filelog settings
82 82
 	define('LOGFILEDIR', '/var/log/grommunio-sync/');
83
-	define('LOGFILE', LOGFILEDIR . 'grommunio-sync.log');
84
-	define('LOGERRORFILE', LOGFILEDIR . 'grommunio-sync-error.log');
83
+	define('LOGFILE', LOGFILEDIR.'grommunio-sync.log');
84
+	define('LOGERRORFILE', LOGFILEDIR.'grommunio-sync-error.log');
85 85
 
86 86
 	// Syslog settings
87 87
 	// false will log to local syslog, otherwise put the remote syslog IP here
Please login to merge, or discard this patch.
index.php 3 patches
Indentation   +243 added lines, -243 removed lines patch added patch discarded remove patch
@@ -15,250 +15,250 @@
 block discarded – undo
15 15
 require_once 'vendor/autoload.php';
16 16
 
17 17
 if (!defined('GSYNC_CONFIG')) {
18
-	define('GSYNC_CONFIG', 'config.php');
18
+    define('GSYNC_CONFIG', 'config.php');
19 19
 }
20 20
 
21 21
 include_once GSYNC_CONFIG;
22 22
 
23
-	// Attempt to set maximum execution time
24
-	ini_set('max_execution_time', SCRIPT_TIMEOUT);
25
-	set_time_limit(SCRIPT_TIMEOUT);
26
-
27
-	try {
28
-		// check config & initialize the basics
29
-		GSync::CheckConfig();
30
-		Request::Initialize();
31
-		SLog::Initialize();
32
-
33
-		SLog::Write(LOGLEVEL_DEBUG, "-------- Start");
34
-		SLog::Write(
35
-			LOGLEVEL_DEBUG,
36
-			sprintf(
37
-				"cmd='%s' devType='%s' devId='%s' getUser='%s' from='%s' version='%s' method='%s'",
38
-				Request::GetCommand(),
39
-				Request::GetDeviceType(),
40
-				Request::GetDeviceID(),
41
-				Request::GetGETUser(),
42
-				Request::GetRemoteAddr(),
43
-				@constant('GROMMUNIOSYNC_VERSION'),
44
-				Request::GetMethod()
45
-			)
46
-		);
47
-
48
-		// always request the authorization header
49
-		if (!Request::HasAuthenticationInfo() || !Request::GetGETUser()) {
50
-			throw new AuthenticationRequiredException("Access denied. Please send authorisation information");
51
-		}
52
-
53
-		GSync::CheckAdvancedConfig();
54
-
55
-		// Process request headers and look for AS headers
56
-		Request::ProcessHeaders();
57
-
58
-		// Stop here if this is an OPTIONS request
59
-		if (Request::IsMethodOPTIONS()) {
60
-			RequestProcessor::Authenticate();
61
-
62
-			throw new NoPostRequestException("Options request", NoPostRequestException::OPTIONS_REQUEST);
63
-		}
64
-
65
-		// Check required GET parameters
66
-		if (Request::IsMethodPOST() && (Request::GetCommandCode() === false || !Request::GetDeviceID() || !Request::GetDeviceType())) {
67
-			throw new FatalException("Requested the grommunio-sync URL without the required GET parameters");
68
-		}
69
-
70
-		// Load the backend
71
-		$backend = GSync::GetBackend();
72
-
73
-		// check the provisioning information
74
-		if (
75
-				PROVISIONING === true &&
76
-				Request::IsMethodPOST() &&
77
-				GSync::CommandNeedsProvisioning(Request::GetCommandCode()) &&
78
-				(
79
-					(Request::WasPolicyKeySent() && Request::GetPolicyKey() == 0) ||
80
-					GSync::GetProvisioningManager()->ProvisioningRequired(Request::GetPolicyKey())
81
-				) && (
82
-					LOOSE_PROVISIONING === false ||
83
-					(LOOSE_PROVISIONING === true && Request::WasPolicyKeySent())
84
-				)) {
85
-			// TODO for AS 14 send a wbxml response
86
-			throw new ProvisioningRequiredException();
87
-		}
88
-
89
-		// most commands require an authenticated user
90
-		if (GSync::CommandNeedsAuthentication(Request::GetCommandCode())) {
91
-			RequestProcessor::Authenticate();
92
-		}
93
-
94
-		// Do the actual processing of the request
95
-		if (Request::IsMethodGET()) {
96
-			throw new NoPostRequestException("This is the grommunio-sync location and can only be accessed by Microsoft ActiveSync-capable devices", NoPostRequestException::GET_REQUEST);
97
-		}
98
-
99
-		// Do the actual request
100
-		header(GSync::GetServerHeader());
101
-
102
-		if (RequestProcessor::isUserAuthenticated()) {
103
-			header("X-Grommunio-Sync-Version: " . @constant('GROMMUNIOSYNC_VERSION'));
104
-
105
-			// announce the supported AS versions (if not already sent to device)
106
-			if (GSync::GetDeviceManager()->AnnounceASVersion()) {
107
-				$versions = GSync::GetSupportedProtocolVersions(true);
108
-				SLog::Write(LOGLEVEL_INFO, sprintf("Announcing latest AS version to device: %s", $versions));
109
-				header("X-MS-RP: " . $versions);
110
-			}
111
-		}
112
-
113
-		RequestProcessor::Initialize();
114
-		RequestProcessor::HandleRequest();
115
-
116
-		// eventually the RequestProcessor wants to send other headers to the mobile
117
-		foreach (RequestProcessor::GetSpecialHeaders() as $header) {
118
-			SLog::Write(LOGLEVEL_DEBUG, sprintf("Special header: %s", $header));
119
-			header($header);
120
-		}
121
-
122
-		// stream the data
123
-		$len = ob_get_length();
124
-		$data = ob_get_contents();
125
-		ob_end_clean();
126
-
127
-		// log amount of data transferred
128
-		// TODO check $len when streaming more data (e.g. Attachments), as the data will be send chunked
129
-		if (GSync::GetDeviceManager(false)) {
130
-			GSync::GetDeviceManager()->SentData($len);
131
-		}
132
-
133
-		// Unfortunately, even though grommunio-sync can stream the data to the client
134
-		// with a chunked encoding, using chunked encoding breaks the progress bar
135
-		// on the PDA. So the data is de-chunk here, written a content-length header and
136
-		// data send as a 'normal' packet. If the output packet exceeds 1MB (see ob_start)
137
-		// then it will be sent as a chunked packet anyway because PHP will have to flush
138
-		// the buffer.
139
-		if (!headers_sent()) {
140
-			header("Content-Length: {$len}");
141
-		}
142
-
143
-		// send vnd.ms-sync.wbxml content type header if there is no content
144
-		// otherwise text/html content type is added which might break some devices
145
-		if (!headers_sent() && $len == 0) {
146
-			header("Content-Type: application/vnd.ms-sync.wbxml");
147
-		}
148
-
149
-		echo $data;
150
-
151
-		// destruct backend after all data is on the stream
152
-		$backend->Logoff();
153
-	}
154
-	catch (NoPostRequestException $nopostex) {
155
-		if ($nopostex->getCode() == NoPostRequestException::OPTIONS_REQUEST) {
156
-			header(GSync::GetServerHeader());
157
-			header(GSync::GetSupportedProtocolVersions());
158
-			header(GSync::GetSupportedCommands());
159
-			SLog::Write(LOGLEVEL_INFO, $nopostex->getMessage());
160
-		}
161
-		elseif ($nopostex->getCode() == NoPostRequestException::GET_REQUEST) {
162
-			if (Request::GetUserAgent()) {
163
-				SLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
164
-			}
165
-			if (!headers_sent() && $nopostex->showLegalNotice()) {
166
-				GSync::PrintGrommunioSyncLegal('GET not supported', $nopostex->getMessage());
167
-			}
168
-		}
169
-	}
170
-	catch (Exception $ex) {
171
-		// Extract any previous exception message for logging purpose.
172
-		$exclass = get_class($ex);
173
-		$exception_message = $ex->getMessage();
174
-		if ($ex->getPrevious()) {
175
-			do {
176
-				$current_exception = $ex->getPrevious();
177
-				$exception_message .= ' -> ' . $current_exception->getMessage();
178
-			}
179
-			while ($current_exception->getPrevious());
180
-		}
181
-
182
-		if (Request::GetUserAgent()) {
183
-			SLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
184
-		}
185
-
186
-		SLog::Write(LOGLEVEL_FATAL, sprintf('Exception: (%s) - %s', $exclass, $exception_message));
187
-
188
-		if (!headers_sent()) {
189
-			if ($ex instanceof GSyncException) {
190
-				header('HTTP/1.1 ' . $ex->getHTTPCodeString());
191
-				foreach ($ex->getHTTPHeaders() as $h) {
192
-					header($h);
193
-				}
194
-			}
195
-			// something really unexpected happened!
196
-			else {
197
-				header('HTTP/1.1 500 Internal Server Error');
198
-			}
199
-		}
200
-
201
-		if ($ex instanceof AuthenticationRequiredException) {
202
-			// Only print GSync legal message for GET requests because
203
-			// some devices send unauthorized OPTIONS requests
204
-			// and don't expect anything in the response body
205
-			if (Request::IsMethodGET()) {
206
-				GSync::PrintGrommunioSyncLegal($exclass, sprintf('<pre>%s</pre>', $ex->getMessage()));
207
-			}
208
-
209
-			// log the failed login attempt e.g. for fail2ban
210
-			if (defined('LOGAUTHFAIL') && LOGAUTHFAIL != false) {
211
-				SLog::Write(LOGLEVEL_WARN, sprintf("IP: %s failed to authenticate user '%s'", Request::GetRemoteAddr(), Request::GetAuthUser() ? Request::GetAuthUser() : Request::GetGETUser()));
212
-			}
213
-		}
214
-
215
-		// This could be a WBXML problem.. try to get the complete request
216
-		elseif ($ex instanceof WBXMLException) {
217
-			SLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this including the 'WBXML debug data' logged. Be aware that the debug data could contain confidential information.");
218
-		}
219
-
220
-		// Try to output some kind of error information. This is only possible if
221
-		// the output had not started yet. If it has started already, we can't show the user the error, and
222
-		// the device will give its own (useless) error message.
223
-		elseif (!($ex instanceof GSyncException) || $ex->showLegalNotice()) {
224
-			$cmdinfo = (Request::GetCommand()) ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
225
-			$extrace = $ex->getTrace();
226
-			$trace = (!empty($extrace)) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
227
-			GSync::PrintGrommunioSyncLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
228
-		}
229
-
230
-		// Announce exception to process loop detection
231
-		if (GSync::GetDeviceManager(false)) {
232
-			GSync::GetDeviceManager()->AnnounceProcessException($ex);
233
-		}
234
-
235
-		// Announce exception if the TopCollector if available
236
-		GSync::GetTopCollector()->AnnounceInformation(get_class($ex), true);
237
-	}
238
-
239
-	// save device data if the DeviceManager is available
240
-	if (GSync::GetDeviceManager(false)) {
241
-		GSync::GetDeviceManager()->Save();
242
-	}
243
-
244
-	// end gracefully
245
-	SLog::Write(
246
-		LOGLEVEL_INFO,
247
-		sprintf(
248
-			"cmd='%s' memory='%s/%s' time='%ss' devType='%s' devId='%s' getUser='%s' from='%s' idle='%ss' version='%s' method='%s' httpcode='%s'",
249
-			Request::GetCommand(),
250
-			Utils::FormatBytes(memory_get_peak_usage(false)),
251
-			Utils::FormatBytes(memory_get_peak_usage(true)),
252
-			number_format(microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"], 2),
253
-			Request::GetDeviceType(),
254
-			Request::GetDeviceID(),
255
-			Request::GetGETUser(),
256
-			Request::GetRemoteAddr(),
257
-			RequestProcessor::GetWaitTime(),
258
-			@constant('GROMMUNIOSYNC_VERSION'),
259
-			Request::GetMethod(),
260
-			http_response_code()
261
-		)
262
-	);
263
-
264
-	SLog::Write(LOGLEVEL_DEBUG, "-------- End");
23
+    // Attempt to set maximum execution time
24
+    ini_set('max_execution_time', SCRIPT_TIMEOUT);
25
+    set_time_limit(SCRIPT_TIMEOUT);
26
+
27
+    try {
28
+        // check config & initialize the basics
29
+        GSync::CheckConfig();
30
+        Request::Initialize();
31
+        SLog::Initialize();
32
+
33
+        SLog::Write(LOGLEVEL_DEBUG, "-------- Start");
34
+        SLog::Write(
35
+            LOGLEVEL_DEBUG,
36
+            sprintf(
37
+                "cmd='%s' devType='%s' devId='%s' getUser='%s' from='%s' version='%s' method='%s'",
38
+                Request::GetCommand(),
39
+                Request::GetDeviceType(),
40
+                Request::GetDeviceID(),
41
+                Request::GetGETUser(),
42
+                Request::GetRemoteAddr(),
43
+                @constant('GROMMUNIOSYNC_VERSION'),
44
+                Request::GetMethod()
45
+            )
46
+        );
47
+
48
+        // always request the authorization header
49
+        if (!Request::HasAuthenticationInfo() || !Request::GetGETUser()) {
50
+            throw new AuthenticationRequiredException("Access denied. Please send authorisation information");
51
+        }
52
+
53
+        GSync::CheckAdvancedConfig();
54
+
55
+        // Process request headers and look for AS headers
56
+        Request::ProcessHeaders();
57
+
58
+        // Stop here if this is an OPTIONS request
59
+        if (Request::IsMethodOPTIONS()) {
60
+            RequestProcessor::Authenticate();
61
+
62
+            throw new NoPostRequestException("Options request", NoPostRequestException::OPTIONS_REQUEST);
63
+        }
64
+
65
+        // Check required GET parameters
66
+        if (Request::IsMethodPOST() && (Request::GetCommandCode() === false || !Request::GetDeviceID() || !Request::GetDeviceType())) {
67
+            throw new FatalException("Requested the grommunio-sync URL without the required GET parameters");
68
+        }
69
+
70
+        // Load the backend
71
+        $backend = GSync::GetBackend();
72
+
73
+        // check the provisioning information
74
+        if (
75
+                PROVISIONING === true &&
76
+                Request::IsMethodPOST() &&
77
+                GSync::CommandNeedsProvisioning(Request::GetCommandCode()) &&
78
+                (
79
+                    (Request::WasPolicyKeySent() && Request::GetPolicyKey() == 0) ||
80
+                    GSync::GetProvisioningManager()->ProvisioningRequired(Request::GetPolicyKey())
81
+                ) && (
82
+                    LOOSE_PROVISIONING === false ||
83
+                    (LOOSE_PROVISIONING === true && Request::WasPolicyKeySent())
84
+                )) {
85
+            // TODO for AS 14 send a wbxml response
86
+            throw new ProvisioningRequiredException();
87
+        }
88
+
89
+        // most commands require an authenticated user
90
+        if (GSync::CommandNeedsAuthentication(Request::GetCommandCode())) {
91
+            RequestProcessor::Authenticate();
92
+        }
93
+
94
+        // Do the actual processing of the request
95
+        if (Request::IsMethodGET()) {
96
+            throw new NoPostRequestException("This is the grommunio-sync location and can only be accessed by Microsoft ActiveSync-capable devices", NoPostRequestException::GET_REQUEST);
97
+        }
98
+
99
+        // Do the actual request
100
+        header(GSync::GetServerHeader());
101
+
102
+        if (RequestProcessor::isUserAuthenticated()) {
103
+            header("X-Grommunio-Sync-Version: " . @constant('GROMMUNIOSYNC_VERSION'));
104
+
105
+            // announce the supported AS versions (if not already sent to device)
106
+            if (GSync::GetDeviceManager()->AnnounceASVersion()) {
107
+                $versions = GSync::GetSupportedProtocolVersions(true);
108
+                SLog::Write(LOGLEVEL_INFO, sprintf("Announcing latest AS version to device: %s", $versions));
109
+                header("X-MS-RP: " . $versions);
110
+            }
111
+        }
112
+
113
+        RequestProcessor::Initialize();
114
+        RequestProcessor::HandleRequest();
115
+
116
+        // eventually the RequestProcessor wants to send other headers to the mobile
117
+        foreach (RequestProcessor::GetSpecialHeaders() as $header) {
118
+            SLog::Write(LOGLEVEL_DEBUG, sprintf("Special header: %s", $header));
119
+            header($header);
120
+        }
121
+
122
+        // stream the data
123
+        $len = ob_get_length();
124
+        $data = ob_get_contents();
125
+        ob_end_clean();
126
+
127
+        // log amount of data transferred
128
+        // TODO check $len when streaming more data (e.g. Attachments), as the data will be send chunked
129
+        if (GSync::GetDeviceManager(false)) {
130
+            GSync::GetDeviceManager()->SentData($len);
131
+        }
132
+
133
+        // Unfortunately, even though grommunio-sync can stream the data to the client
134
+        // with a chunked encoding, using chunked encoding breaks the progress bar
135
+        // on the PDA. So the data is de-chunk here, written a content-length header and
136
+        // data send as a 'normal' packet. If the output packet exceeds 1MB (see ob_start)
137
+        // then it will be sent as a chunked packet anyway because PHP will have to flush
138
+        // the buffer.
139
+        if (!headers_sent()) {
140
+            header("Content-Length: {$len}");
141
+        }
142
+
143
+        // send vnd.ms-sync.wbxml content type header if there is no content
144
+        // otherwise text/html content type is added which might break some devices
145
+        if (!headers_sent() && $len == 0) {
146
+            header("Content-Type: application/vnd.ms-sync.wbxml");
147
+        }
148
+
149
+        echo $data;
150
+
151
+        // destruct backend after all data is on the stream
152
+        $backend->Logoff();
153
+    }
154
+    catch (NoPostRequestException $nopostex) {
155
+        if ($nopostex->getCode() == NoPostRequestException::OPTIONS_REQUEST) {
156
+            header(GSync::GetServerHeader());
157
+            header(GSync::GetSupportedProtocolVersions());
158
+            header(GSync::GetSupportedCommands());
159
+            SLog::Write(LOGLEVEL_INFO, $nopostex->getMessage());
160
+        }
161
+        elseif ($nopostex->getCode() == NoPostRequestException::GET_REQUEST) {
162
+            if (Request::GetUserAgent()) {
163
+                SLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
164
+            }
165
+            if (!headers_sent() && $nopostex->showLegalNotice()) {
166
+                GSync::PrintGrommunioSyncLegal('GET not supported', $nopostex->getMessage());
167
+            }
168
+        }
169
+    }
170
+    catch (Exception $ex) {
171
+        // Extract any previous exception message for logging purpose.
172
+        $exclass = get_class($ex);
173
+        $exception_message = $ex->getMessage();
174
+        if ($ex->getPrevious()) {
175
+            do {
176
+                $current_exception = $ex->getPrevious();
177
+                $exception_message .= ' -> ' . $current_exception->getMessage();
178
+            }
179
+            while ($current_exception->getPrevious());
180
+        }
181
+
182
+        if (Request::GetUserAgent()) {
183
+            SLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
184
+        }
185
+
186
+        SLog::Write(LOGLEVEL_FATAL, sprintf('Exception: (%s) - %s', $exclass, $exception_message));
187
+
188
+        if (!headers_sent()) {
189
+            if ($ex instanceof GSyncException) {
190
+                header('HTTP/1.1 ' . $ex->getHTTPCodeString());
191
+                foreach ($ex->getHTTPHeaders() as $h) {
192
+                    header($h);
193
+                }
194
+            }
195
+            // something really unexpected happened!
196
+            else {
197
+                header('HTTP/1.1 500 Internal Server Error');
198
+            }
199
+        }
200
+
201
+        if ($ex instanceof AuthenticationRequiredException) {
202
+            // Only print GSync legal message for GET requests because
203
+            // some devices send unauthorized OPTIONS requests
204
+            // and don't expect anything in the response body
205
+            if (Request::IsMethodGET()) {
206
+                GSync::PrintGrommunioSyncLegal($exclass, sprintf('<pre>%s</pre>', $ex->getMessage()));
207
+            }
208
+
209
+            // log the failed login attempt e.g. for fail2ban
210
+            if (defined('LOGAUTHFAIL') && LOGAUTHFAIL != false) {
211
+                SLog::Write(LOGLEVEL_WARN, sprintf("IP: %s failed to authenticate user '%s'", Request::GetRemoteAddr(), Request::GetAuthUser() ? Request::GetAuthUser() : Request::GetGETUser()));
212
+            }
213
+        }
214
+
215
+        // This could be a WBXML problem.. try to get the complete request
216
+        elseif ($ex instanceof WBXMLException) {
217
+            SLog::Write(LOGLEVEL_FATAL, "Request could not be processed correctly due to a WBXMLException. Please report this including the 'WBXML debug data' logged. Be aware that the debug data could contain confidential information.");
218
+        }
219
+
220
+        // Try to output some kind of error information. This is only possible if
221
+        // the output had not started yet. If it has started already, we can't show the user the error, and
222
+        // the device will give its own (useless) error message.
223
+        elseif (!($ex instanceof GSyncException) || $ex->showLegalNotice()) {
224
+            $cmdinfo = (Request::GetCommand()) ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
225
+            $extrace = $ex->getTrace();
226
+            $trace = (!empty($extrace)) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
227
+            GSync::PrintGrommunioSyncLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
228
+        }
229
+
230
+        // Announce exception to process loop detection
231
+        if (GSync::GetDeviceManager(false)) {
232
+            GSync::GetDeviceManager()->AnnounceProcessException($ex);
233
+        }
234
+
235
+        // Announce exception if the TopCollector if available
236
+        GSync::GetTopCollector()->AnnounceInformation(get_class($ex), true);
237
+    }
238
+
239
+    // save device data if the DeviceManager is available
240
+    if (GSync::GetDeviceManager(false)) {
241
+        GSync::GetDeviceManager()->Save();
242
+    }
243
+
244
+    // end gracefully
245
+    SLog::Write(
246
+        LOGLEVEL_INFO,
247
+        sprintf(
248
+            "cmd='%s' memory='%s/%s' time='%ss' devType='%s' devId='%s' getUser='%s' from='%s' idle='%ss' version='%s' method='%s' httpcode='%s'",
249
+            Request::GetCommand(),
250
+            Utils::FormatBytes(memory_get_peak_usage(false)),
251
+            Utils::FormatBytes(memory_get_peak_usage(true)),
252
+            number_format(microtime(true) - $_SERVER["REQUEST_TIME_FLOAT"], 2),
253
+            Request::GetDeviceType(),
254
+            Request::GetDeviceID(),
255
+            Request::GetGETUser(),
256
+            Request::GetRemoteAddr(),
257
+            RequestProcessor::GetWaitTime(),
258
+            @constant('GROMMUNIOSYNC_VERSION'),
259
+            Request::GetMethod(),
260
+            http_response_code()
261
+        )
262
+    );
263
+
264
+    SLog::Write(LOGLEVEL_DEBUG, "-------- End");
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -100,13 +100,13 @@  discard block
 block discarded – undo
100 100
 		header(GSync::GetServerHeader());
101 101
 
102 102
 		if (RequestProcessor::isUserAuthenticated()) {
103
-			header("X-Grommunio-Sync-Version: " . @constant('GROMMUNIOSYNC_VERSION'));
103
+			header("X-Grommunio-Sync-Version: ".@constant('GROMMUNIOSYNC_VERSION'));
104 104
 
105 105
 			// announce the supported AS versions (if not already sent to device)
106 106
 			if (GSync::GetDeviceManager()->AnnounceASVersion()) {
107 107
 				$versions = GSync::GetSupportedProtocolVersions(true);
108 108
 				SLog::Write(LOGLEVEL_INFO, sprintf("Announcing latest AS version to device: %s", $versions));
109
-				header("X-MS-RP: " . $versions);
109
+				header("X-MS-RP: ".$versions);
110 110
 			}
111 111
 		}
112 112
 
@@ -174,7 +174,7 @@  discard block
 block discarded – undo
174 174
 		if ($ex->getPrevious()) {
175 175
 			do {
176 176
 				$current_exception = $ex->getPrevious();
177
-				$exception_message .= ' -> ' . $current_exception->getMessage();
177
+				$exception_message .= ' -> '.$current_exception->getMessage();
178 178
 			}
179 179
 			while ($current_exception->getPrevious());
180 180
 		}
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
 
188 188
 		if (!headers_sent()) {
189 189
 			if ($ex instanceof GSyncException) {
190
-				header('HTTP/1.1 ' . $ex->getHTTPCodeString());
190
+				header('HTTP/1.1 '.$ex->getHTTPCodeString());
191 191
 				foreach ($ex->getHTTPHeaders() as $h) {
192 192
 					header($h);
193 193
 				}
@@ -223,8 +223,8 @@  discard block
 block discarded – undo
223 223
 		elseif (!($ex instanceof GSyncException) || $ex->showLegalNotice()) {
224 224
 			$cmdinfo = (Request::GetCommand()) ? sprintf(" processing command <i>%s</i>", Request::GetCommand()) : "";
225 225
 			$extrace = $ex->getTrace();
226
-			$trace = (!empty($extrace)) ? "\n\nTrace:\n" . print_r($extrace, 1) : "";
227
-			GSync::PrintGrommunioSyncLegal($exclass . $cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage() . $trace));
226
+			$trace = (!empty($extrace)) ? "\n\nTrace:\n".print_r($extrace, 1) : "";
227
+			GSync::PrintGrommunioSyncLegal($exclass.$cmdinfo, sprintf('<pre>%s</pre>', $ex->getMessage().$trace));
228 228
 		}
229 229
 
230 230
 		// Announce exception to process loop detection
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -150,15 +150,13 @@  discard block
 block discarded – undo
150 150
 
151 151
 		// destruct backend after all data is on the stream
152 152
 		$backend->Logoff();
153
-	}
154
-	catch (NoPostRequestException $nopostex) {
153
+	} catch (NoPostRequestException $nopostex) {
155 154
 		if ($nopostex->getCode() == NoPostRequestException::OPTIONS_REQUEST) {
156 155
 			header(GSync::GetServerHeader());
157 156
 			header(GSync::GetSupportedProtocolVersions());
158 157
 			header(GSync::GetSupportedCommands());
159 158
 			SLog::Write(LOGLEVEL_INFO, $nopostex->getMessage());
160
-		}
161
-		elseif ($nopostex->getCode() == NoPostRequestException::GET_REQUEST) {
159
+		} elseif ($nopostex->getCode() == NoPostRequestException::GET_REQUEST) {
162 160
 			if (Request::GetUserAgent()) {
163 161
 				SLog::Write(LOGLEVEL_INFO, sprintf("User-agent: '%s'", Request::GetUserAgent()));
164 162
 			}
@@ -166,8 +164,7 @@  discard block
 block discarded – undo
166 164
 				GSync::PrintGrommunioSyncLegal('GET not supported', $nopostex->getMessage());
167 165
 			}
168 166
 		}
169
-	}
170
-	catch (Exception $ex) {
167
+	} catch (Exception $ex) {
171 168
 		// Extract any previous exception message for logging purpose.
172 169
 		$exclass = get_class($ex);
173 170
 		$exception_message = $ex->getMessage();
Please login to merge, or discard this patch.