Version Description
- Updatet AWS SDK to ver.1.2.6 for Amazon S3
- Added AWS Regin "Northeast" (Japan)
- Added Microsoft Azure (Blob) as backup destination
- bug fixes
Download this release
Release Info
Developer | danielhuesken |
Plugin | BackWPup – WordPress Backup Plugin |
Version | 1.5.5 |
Comparing to | |
See all releases |
Code changes from version 1.5.2 to 1.5.5
- app/backwpup_dojob.php +88 -17
- app/functions5.php +124 -9
- app/js/options.js +26 -0
- app/libs/Microsoft/Exception.php +43 -0
- app/libs/Microsoft/Http/Client.php +1444 -0
- app/libs/Microsoft/Http/Client/Adapter/Curl.php +498 -0
- app/libs/Microsoft/Http/Client/Adapter/Exception.php +38 -0
- app/libs/Microsoft/Http/Client/Adapter/Interface.php +78 -0
- app/libs/Microsoft/Http/Client/Adapter/Proxy.php +267 -0
- app/libs/Microsoft/Http/Client/Adapter/Socket.php +531 -0
- app/libs/Microsoft/Http/Client/Adapter/Stream.php +46 -0
- app/libs/Microsoft/Http/Client/Exception.php +36 -0
- app/libs/Microsoft/Http/Cookie.php +408 -0
- app/libs/Microsoft/Http/CookieJar.php +403 -0
- app/libs/Microsoft/Http/Exception.php +48 -0
- app/libs/Microsoft/Http/Response.php +664 -0
- app/libs/Microsoft/Http/Response/Stream.php +235 -0
- app/libs/Microsoft/Uri.php +188 -0
- app/libs/Microsoft/Uri/Exception.php +37 -0
- app/libs/Microsoft/Uri/Http.php +761 -0
- app/libs/Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php +257 -0
- app/libs/Microsoft/WindowsAzure/Credentials/Exception.php +48 -0
- app/libs/Microsoft/WindowsAzure/Credentials/SharedAccessSignature.php +320 -0
- app/libs/Microsoft/WindowsAzure/Credentials/SharedKey.php +200 -0
- app/libs/Microsoft/WindowsAzure/Credentials/SharedKeyLite.php +179 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDataSources.php +104 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php +80 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDirectories.php +103 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationInstance.php +234 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationLogs.php +80 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php +84 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php +102 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php +104 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php +75 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/Exception.php +51 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/LogLevel.php +52 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/Manager.php +225 -0
- app/libs/Microsoft/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php +72 -0
- app/libs/Microsoft/WindowsAzure/Exception.php +48 -0
- app/libs/Microsoft/WindowsAzure/RetryPolicy/Exception.php +49 -0
- app/libs/Microsoft/WindowsAzure/RetryPolicy/NoRetry.php +71 -0
- app/libs/Microsoft/WindowsAzure/RetryPolicy/RetryN.php +105 -0
- app/libs/Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php +90 -0
- app/libs/Microsoft/WindowsAzure/SessionHandler.php +230 -0
- app/libs/Microsoft/WindowsAzure/Storage.php +586 -0
- app/libs/Microsoft/WindowsAzure/Storage/Batch.php +261 -0
- app/libs/Microsoft/WindowsAzure/Storage/BatchStorageAbstract.php +210 -0
- app/libs/Microsoft/WindowsAzure/Storage/Blob.php +2029 -0
- app/libs/Microsoft/WindowsAzure/Storage/Blob/Stream.php +578 -0
- app/libs/Microsoft/WindowsAzure/Storage/BlobContainer.php +112 -0
- app/libs/Microsoft/WindowsAzure/Storage/BlobInstance.php +145 -0
- app/libs/Microsoft/WindowsAzure/Storage/DynamicTableEntity.php +213 -0
- app/libs/Microsoft/WindowsAzure/Storage/LeaseInstance.php +78 -0
- app/libs/Microsoft/WindowsAzure/Storage/PageRegionInstance.php +72 -0
- app/libs/Microsoft/WindowsAzure/Storage/Queue.php +582 -0
- app/libs/Microsoft/WindowsAzure/Storage/QueueInstance.php +74 -0
- app/libs/Microsoft/WindowsAzure/Storage/QueueMessage.php +87 -0
- app/libs/Microsoft/WindowsAzure/Storage/SignedIdentifier.php +78 -0
- app/libs/Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php +86 -0
- app/libs/Microsoft/WindowsAzure/Storage/Table.php +919 -0
- app/libs/Microsoft/WindowsAzure/Storage/TableEntity.php +344 -0
- app/libs/Microsoft/WindowsAzure/Storage/TableEntityQuery.php +363 -0
- app/libs/Microsoft/WindowsAzure/Storage/TableInstance.php +78 -0
- app/libs/aws/lib/requestcore/requestcore.class.php +81 -4
- app/libs/aws/sdk.class.php +71 -3
- app/libs/aws/services/as.class.php +6 -1
- app/libs/aws/services/cloudformation.class.php +6 -1
- app/libs/aws/services/cloudfront.class.php +11 -0
- app/libs/aws/services/cloudwatch.class.php +6 -1
- app/libs/aws/services/ec2.class.php +6 -1
- app/libs/aws/services/elasticbeanstalk.class.php +1 -1
- app/libs/aws/services/elb.class.php +6 -1
- app/libs/aws/services/emr.class.php +6 -1
- app/libs/aws/services/iam.class.php +1 -1
- app/libs/aws/services/importexport.class.php +1 -1
- app/libs/aws/services/rds.class.php +6 -1
- app/libs/aws/services/s3.class.php +33 -14
- app/libs/aws/services/sdb.class.php +6 -1
- app/libs/aws/services/ses.class.php +1 -1
- app/libs/aws/services/sns.class.php +23 -47
- app/libs/aws/services/sqs.class.php +29 -67
- app/list-tables.php +2 -0
- app/options-edit-job.php +27 -2
- app/options-save.php +65 -7
- backwpup.php +4 -3
- readme.txt +10 -2
app/backwpup_dojob.php
CHANGED
@@ -92,7 +92,7 @@ class backwpup_dojob {
|
|
92 |
$this->job_end($jobs[$this->jobid]['logfile']);
|
93 |
} else {
|
94 |
trigger_error(sprintf(__('Job %1$s already running!!!','backwpup'),$jobs[$this->jobid]['name']),E_USER_ERROR);
|
95 |
-
|
96 |
}
|
97 |
}
|
98 |
//Set job start settings
|
@@ -106,24 +106,26 @@ class backwpup_dojob {
|
|
106 |
$this->job=backwpup_check_job_vars($jobs[$this->jobid],$this->jobid);//Set and check job settings
|
107 |
//set waht to do
|
108 |
$this->todo=explode('+',$this->job['type']);
|
109 |
-
//set Backup File format
|
110 |
-
$this->backupfileformat=$this->job['fileformart'];
|
111 |
//set Temp Dir
|
112 |
$this->tempdir=trailingslashit($this->cfg['dirtemp']);
|
113 |
if (empty($this->tempdir) or $this->tempdir=='/')
|
114 |
$this->tempdir=backwpup_get_upload_dir();
|
115 |
-
//
|
116 |
-
|
117 |
-
|
118 |
-
$this->
|
119 |
-
|
120 |
-
|
121 |
-
if (
|
122 |
-
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
126 |
$this->backupfile=$this->job['fileprefix'].date_i18n('Y-m-d_H-i-s').$this->backupfileformat;
|
|
|
127 |
//check max script execution tme
|
128 |
if (ini_get('safe_mode') or strtolower(ini_get('safe_mode'))=='on' or ini_get('safe_mode')=='1')
|
129 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Max exec time is %1$d sec.','backwpup'),ini_get('max_execution_time')),E_USER_WARNING);
|
@@ -165,6 +167,8 @@ class backwpup_dojob {
|
|
165 |
$this->destination_s3();
|
166 |
if (in_array('RSC',$dests))
|
167 |
$this->destination_rsc();
|
|
|
|
|
168 |
$this->destination_dir();
|
169 |
}
|
170 |
|
@@ -1002,9 +1006,10 @@ class backwpup_dojob {
|
|
1002 |
}
|
1003 |
}
|
1004 |
|
1005 |
-
if (ftp_put($ftp_conn_id, $this->job['ftpdir'].$this->backupfile, $this->backupdir.$this->backupfile, FTP_BINARY))
|
1006 |
trigger_error(__('Backup File transferred to FTP Server:','backwpup').' '.$this->job['ftpdir'].$this->backupfile,E_USER_NOTICE);
|
1007 |
-
|
|
|
1008 |
trigger_error(__('Can not transfer backup to FTP server.','backwpup'),E_USER_ERROR);
|
1009 |
|
1010 |
if ($this->job['ftpmaxbackups']>0) { //Delete old backups
|
@@ -1238,7 +1243,7 @@ class backwpup_dojob {
|
|
1238 |
if ($backwpupcontainer->delete_object($this->job['rscdir'].$backupfilelist[$i])) //delte files on Cloud
|
1239 |
$numdeltefiles++;
|
1240 |
else
|
1241 |
-
trigger_error(__('Can not delete file on RSC://','backwpup').$this->job['rscContainer']
|
1242 |
}
|
1243 |
if ($numdeltefiles>0)
|
1244 |
trigger_error($numdeltefiles.' '.__('files deleted on Racspase Cloud Container!','backwpup'),E_USER_NOTICE);
|
@@ -1249,6 +1254,72 @@ class backwpup_dojob {
|
|
1249 |
}
|
1250 |
}
|
1251 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1252 |
|
1253 |
private function destination_dir() {
|
1254 |
if (empty($this->job['backupdir'])) //Go back if no destination dir
|
92 |
$this->job_end($jobs[$this->jobid]['logfile']);
|
93 |
} else {
|
94 |
trigger_error(sprintf(__('Job %1$s already running!!!','backwpup'),$jobs[$this->jobid]['name']),E_USER_ERROR);
|
95 |
+
$this->job_end();
|
96 |
}
|
97 |
}
|
98 |
//Set job start settings
|
106 |
$this->job=backwpup_check_job_vars($jobs[$this->jobid],$this->jobid);//Set and check job settings
|
107 |
//set waht to do
|
108 |
$this->todo=explode('+',$this->job['type']);
|
|
|
|
|
109 |
//set Temp Dir
|
110 |
$this->tempdir=trailingslashit($this->cfg['dirtemp']);
|
111 |
if (empty($this->tempdir) or $this->tempdir=='/')
|
112 |
$this->tempdir=backwpup_get_upload_dir();
|
113 |
+
//only for jos that makes backups
|
114 |
+
if (in_array('FILE',$this->todo) or in_array('DB',$this->todo) or in_array('WPEXP',$this->todo)) {
|
115 |
+
//set Backup File format
|
116 |
+
$this->backupfileformat=$this->job['fileformart'];
|
117 |
+
//set Backup Dir
|
118 |
+
$this->backupdir=$this->job['backupdir'];
|
119 |
+
if (empty($this->backupdir))
|
120 |
+
$this->backupdir=$this->tempdir;
|
121 |
+
//check backup dir
|
122 |
+
if ($this->backupdir!=backwpup_get_upload_dir()) {
|
123 |
+
if (!$this->_check_folders($this->backupdir))
|
124 |
+
return false;
|
125 |
+
}
|
126 |
+
//set Backup file Name
|
127 |
$this->backupfile=$this->job['fileprefix'].date_i18n('Y-m-d_H-i-s').$this->backupfileformat;
|
128 |
+
}
|
129 |
//check max script execution tme
|
130 |
if (ini_get('safe_mode') or strtolower(ini_get('safe_mode'))=='on' or ini_get('safe_mode')=='1')
|
131 |
trigger_error(sprintf(__('PHP Safe Mode is on!!! Max exec time is %1$d sec.','backwpup'),ini_get('max_execution_time')),E_USER_WARNING);
|
167 |
$this->destination_s3();
|
168 |
if (in_array('RSC',$dests))
|
169 |
$this->destination_rsc();
|
170 |
+
if (in_array('MSAZURE',$dests))
|
171 |
+
$this->destination_msazure();
|
172 |
$this->destination_dir();
|
173 |
}
|
174 |
|
1006 |
}
|
1007 |
}
|
1008 |
|
1009 |
+
if (ftp_put($ftp_conn_id, $this->job['ftpdir'].$this->backupfile, $this->backupdir.$this->backupfile, FTP_BINARY)) { //transfere file
|
1010 |
trigger_error(__('Backup File transferred to FTP Server:','backwpup').' '.$this->job['ftpdir'].$this->backupfile,E_USER_NOTICE);
|
1011 |
+
$this->lastbackupdownloadurl="ftp://".$this->job['ftpuser'].":".base64_decode($this->job['ftppass'])."@".$this->job['ftphost'].$this->job['ftpdir'].$this->backupfile;
|
1012 |
+
} else
|
1013 |
trigger_error(__('Can not transfer backup to FTP server.','backwpup'),E_USER_ERROR);
|
1014 |
|
1015 |
if ($this->job['ftpmaxbackups']>0) { //Delete old backups
|
1243 |
if ($backwpupcontainer->delete_object($this->job['rscdir'].$backupfilelist[$i])) //delte files on Cloud
|
1244 |
$numdeltefiles++;
|
1245 |
else
|
1246 |
+
trigger_error(__('Can not delete file on RSC://','backwpup').$this->job['rscContainer'].$this->job['rscdir'].$backupfilelist[$i],E_USER_ERROR);
|
1247 |
}
|
1248 |
if ($numdeltefiles>0)
|
1249 |
trigger_error($numdeltefiles.' '.__('files deleted on Racspase Cloud Container!','backwpup'),E_USER_NOTICE);
|
1254 |
}
|
1255 |
}
|
1256 |
|
1257 |
+
private function destination_msazure() {
|
1258 |
+
|
1259 |
+
if (empty($this->job['msazureHost']) or empty($this->job['msazureAccName']) or empty($this->job['msazureKey']) or empty($this->job['msazureContainer']))
|
1260 |
+
return;
|
1261 |
+
|
1262 |
+
if (!(extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll'))) {
|
1263 |
+
trigger_error(__('Can not load curl extension is needed for Microsoft Azure!','backwpup'),E_USER_ERROR);
|
1264 |
+
return;
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob')) {
|
1268 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
1269 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
1270 |
+
}
|
1271 |
+
|
1272 |
+
try {
|
1273 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($this->job['msazureHost'],$this->job['msazureAccName'],$this->job['msazureKey']);
|
1274 |
+
|
1275 |
+
if(!$storageClient->containerExists($this->job['msazureContainer'])) {
|
1276 |
+
trigger_error(__('Microsoft Azure Container not exists:','backwpup').' '.$this->job['msazureContainer'],E_USER_ERROR);
|
1277 |
+
return;
|
1278 |
+
} else {
|
1279 |
+
trigger_error(__('Connected to Microsoft Azure Container:','backwpup').' '.$this->job['msazureContainer'],E_USER_NOTICE);
|
1280 |
+
}
|
1281 |
+
|
1282 |
+
if (filesize($this->backupdir.$this->backupfile)<Microsoft_WindowsAzure_Storage_Blob::MAX_BLOB_SIZE) { //for files bigger tha 64MB
|
1283 |
+
$result = $storageClient->putBlob($this->job['msazureContainer'], $this->job['msazuredir'].$this->backupfile, $this->backupdir.$this->backupfile);
|
1284 |
+
} else {
|
1285 |
+
$result = $storageClient->putLargeBlob($this->job['msazureContainer'], $this->job['msazuredir'].$this->backupfile, $this->backupdir.$this->backupfile);
|
1286 |
+
}
|
1287 |
+
|
1288 |
+
if ($result->Name==$this->job['msazuredir'].$this->backupfile) {
|
1289 |
+
trigger_error(__('Backup File transferred to azure://','backwpup').$this->job['msazuredir'].$this->backupfile,E_USER_NOTICE);
|
1290 |
+
$this->lastbackupdownloadurl='admin.php?page=BackWPup&subpage=backups&action=downloadmsazure&file='.$this->job['msazuredir'].$this->backupfile.'&jobid='.$this->jobid;
|
1291 |
+
} else {
|
1292 |
+
trigger_error(__('Can not transfer backup to Microsoft Azure.','backwpup'),E_USER_ERROR);
|
1293 |
+
}
|
1294 |
+
|
1295 |
+
if ($this->job['msazuremaxbackups']>0) { //Delete old backups
|
1296 |
+
$backupfilelist=array();
|
1297 |
+
$blobs = $storageClient->listBlobs($this->job['msazureContainer'],$this->job['msazuredir']);
|
1298 |
+
if (is_array($blobs)) {
|
1299 |
+
foreach ($blobs as $blob) {
|
1300 |
+
$file=basename($blob->Name);
|
1301 |
+
if ($this->job['msazuredir'].$file == $blob->Name) {//only in the folder and not in complete bucket
|
1302 |
+
if ($this->job['fileprefix'] == substr($file,0,strlen($this->job['fileprefix'])) and $this->backupfileformat == substr($file,-strlen($this->backupfileformat)))
|
1303 |
+
$backupfilelist[]=$file;
|
1304 |
+
}
|
1305 |
+
}
|
1306 |
+
}
|
1307 |
+
if (sizeof($backupfilelist)>0) {
|
1308 |
+
rsort($backupfilelist);
|
1309 |
+
$numdeltefiles=0;
|
1310 |
+
for ($i=$this->job['msazuremaxbackups'];$i<sizeof($backupfilelist);$i++) {
|
1311 |
+
$storageClient->deleteBlob($this->job['msazureContainer'],$this->job['msazuredir'].$backupfilelist[$i]); //delte files on Cloud
|
1312 |
+
$numdeltefiles++;
|
1313 |
+
}
|
1314 |
+
if ($numdeltefiles>0)
|
1315 |
+
trigger_error($numdeltefiles.' '.__('files deleted on Microsoft Azure Container!','backwpup'),E_USER_NOTICE);
|
1316 |
+
}
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
} catch (Exception $e) {
|
1320 |
+
trigger_error(__('Microsoft Azure API:','backwpup').' '.__($e->getMessage(),'backwpup'),E_USER_ERROR);
|
1321 |
+
}
|
1322 |
+
}
|
1323 |
|
1324 |
private function destination_dir() {
|
1325 |
if (empty($this->job['backupdir'])) //Go back if no destination dir
|
app/functions5.php
CHANGED
@@ -217,7 +217,28 @@ function backwpup_check_job_vars($jobsettings,$jobid='') {
|
|
217 |
|
218 |
if (!isset($jobsettings['awsmaxbackups']) or !is_int($jobsettings['awsmaxbackups']))
|
219 |
$jobsettings['awsmaxbackups']=0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
220 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
221 |
if (!isset($jobsettings['rscUsername']) or !is_string($jobsettings['rscUsername']))
|
222 |
$jobsettings['rscUsername']='';
|
223 |
|
@@ -264,6 +285,9 @@ function backwpup_get_backup_files($onlyjobid='') {
|
|
264 |
$files=array();
|
265 |
$donefolders=array();
|
266 |
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
|
|
|
|
|
|
267 |
if (!class_exists('CFRuntime'))
|
268 |
require_once(dirname(__FILE__).'/libs/aws/sdk.class.php');
|
269 |
if (!class_exists('CF_Authentication'))
|
@@ -320,6 +344,28 @@ function backwpup_get_backup_files($onlyjobid='') {
|
|
320 |
$donefolders[]=$jobvalue['awsAccessKey'].'|'.$jobvalue['awsBucket'].'|'.$jobvalue['awsdir'];
|
321 |
}
|
322 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
323 |
//Get files/filinfo from RSC
|
324 |
if (class_exists('CF_Authentication') and in_array('RSC',$dests) and !in_array($jobvalue['rscUsername'].'|'.$jobvalue['rscContainer'].'|'.$jobvalue['rscdir'],$donefolders)) {
|
325 |
if (!empty($jobvalue['rscUsername']) and !empty($jobvalue['rscAPIKey']) and !empty($jobvalue['rscContainer'])) {
|
@@ -382,10 +428,7 @@ function backwpup_get_backup_files($onlyjobid='') {
|
|
382 |
$files[$filecounter]['filename']=basename($ftpfiles);
|
383 |
$files[$filecounter]['downloadurl']="ftp://".$jobvalue['ftpuser'].":".base64_decode($jobvalue['ftppass'])."@".$jobvalue['ftphost'].$ftpfiles;
|
384 |
$files[$filecounter]['filesize']=ftp_size($ftp_conn_id,$ftpfiles);
|
385 |
-
|
386 |
-
$filnameparts=explode('_',substr(basename($ftpfiles),0,strpos(basename($ftpfiles),'.')));
|
387 |
-
$files[$filecounter]['time']=strtotime($filnameparts[2].' '.str_replace('-',':',$filnameparts[3]));
|
388 |
-
}
|
389 |
$filecounter++;
|
390 |
}
|
391 |
}
|
@@ -428,11 +471,18 @@ function backwpup_get_aws_buckets($args='') {
|
|
428 |
else
|
429 |
return;
|
430 |
}
|
431 |
-
|
432 |
-
|
433 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
434 |
if ($buckets->status!=200) {
|
435 |
-
echo '<span id="awsBucket" style="color:red;">'.__('No Buckets found!
|
436 |
if ($ajax)
|
437 |
die();
|
438 |
else
|
@@ -477,9 +527,9 @@ function backwpup_get_rsc_container($args='') {
|
|
477 |
else
|
478 |
return;
|
479 |
}
|
480 |
-
$auth = new CF_Authentication($rscUsername, $rscAPIKey);
|
481 |
|
482 |
try {
|
|
|
483 |
$auth->authenticate();
|
484 |
$conn = new CF_Connection($auth);
|
485 |
$containers=$conn->get_containers();
|
@@ -507,5 +557,70 @@ function backwpup_get_rsc_container($args='') {
|
|
507 |
die();
|
508 |
else
|
509 |
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
510 |
}
|
511 |
?>
|
217 |
|
218 |
if (!isset($jobsettings['awsmaxbackups']) or !is_int($jobsettings['awsmaxbackups']))
|
219 |
$jobsettings['awsmaxbackups']=0;
|
220 |
+
|
221 |
+
if (!isset($jobsettings['msazureHost']) or !is_string($jobsettings['msazureHost']))
|
222 |
+
$jobsettings['msazureHost']='blob.core.windows.net';
|
223 |
+
|
224 |
+
if (!isset($jobsettings['msazureAccName']) or !is_string($jobsettings['msazureAccName']))
|
225 |
+
$jobsettings['msazureAccName']='';
|
226 |
+
|
227 |
+
if (!isset($jobsettings['msazureKey']) or !is_string($jobsettings['msazureKey']))
|
228 |
+
$jobsettings['msazureKey']='';
|
229 |
+
|
230 |
+
if (!isset($jobsettings['msazureContainer']) or !is_string($jobsettings['msazureContainer']))
|
231 |
+
$jobsettings['msazureContainer']='';
|
232 |
|
233 |
+
if (!isset($jobsettings['msazuredir']) or !is_string($jobsettings['msazuredir']) or $jobsettings['msazuredir']=='/')
|
234 |
+
$jobsettings['msazuredir']='';
|
235 |
+
$jobsettings['msazuredir']=trailingslashit(str_replace('//','/',str_replace('\\','/',trim($jobsettings['msazuredir']))));
|
236 |
+
if (substr($jobsettings['msazuredir'],0,1)=='/')
|
237 |
+
$jobsettings['msazuredir']=substr($jobsettings['msazuredir'],1);
|
238 |
+
|
239 |
+
if (!isset($jobsettings['msazuremaxbackups']) or !is_int($jobsettings['msazuremaxbackups']))
|
240 |
+
$jobsettings['msazuremaxbackups']=0;
|
241 |
+
|
242 |
if (!isset($jobsettings['rscUsername']) or !is_string($jobsettings['rscUsername']))
|
243 |
$jobsettings['rscUsername']='';
|
244 |
|
285 |
$files=array();
|
286 |
$donefolders=array();
|
287 |
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
288 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
289 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob'))
|
290 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
291 |
if (!class_exists('CFRuntime'))
|
292 |
require_once(dirname(__FILE__).'/libs/aws/sdk.class.php');
|
293 |
if (!class_exists('CF_Authentication'))
|
344 |
$donefolders[]=$jobvalue['awsAccessKey'].'|'.$jobvalue['awsBucket'].'|'.$jobvalue['awsdir'];
|
345 |
}
|
346 |
}
|
347 |
+
//Get files/filinfo from Microsoft Azure
|
348 |
+
if (class_exists('Microsoft_WindowsAzure_Storage_Blob') and in_array('MSAZURE',$dests) and !in_array($jobvalue['msazureAccName'].'|'.$jobvalue['msazureKey'].'|'.$jobvalue['msazureContainer'].'|'.$jobvalue['msazuredir'],$donefolders)) {
|
349 |
+
if (!empty($jobvalue['msazureHost']) and !empty($jobvalue['msazureAccName']) and !empty($jobvalue['msazureKey']) and !empty($jobvalue['msazureContainer'])) {
|
350 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($jobvalue['msazureHost'],$jobvalue['msazureAccName'],$jobvalue['msazureKey']);
|
351 |
+
$blobs = $storageClient->listBlobs($jobvalue['msazureContainer'],$jobvalue['msazuredir']);
|
352 |
+
if (is_array($blobs)) {
|
353 |
+
foreach ($blobs as $blob) {
|
354 |
+
if (strtolower(substr($blob->Name,-4))=='.zip' or strtolower(substr($blob->Name,-4))=='.tar' or strtolower(substr($blob->Name,-7))=='.tar.gz' or strtolower(substr($blob->Name,-8))=='.tar.bz2') {
|
355 |
+
$files[$filecounter]['type']='MSAZURE';
|
356 |
+
$files[$filecounter]['jobid']=$jobid;
|
357 |
+
$files[$filecounter]['file']=$blob->Name;
|
358 |
+
$files[$filecounter]['filename']=basename($blob->Name);
|
359 |
+
$files[$filecounter]['downloadurl']='admin.php?page=BackWPup&subpage=backups&action=downloadmsazure&file='.$blob->Name.'&jobid='.$jobid;
|
360 |
+
$files[$filecounter]['filesize']=$blob->size;
|
361 |
+
$files[$filecounter]['time']=strtotime($blob->lastmodified);
|
362 |
+
$filecounter++;
|
363 |
+
}
|
364 |
+
}
|
365 |
+
}
|
366 |
+
$donefolders[]=$jobvalue['msazureAccName'].'|'.$jobvalue['msazureKey'].'|'.$jobvalue['msazureContainer'].'|'.$jobvalue['msazuredir'];
|
367 |
+
}
|
368 |
+
}
|
369 |
//Get files/filinfo from RSC
|
370 |
if (class_exists('CF_Authentication') and in_array('RSC',$dests) and !in_array($jobvalue['rscUsername'].'|'.$jobvalue['rscContainer'].'|'.$jobvalue['rscdir'],$donefolders)) {
|
371 |
if (!empty($jobvalue['rscUsername']) and !empty($jobvalue['rscAPIKey']) and !empty($jobvalue['rscContainer'])) {
|
428 |
$files[$filecounter]['filename']=basename($ftpfiles);
|
429 |
$files[$filecounter]['downloadurl']="ftp://".$jobvalue['ftpuser'].":".base64_decode($jobvalue['ftppass'])."@".$jobvalue['ftphost'].$ftpfiles;
|
430 |
$files[$filecounter]['filesize']=ftp_size($ftp_conn_id,$ftpfiles);
|
431 |
+
$files[$filecounter]['time']=ftp_mdtm($ftp_conn_id,$ftpfiles);
|
|
|
|
|
|
|
432 |
$filecounter++;
|
433 |
}
|
434 |
}
|
471 |
else
|
472 |
return;
|
473 |
}
|
474 |
+
try {
|
475 |
+
$s3 = new AmazonS3($awsAccessKey, $awsSecretKey);
|
476 |
+
$buckets=$s3->list_buckets();
|
477 |
+
} catch (Exception $e) {
|
478 |
+
echo '<span id="awsBucket" style="color:red;">'.__($e->getMessage(),'backwpup').'</span>';
|
479 |
+
if ($ajax)
|
480 |
+
die();
|
481 |
+
else
|
482 |
+
return;
|
483 |
+
}
|
484 |
if ($buckets->status!=200) {
|
485 |
+
echo '<span id="awsBucket" style="color:red;">'.__('No Buckets found!','backwpup').'</span>';
|
486 |
if ($ajax)
|
487 |
die();
|
488 |
else
|
527 |
else
|
528 |
return;
|
529 |
}
|
|
|
530 |
|
531 |
try {
|
532 |
+
$auth = new CF_Authentication($rscUsername, $rscAPIKey);
|
533 |
$auth->authenticate();
|
534 |
$conn = new CF_Connection($auth);
|
535 |
$containers=$conn->get_containers();
|
557 |
die();
|
558 |
else
|
559 |
return;
|
560 |
+
}
|
561 |
+
|
562 |
+
//ajax/normal get buckests select box
|
563 |
+
function backwpup_get_msazure_container($args='') {
|
564 |
+
if (is_array($args)) {
|
565 |
+
extract($args);
|
566 |
+
$ajax=false;
|
567 |
+
} else {
|
568 |
+
$msazureHost=$_POST['msazureHost'];
|
569 |
+
$msazureAccName=$_POST['msazureAccName'];
|
570 |
+
$msazureKey=$_POST['msazureKey'];
|
571 |
+
$msazureselected=$_POST['msazureselected'];
|
572 |
+
$ajax=true;
|
573 |
+
}
|
574 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob')) {
|
575 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
576 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
577 |
+
}
|
578 |
+
if (empty($msazureHost)) {
|
579 |
+
echo '<span id="msazureContainer" style="color:red;">'.__('Missing Hostname!','backwpup').'</span>';
|
580 |
+
if ($ajax)
|
581 |
+
die();
|
582 |
+
else
|
583 |
+
return;
|
584 |
+
}
|
585 |
+
if (empty($msazureAccName)) {
|
586 |
+
echo '<span id="msazureContainer" style="color:red;">'.__('Missing Account Name!','backwpup').'</span>';
|
587 |
+
if ($ajax)
|
588 |
+
die();
|
589 |
+
else
|
590 |
+
return;
|
591 |
+
}
|
592 |
+
if (empty($msazureKey)) {
|
593 |
+
echo '<span id="msazureContainer" style="color:red;">'.__('Missing Access Key!','backwpup').'</span>';
|
594 |
+
if ($ajax)
|
595 |
+
die();
|
596 |
+
else
|
597 |
+
return;
|
598 |
+
}
|
599 |
+
try {
|
600 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($msazureHost,$msazureAccName,$msazureKey);
|
601 |
+
$Containers=$storageClient->listContainers();
|
602 |
+
} catch (Exception $e) {
|
603 |
+
echo '<span id="msazureContainer" style="color:red;">'.$e->getMessage().'</span>';
|
604 |
+
if ($ajax)
|
605 |
+
die();
|
606 |
+
else
|
607 |
+
return;
|
608 |
+
}
|
609 |
+
if (empty($Containers)) {
|
610 |
+
echo '<span id="msazureContainer" style="color:red;">'.__('No Container found!','backwpup').'</span>';
|
611 |
+
if ($ajax)
|
612 |
+
die();
|
613 |
+
else
|
614 |
+
return;
|
615 |
+
}
|
616 |
+
echo '<select name="msazureContainer" id="msazureContainer">';
|
617 |
+
foreach ($Containers as $Container) {
|
618 |
+
echo "<option ".selected(strtolower($msazureselected),strtolower($Container->Name),false).">".$Container->Name."</option>";
|
619 |
+
}
|
620 |
+
echo '</select>';
|
621 |
+
if ($ajax)
|
622 |
+
die();
|
623 |
+
else
|
624 |
+
return;
|
625 |
}
|
626 |
?>
|
app/js/options.js
CHANGED
@@ -5,14 +5,18 @@ jQuery(document).ready( function($) {
|
|
5 |
$('#fileformart').show();
|
6 |
$('#toftp').show();
|
7 |
$('#toamazon').show();
|
|
|
8 |
$('#torsc').show();
|
|
|
9 |
$('#todir').show();
|
10 |
$('#tomail').show();
|
11 |
} else {
|
12 |
$('#fileformart').hide();
|
13 |
$('#toftp').hide();
|
14 |
$('#toamazon').hide();
|
|
|
15 |
$('#torsc').hide();
|
|
|
16 |
$('#todir').hide();
|
17 |
$('#tomail').hide();
|
18 |
}
|
@@ -66,6 +70,28 @@ jQuery(document).ready( function($) {
|
|
66 |
$('#awsAccessKey').change(function() {awsgetbucket();});
|
67 |
$('#awsSecretKey').change(function() {awsgetbucket();});
|
68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
69 |
function rscgetcontainer() {
|
70 |
var rscUsername = $('#rscUsername').val();
|
71 |
var rscAPIKey = $('#rscAPIKey').val();
|
5 |
$('#fileformart').show();
|
6 |
$('#toftp').show();
|
7 |
$('#toamazon').show();
|
8 |
+
$('#tomsazure').show();
|
9 |
$('#torsc').show();
|
10 |
+
$('#todropbox').show();
|
11 |
$('#todir').show();
|
12 |
$('#tomail').show();
|
13 |
} else {
|
14 |
$('#fileformart').hide();
|
15 |
$('#toftp').hide();
|
16 |
$('#toamazon').hide();
|
17 |
+
$('#tomsazure').hide();
|
18 |
$('#torsc').hide();
|
19 |
+
$('#todropbox').hide();
|
20 |
$('#todir').hide();
|
21 |
$('#tomail').hide();
|
22 |
}
|
70 |
$('#awsAccessKey').change(function() {awsgetbucket();});
|
71 |
$('#awsSecretKey').change(function() {awsgetbucket();});
|
72 |
|
73 |
+
function msazuregetcontainer() {
|
74 |
+
var msazureHost = $('#msazureHost').val();
|
75 |
+
var msazureAccName = $('#msazureAccName').val();
|
76 |
+
var msazureKey = $('#msazureKey').val();
|
77 |
+
var msazureContainer = $('#msazureContainerselected').val();
|
78 |
+
var data = {
|
79 |
+
action: 'backwpup_get_msazure_container',
|
80 |
+
msazureHost: msazureHost,
|
81 |
+
msazureAccName: msazureAccName,
|
82 |
+
msazureKey: msazureKey,
|
83 |
+
msazureselected: msazureContainer
|
84 |
+
};
|
85 |
+
$.post(ajaxurl, data, function(response) {
|
86 |
+
$('#msazureContainer').remove();
|
87 |
+
$('#msazureContainerselected').after(response);
|
88 |
+
});
|
89 |
+
}
|
90 |
+
|
91 |
+
$('#msazureHost').change(function() {msazuregetcontainer();});
|
92 |
+
$('#msazureAccName').change(function() {msazuregetcontainer();});
|
93 |
+
$('#msazureKey').change(function() {msazuregetcontainer();});
|
94 |
+
|
95 |
function rscgetcontainer() {
|
96 |
var rscUsername = $('#rscUsername').val();
|
97 |
var rscAPIKey = $('#rscAPIKey').val();
|
app/libs/Microsoft/Exception.php
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft
|
30 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
31 |
+
* @license http://phpazure.codeplex.com/license
|
32 |
+
*/
|
33 |
+
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @category Microsoft
|
37 |
+
* @package Microsoft
|
38 |
+
* @subpackage Exception
|
39 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
40 |
+
* @license http://phpazure.codeplex.com/license
|
41 |
+
*/
|
42 |
+
class Microsoft_Exception extends Exception
|
43 |
+
{}
|
app/libs/Microsoft/Http/Client.php
ADDED
@@ -0,0 +1,1444 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client
|
19 |
+
* @version $Id: Client.php 19661 2009-12-15 18:03:07Z matthew $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @see Microsoft_Uri
|
27 |
+
*/
|
28 |
+
require_once 'Microsoft/Uri.php';
|
29 |
+
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @see Microsoft_Http_Client_Adapter_Interface
|
33 |
+
*/
|
34 |
+
require_once 'Microsoft/Http/Client/Adapter/Interface.php';
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @see Microsoft_Http_Response
|
39 |
+
*/
|
40 |
+
require_once 'Microsoft/Http/Response.php';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @see Microsoft_Http_Response_Stream
|
44 |
+
*/
|
45 |
+
require_once 'Microsoft/Http/Response/Stream.php';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Microsoft_Http_Client is an implemetation of an HTTP client in PHP. The client
|
49 |
+
* supports basic features like sending different HTTP requests and handling
|
50 |
+
* redirections, as well as more advanced features like proxy settings, HTTP
|
51 |
+
* authentication and cookie persistance (using a Microsoft_Http_CookieJar object)
|
52 |
+
*
|
53 |
+
* @todo Implement proxy settings
|
54 |
+
* @category Microsoft
|
55 |
+
* @package Microsoft_Http
|
56 |
+
* @subpackage Client
|
57 |
+
* @throws Microsoft_Http_Client_Exception
|
58 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
59 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
60 |
+
*/
|
61 |
+
class Microsoft_Http_Client
|
62 |
+
{
|
63 |
+
/**
|
64 |
+
* HTTP request methods
|
65 |
+
*/
|
66 |
+
const GET = 'GET';
|
67 |
+
const POST = 'POST';
|
68 |
+
const PUT = 'PUT';
|
69 |
+
const HEAD = 'HEAD';
|
70 |
+
const DELETE = 'DELETE';
|
71 |
+
const TRACE = 'TRACE';
|
72 |
+
const OPTIONS = 'OPTIONS';
|
73 |
+
const CONNECT = 'CONNECT';
|
74 |
+
const MERGE = 'MERGE';
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Supported HTTP Authentication methods
|
78 |
+
*/
|
79 |
+
const AUTH_BASIC = 'basic';
|
80 |
+
//const AUTH_DIGEST = 'digest'; <-- not implemented yet
|
81 |
+
|
82 |
+
/**
|
83 |
+
* HTTP protocol versions
|
84 |
+
*/
|
85 |
+
const HTTP_1 = '1.1';
|
86 |
+
const HTTP_0 = '1.0';
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Content attributes
|
90 |
+
*/
|
91 |
+
const CONTENT_TYPE = 'Content-Type';
|
92 |
+
const CONTENT_LENGTH = 'Content-Length';
|
93 |
+
|
94 |
+
/**
|
95 |
+
* POST data encoding methods
|
96 |
+
*/
|
97 |
+
const ENC_URLENCODED = 'application/x-www-form-urlencoded';
|
98 |
+
const ENC_FORMDATA = 'multipart/form-data';
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Configuration array, set using the constructor or using ::setConfig()
|
102 |
+
*
|
103 |
+
* @var array
|
104 |
+
*/
|
105 |
+
protected $config = array(
|
106 |
+
'maxredirects' => 5,
|
107 |
+
'strictredirects' => false,
|
108 |
+
'useragent' => 'Microsoft_Http_Client',
|
109 |
+
'timeout' => 10,
|
110 |
+
'adapter' => 'Microsoft_Http_Client_Adapter_Socket',
|
111 |
+
'httpversion' => self::HTTP_1,
|
112 |
+
'keepalive' => false,
|
113 |
+
'storeresponse' => true,
|
114 |
+
'strict' => true,
|
115 |
+
'output_stream' => false,
|
116 |
+
);
|
117 |
+
|
118 |
+
/**
|
119 |
+
* The adapter used to preform the actual connection to the server
|
120 |
+
*
|
121 |
+
* @var Microsoft_Http_Client_Adapter_Interface
|
122 |
+
*/
|
123 |
+
protected $adapter = null;
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Request URI
|
127 |
+
*
|
128 |
+
* @var Microsoft_Uri_Http
|
129 |
+
*/
|
130 |
+
protected $uri = null;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Associative array of request headers
|
134 |
+
*
|
135 |
+
* @var array
|
136 |
+
*/
|
137 |
+
protected $headers = array();
|
138 |
+
|
139 |
+
/**
|
140 |
+
* HTTP request method
|
141 |
+
*
|
142 |
+
* @var string
|
143 |
+
*/
|
144 |
+
protected $method = self::GET;
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Associative array of GET parameters
|
148 |
+
*
|
149 |
+
* @var array
|
150 |
+
*/
|
151 |
+
protected $paramsGet = array();
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Assiciative array of POST parameters
|
155 |
+
*
|
156 |
+
* @var array
|
157 |
+
*/
|
158 |
+
protected $paramsPost = array();
|
159 |
+
|
160 |
+
/**
|
161 |
+
* Request body content type (for POST requests)
|
162 |
+
*
|
163 |
+
* @var string
|
164 |
+
*/
|
165 |
+
protected $enctype = null;
|
166 |
+
|
167 |
+
/**
|
168 |
+
* The raw post data to send. Could be set by setRawData($data, $enctype).
|
169 |
+
*
|
170 |
+
* @var string
|
171 |
+
*/
|
172 |
+
protected $raw_post_data = null;
|
173 |
+
|
174 |
+
/**
|
175 |
+
* HTTP Authentication settings
|
176 |
+
*
|
177 |
+
* Expected to be an associative array with this structure:
|
178 |
+
* $this->auth = array('user' => 'username', 'password' => 'password', 'type' => 'basic')
|
179 |
+
* Where 'type' should be one of the supported authentication types (see the AUTH_*
|
180 |
+
* constants), for example 'basic' or 'digest'.
|
181 |
+
*
|
182 |
+
* If null, no authentication will be used.
|
183 |
+
*
|
184 |
+
* @var array|null
|
185 |
+
*/
|
186 |
+
protected $auth;
|
187 |
+
|
188 |
+
/**
|
189 |
+
* File upload arrays (used in POST requests)
|
190 |
+
*
|
191 |
+
* An associative array, where each element is of the format:
|
192 |
+
* 'name' => array('filename.txt', 'text/plain', 'This is the actual file contents')
|
193 |
+
*
|
194 |
+
* @var array
|
195 |
+
*/
|
196 |
+
protected $files = array();
|
197 |
+
|
198 |
+
/**
|
199 |
+
* The client's cookie jar
|
200 |
+
*
|
201 |
+
* @var Microsoft_Http_CookieJar
|
202 |
+
*/
|
203 |
+
protected $cookiejar = null;
|
204 |
+
|
205 |
+
/**
|
206 |
+
* The last HTTP request sent by the client, as string
|
207 |
+
*
|
208 |
+
* @var string
|
209 |
+
*/
|
210 |
+
protected $last_request = null;
|
211 |
+
|
212 |
+
/**
|
213 |
+
* The last HTTP response received by the client
|
214 |
+
*
|
215 |
+
* @var Microsoft_Http_Response
|
216 |
+
*/
|
217 |
+
protected $last_response = null;
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Redirection counter
|
221 |
+
*
|
222 |
+
* @var int
|
223 |
+
*/
|
224 |
+
protected $redirectCounter = 0;
|
225 |
+
|
226 |
+
/**
|
227 |
+
* Fileinfo magic database resource
|
228 |
+
*
|
229 |
+
* This varaiable is populated the first time _detectFileMimeType is called
|
230 |
+
* and is then reused on every call to this method
|
231 |
+
*
|
232 |
+
* @var resource
|
233 |
+
*/
|
234 |
+
static protected $_fileInfoDb = null;
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Contructor method. Will create a new HTTP client. Accepts the target
|
238 |
+
* URL and optionally configuration array.
|
239 |
+
*
|
240 |
+
* @param Microsoft_Uri_Http|string $uri
|
241 |
+
* @param array $config Configuration key-value pairs.
|
242 |
+
*/
|
243 |
+
public function __construct($uri = null, $config = null)
|
244 |
+
{
|
245 |
+
if ($uri !== null) {
|
246 |
+
$this->setUri($uri);
|
247 |
+
}
|
248 |
+
if ($config !== null) {
|
249 |
+
$this->setConfig($config);
|
250 |
+
}
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Set the URI for the next request
|
255 |
+
*
|
256 |
+
* @param Microsoft_Uri_Http|string $uri
|
257 |
+
* @return Microsoft_Http_Client
|
258 |
+
* @throws Microsoft_Http_Client_Exception
|
259 |
+
*/
|
260 |
+
public function setUri($uri)
|
261 |
+
{
|
262 |
+
if (is_string($uri)) {
|
263 |
+
$uri = Microsoft_Uri::factory($uri);
|
264 |
+
}
|
265 |
+
|
266 |
+
if (!$uri instanceof Microsoft_Uri_Http) {
|
267 |
+
/** @see Microsoft_Http_Client_Exception */
|
268 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
269 |
+
throw new Microsoft_Http_Client_Exception('Passed parameter is not a valid HTTP URI.');
|
270 |
+
}
|
271 |
+
|
272 |
+
// Set auth if username and password has been specified in the uri
|
273 |
+
if ($uri->getUsername() && $uri->getPassword()) {
|
274 |
+
$this->setAuth($uri->getUsername(), $uri->getPassword());
|
275 |
+
}
|
276 |
+
|
277 |
+
// We have no ports, set the defaults
|
278 |
+
if (! $uri->getPort()) {
|
279 |
+
$uri->setPort(($uri->getScheme() == 'https' ? 443 : 80));
|
280 |
+
}
|
281 |
+
|
282 |
+
$this->uri = $uri;
|
283 |
+
|
284 |
+
return $this;
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* Get the URI for the next request
|
289 |
+
*
|
290 |
+
* @param boolean $as_string If true, will return the URI as a string
|
291 |
+
* @return Microsoft_Uri_Http|string
|
292 |
+
*/
|
293 |
+
public function getUri($as_string = false)
|
294 |
+
{
|
295 |
+
if ($as_string && $this->uri instanceof Microsoft_Uri_Http) {
|
296 |
+
return $this->uri->__toString();
|
297 |
+
} else {
|
298 |
+
return $this->uri;
|
299 |
+
}
|
300 |
+
}
|
301 |
+
|
302 |
+
/**
|
303 |
+
* Set configuration parameters for this HTTP client
|
304 |
+
*
|
305 |
+
* @param Microsoft_Config | array $config
|
306 |
+
* @return Microsoft_Http_Client
|
307 |
+
* @throws Microsoft_Http_Client_Exception
|
308 |
+
*/
|
309 |
+
public function setConfig($config = array())
|
310 |
+
{
|
311 |
+
if ($config instanceof Microsoft_Config) {
|
312 |
+
$config = $config->toArray();
|
313 |
+
|
314 |
+
} elseif (! is_array($config)) {
|
315 |
+
/** @see Microsoft_Http_Client_Exception */
|
316 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
317 |
+
throw new Microsoft_Http_Client_Exception('Array expected, got ' . gettype($config));
|
318 |
+
}
|
319 |
+
|
320 |
+
foreach ($config as $k => $v) {
|
321 |
+
$this->config[strtolower($k)] = $v;
|
322 |
+
}
|
323 |
+
|
324 |
+
// Pass configuration options to the adapter if it exists
|
325 |
+
if ($this->adapter instanceof Microsoft_Http_Client_Adapter_Interface) {
|
326 |
+
$this->adapter->setConfig($config);
|
327 |
+
}
|
328 |
+
|
329 |
+
return $this;
|
330 |
+
}
|
331 |
+
|
332 |
+
/**
|
333 |
+
* Set the next request's method
|
334 |
+
*
|
335 |
+
* Validated the passed method and sets it. If we have files set for
|
336 |
+
* POST requests, and the new method is not POST, the files are silently
|
337 |
+
* dropped.
|
338 |
+
*
|
339 |
+
* @param string $method
|
340 |
+
* @return Microsoft_Http_Client
|
341 |
+
* @throws Microsoft_Http_Client_Exception
|
342 |
+
*/
|
343 |
+
public function setMethod($method = self::GET)
|
344 |
+
{
|
345 |
+
if (! preg_match('/^[^\x00-\x1f\x7f-\xff\(\)<>@,;:\\\\"\/\[\]\?={}\s]+$/', $method)) {
|
346 |
+
/** @see Microsoft_Http_Client_Exception */
|
347 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
348 |
+
throw new Microsoft_Http_Client_Exception("'{$method}' is not a valid HTTP request method.");
|
349 |
+
}
|
350 |
+
|
351 |
+
if ($method == self::POST && $this->enctype === null) {
|
352 |
+
$this->setEncType(self::ENC_URLENCODED);
|
353 |
+
}
|
354 |
+
|
355 |
+
$this->method = $method;
|
356 |
+
|
357 |
+
return $this;
|
358 |
+
}
|
359 |
+
|
360 |
+
/**
|
361 |
+
* Set one or more request headers
|
362 |
+
*
|
363 |
+
* This function can be used in several ways to set the client's request
|
364 |
+
* headers:
|
365 |
+
* 1. By providing two parameters: $name as the header to set (eg. 'Host')
|
366 |
+
* and $value as it's value (eg. 'www.example.com').
|
367 |
+
* 2. By providing a single header string as the only parameter
|
368 |
+
* eg. 'Host: www.example.com'
|
369 |
+
* 3. By providing an array of headers as the first parameter
|
370 |
+
* eg. array('host' => 'www.example.com', 'x-foo: bar'). In This case
|
371 |
+
* the function will call itself recursively for each array item.
|
372 |
+
*
|
373 |
+
* @param string|array $name Header name, full header string ('Header: value')
|
374 |
+
* or an array of headers
|
375 |
+
* @param mixed $value Header value or null
|
376 |
+
* @return Microsoft_Http_Client
|
377 |
+
* @throws Microsoft_Http_Client_Exception
|
378 |
+
*/
|
379 |
+
public function setHeaders($name, $value = null)
|
380 |
+
{
|
381 |
+
// If we got an array, go recusive!
|
382 |
+
if (is_array($name)) {
|
383 |
+
foreach ($name as $k => $v) {
|
384 |
+
if (is_string($k)) {
|
385 |
+
$this->setHeaders($k, $v);
|
386 |
+
} else {
|
387 |
+
$this->setHeaders($v, null);
|
388 |
+
}
|
389 |
+
}
|
390 |
+
} else {
|
391 |
+
// Check if $name needs to be split
|
392 |
+
if ($value === null && (strpos($name, ':') > 0)) {
|
393 |
+
list($name, $value) = explode(':', $name, 2);
|
394 |
+
}
|
395 |
+
|
396 |
+
// Make sure the name is valid if we are in strict mode
|
397 |
+
if ($this->config['strict'] && (! preg_match('/^[a-zA-Z0-9-]+$/', $name))) {
|
398 |
+
/** @see Microsoft_Http_Client_Exception */
|
399 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
400 |
+
throw new Microsoft_Http_Client_Exception("{$name} is not a valid HTTP header name");
|
401 |
+
}
|
402 |
+
|
403 |
+
$normalized_name = strtolower($name);
|
404 |
+
|
405 |
+
// If $value is null or false, unset the header
|
406 |
+
if ($value === null || $value === false) {
|
407 |
+
unset($this->headers[$normalized_name]);
|
408 |
+
|
409 |
+
// Else, set the header
|
410 |
+
} else {
|
411 |
+
// Header names are stored lowercase internally.
|
412 |
+
if (is_string($value)) {
|
413 |
+
$value = trim($value);
|
414 |
+
}
|
415 |
+
$this->headers[$normalized_name] = array($name, $value);
|
416 |
+
}
|
417 |
+
}
|
418 |
+
|
419 |
+
return $this;
|
420 |
+
}
|
421 |
+
|
422 |
+
/**
|
423 |
+
* Get the value of a specific header
|
424 |
+
*
|
425 |
+
* Note that if the header has more than one value, an array
|
426 |
+
* will be returned.
|
427 |
+
*
|
428 |
+
* @param string $key
|
429 |
+
* @return string|array|null The header value or null if it is not set
|
430 |
+
*/
|
431 |
+
public function getHeader($key)
|
432 |
+
{
|
433 |
+
$key = strtolower($key);
|
434 |
+
if (isset($this->headers[$key])) {
|
435 |
+
return $this->headers[$key][1];
|
436 |
+
} else {
|
437 |
+
return null;
|
438 |
+
}
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Set a GET parameter for the request. Wrapper around _setParameter
|
443 |
+
*
|
444 |
+
* @param string|array $name
|
445 |
+
* @param string $value
|
446 |
+
* @return Microsoft_Http_Client
|
447 |
+
*/
|
448 |
+
public function setParameterGet($name, $value = null)
|
449 |
+
{
|
450 |
+
if (is_array($name)) {
|
451 |
+
foreach ($name as $k => $v)
|
452 |
+
$this->_setParameter('GET', $k, $v);
|
453 |
+
} else {
|
454 |
+
$this->_setParameter('GET', $name, $value);
|
455 |
+
}
|
456 |
+
|
457 |
+
return $this;
|
458 |
+
}
|
459 |
+
|
460 |
+
/**
|
461 |
+
* Set a POST parameter for the request. Wrapper around _setParameter
|
462 |
+
*
|
463 |
+
* @param string|array $name
|
464 |
+
* @param string $value
|
465 |
+
* @return Microsoft_Http_Client
|
466 |
+
*/
|
467 |
+
public function setParameterPost($name, $value = null)
|
468 |
+
{
|
469 |
+
if (is_array($name)) {
|
470 |
+
foreach ($name as $k => $v)
|
471 |
+
$this->_setParameter('POST', $k, $v);
|
472 |
+
} else {
|
473 |
+
$this->_setParameter('POST', $name, $value);
|
474 |
+
}
|
475 |
+
|
476 |
+
return $this;
|
477 |
+
}
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Set a GET or POST parameter - used by SetParameterGet and SetParameterPost
|
481 |
+
*
|
482 |
+
* @param string $type GET or POST
|
483 |
+
* @param string $name
|
484 |
+
* @param string $value
|
485 |
+
* @return null
|
486 |
+
*/
|
487 |
+
protected function _setParameter($type, $name, $value)
|
488 |
+
{
|
489 |
+
$parray = array();
|
490 |
+
$type = strtolower($type);
|
491 |
+
switch ($type) {
|
492 |
+
case 'get':
|
493 |
+
$parray = &$this->paramsGet;
|
494 |
+
break;
|
495 |
+
case 'post':
|
496 |
+
$parray = &$this->paramsPost;
|
497 |
+
break;
|
498 |
+
}
|
499 |
+
|
500 |
+
if ($value === null) {
|
501 |
+
if (isset($parray[$name])) unset($parray[$name]);
|
502 |
+
} else {
|
503 |
+
$parray[$name] = $value;
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Get the number of redirections done on the last request
|
509 |
+
*
|
510 |
+
* @return int
|
511 |
+
*/
|
512 |
+
public function getRedirectionsCount()
|
513 |
+
{
|
514 |
+
return $this->redirectCounter;
|
515 |
+
}
|
516 |
+
|
517 |
+
/**
|
518 |
+
* Set HTTP authentication parameters
|
519 |
+
*
|
520 |
+
* $type should be one of the supported types - see the self::AUTH_*
|
521 |
+
* constants.
|
522 |
+
*
|
523 |
+
* To enable authentication:
|
524 |
+
* <code>
|
525 |
+
* $this->setAuth('shahar', 'secret', Microsoft_Http_Client::AUTH_BASIC);
|
526 |
+
* </code>
|
527 |
+
*
|
528 |
+
* To disable authentication:
|
529 |
+
* <code>
|
530 |
+
* $this->setAuth(false);
|
531 |
+
* </code>
|
532 |
+
*
|
533 |
+
* @see http://www.faqs.org/rfcs/rfc2617.html
|
534 |
+
* @param string|false $user User name or false disable authentication
|
535 |
+
* @param string $password Password
|
536 |
+
* @param string $type Authentication type
|
537 |
+
* @return Microsoft_Http_Client
|
538 |
+
* @throws Microsoft_Http_Client_Exception
|
539 |
+
*/
|
540 |
+
public function setAuth($user, $password = '', $type = self::AUTH_BASIC)
|
541 |
+
{
|
542 |
+
// If we got false or null, disable authentication
|
543 |
+
if ($user === false || $user === null) {
|
544 |
+
$this->auth = null;
|
545 |
+
|
546 |
+
// Clear the auth information in the uri instance as well
|
547 |
+
if ($this->uri instanceof Microsoft_Uri_Http) {
|
548 |
+
$this->getUri()->setUsername('');
|
549 |
+
$this->getUri()->setPassword('');
|
550 |
+
}
|
551 |
+
// Else, set up authentication
|
552 |
+
} else {
|
553 |
+
// Check we got a proper authentication type
|
554 |
+
if (! defined('self::AUTH_' . strtoupper($type))) {
|
555 |
+
/** @see Microsoft_Http_Client_Exception */
|
556 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
557 |
+
throw new Microsoft_Http_Client_Exception("Invalid or not supported authentication type: '$type'");
|
558 |
+
}
|
559 |
+
|
560 |
+
$this->auth = array(
|
561 |
+
'user' => (string) $user,
|
562 |
+
'password' => (string) $password,
|
563 |
+
'type' => $type
|
564 |
+
);
|
565 |
+
}
|
566 |
+
|
567 |
+
return $this;
|
568 |
+
}
|
569 |
+
|
570 |
+
/**
|
571 |
+
* Set the HTTP client's cookie jar.
|
572 |
+
*
|
573 |
+
* A cookie jar is an object that holds and maintains cookies across HTTP requests
|
574 |
+
* and responses.
|
575 |
+
*
|
576 |
+
* @param Microsoft_Http_CookieJar|boolean $cookiejar Existing cookiejar object, true to create a new one, false to disable
|
577 |
+
* @return Microsoft_Http_Client
|
578 |
+
* @throws Microsoft_Http_Client_Exception
|
579 |
+
*/
|
580 |
+
public function setCookieJar($cookiejar = true)
|
581 |
+
{
|
582 |
+
if (! class_exists('Microsoft_Http_CookieJar')) {
|
583 |
+
require_once 'Microsoft/Http/CookieJar.php';
|
584 |
+
}
|
585 |
+
|
586 |
+
if ($cookiejar instanceof Microsoft_Http_CookieJar) {
|
587 |
+
$this->cookiejar = $cookiejar;
|
588 |
+
} elseif ($cookiejar === true) {
|
589 |
+
$this->cookiejar = new Microsoft_Http_CookieJar();
|
590 |
+
} elseif (! $cookiejar) {
|
591 |
+
$this->cookiejar = null;
|
592 |
+
} else {
|
593 |
+
/** @see Microsoft_Http_Client_Exception */
|
594 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
595 |
+
throw new Microsoft_Http_Client_Exception('Invalid parameter type passed as CookieJar');
|
596 |
+
}
|
597 |
+
|
598 |
+
return $this;
|
599 |
+
}
|
600 |
+
|
601 |
+
/**
|
602 |
+
* Return the current cookie jar or null if none.
|
603 |
+
*
|
604 |
+
* @return Microsoft_Http_CookieJar|null
|
605 |
+
*/
|
606 |
+
public function getCookieJar()
|
607 |
+
{
|
608 |
+
return $this->cookiejar;
|
609 |
+
}
|
610 |
+
|
611 |
+
/**
|
612 |
+
* Add a cookie to the request. If the client has no Cookie Jar, the cookies
|
613 |
+
* will be added directly to the headers array as "Cookie" headers.
|
614 |
+
*
|
615 |
+
* @param Microsoft_Http_Cookie|string $cookie
|
616 |
+
* @param string|null $value If "cookie" is a string, this is the cookie value.
|
617 |
+
* @return Microsoft_Http_Client
|
618 |
+
* @throws Microsoft_Http_Client_Exception
|
619 |
+
*/
|
620 |
+
public function setCookie($cookie, $value = null)
|
621 |
+
{
|
622 |
+
if (! class_exists('Microsoft_Http_Cookie')) {
|
623 |
+
require_once 'Microsoft/Http/Cookie.php';
|
624 |
+
}
|
625 |
+
|
626 |
+
if (is_array($cookie)) {
|
627 |
+
foreach ($cookie as $c => $v) {
|
628 |
+
if (is_string($c)) {
|
629 |
+
$this->setCookie($c, $v);
|
630 |
+
} else {
|
631 |
+
$this->setCookie($v);
|
632 |
+
}
|
633 |
+
}
|
634 |
+
|
635 |
+
return $this;
|
636 |
+
}
|
637 |
+
|
638 |
+
if ($value !== null) {
|
639 |
+
$value = urlencode($value);
|
640 |
+
}
|
641 |
+
|
642 |
+
if (isset($this->cookiejar)) {
|
643 |
+
if ($cookie instanceof Microsoft_Http_Cookie) {
|
644 |
+
$this->cookiejar->addCookie($cookie);
|
645 |
+
} elseif (is_string($cookie) && $value !== null) {
|
646 |
+
$cookie = Microsoft_Http_Cookie::fromString("{$cookie}={$value}", $this->uri);
|
647 |
+
$this->cookiejar->addCookie($cookie);
|
648 |
+
}
|
649 |
+
} else {
|
650 |
+
if ($cookie instanceof Microsoft_Http_Cookie) {
|
651 |
+
$name = $cookie->getName();
|
652 |
+
$value = $cookie->getValue();
|
653 |
+
$cookie = $name;
|
654 |
+
}
|
655 |
+
|
656 |
+
if (preg_match("/[=,; \t\r\n\013\014]/", $cookie)) {
|
657 |
+
/** @see Microsoft_Http_Client_Exception */
|
658 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
659 |
+
throw new Microsoft_Http_Client_Exception("Cookie name cannot contain these characters: =,; \t\r\n\013\014 ({$cookie})");
|
660 |
+
}
|
661 |
+
|
662 |
+
$value = addslashes($value);
|
663 |
+
|
664 |
+
if (! isset($this->headers['cookie'])) {
|
665 |
+
$this->headers['cookie'] = array('Cookie', '');
|
666 |
+
}
|
667 |
+
$this->headers['cookie'][1] .= $cookie . '=' . $value . '; ';
|
668 |
+
}
|
669 |
+
|
670 |
+
return $this;
|
671 |
+
}
|
672 |
+
|
673 |
+
/**
|
674 |
+
* Set a file to upload (using a POST request)
|
675 |
+
*
|
676 |
+
* Can be used in two ways:
|
677 |
+
*
|
678 |
+
* 1. $data is null (default): $filename is treated as the name if a local file which
|
679 |
+
* will be read and sent. Will try to guess the content type using mime_content_type().
|
680 |
+
* 2. $data is set - $filename is sent as the file name, but $data is sent as the file
|
681 |
+
* contents and no file is read from the file system. In this case, you need to
|
682 |
+
* manually set the Content-Type ($ctype) or it will default to
|
683 |
+
* application/octet-stream.
|
684 |
+
*
|
685 |
+
* @param string $filename Name of file to upload, or name to save as
|
686 |
+
* @param string $formname Name of form element to send as
|
687 |
+
* @param string $data Data to send (if null, $filename is read and sent)
|
688 |
+
* @param string $ctype Content type to use (if $data is set and $ctype is
|
689 |
+
* null, will be application/octet-stream)
|
690 |
+
* @return Microsoft_Http_Client
|
691 |
+
* @throws Microsoft_Http_Client_Exception
|
692 |
+
*/
|
693 |
+
public function setFileUpload($filename, $formname, $data = null, $ctype = null)
|
694 |
+
{
|
695 |
+
if ($data === null) {
|
696 |
+
if (($data = @file_get_contents($filename)) === false) {
|
697 |
+
/** @see Microsoft_Http_Client_Exception */
|
698 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
699 |
+
throw new Microsoft_Http_Client_Exception("Unable to read file '{$filename}' for upload");
|
700 |
+
}
|
701 |
+
|
702 |
+
if (! $ctype) {
|
703 |
+
$ctype = $this->_detectFileMimeType($filename);
|
704 |
+
}
|
705 |
+
}
|
706 |
+
|
707 |
+
// Force enctype to multipart/form-data
|
708 |
+
$this->setEncType(self::ENC_FORMDATA);
|
709 |
+
|
710 |
+
$this->files[] = array(
|
711 |
+
'formname' => $formname,
|
712 |
+
'filename' => basename($filename),
|
713 |
+
'ctype' => $ctype,
|
714 |
+
'data' => $data
|
715 |
+
);
|
716 |
+
|
717 |
+
return $this;
|
718 |
+
}
|
719 |
+
|
720 |
+
/**
|
721 |
+
* Set the encoding type for POST data
|
722 |
+
*
|
723 |
+
* @param string $enctype
|
724 |
+
* @return Microsoft_Http_Client
|
725 |
+
*/
|
726 |
+
public function setEncType($enctype = self::ENC_URLENCODED)
|
727 |
+
{
|
728 |
+
$this->enctype = $enctype;
|
729 |
+
|
730 |
+
return $this;
|
731 |
+
}
|
732 |
+
|
733 |
+
/**
|
734 |
+
* Set the raw (already encoded) POST data.
|
735 |
+
*
|
736 |
+
* This function is here for two reasons:
|
737 |
+
* 1. For advanced user who would like to set their own data, already encoded
|
738 |
+
* 2. For backwards compatibilty: If someone uses the old post($data) method.
|
739 |
+
* this method will be used to set the encoded data.
|
740 |
+
*
|
741 |
+
* $data can also be stream (such as file) from which the data will be read.
|
742 |
+
*
|
743 |
+
* @param string|resource $data
|
744 |
+
* @param string $enctype
|
745 |
+
* @return Microsoft_Http_Client
|
746 |
+
*/
|
747 |
+
public function setRawData($data, $enctype = null)
|
748 |
+
{
|
749 |
+
$this->raw_post_data = $data;
|
750 |
+
$this->setEncType($enctype);
|
751 |
+
if (is_resource($data)) {
|
752 |
+
// We've got stream data
|
753 |
+
$stat = @fstat($data);
|
754 |
+
if($stat) {
|
755 |
+
$this->setHeaders(self::CONTENT_LENGTH, $stat['size']);
|
756 |
+
}
|
757 |
+
}
|
758 |
+
return $this;
|
759 |
+
}
|
760 |
+
|
761 |
+
/**
|
762 |
+
* Clear all GET and POST parameters
|
763 |
+
*
|
764 |
+
* Should be used to reset the request parameters if the client is
|
765 |
+
* used for several concurrent requests.
|
766 |
+
*
|
767 |
+
* clearAll parameter controls if we clean just parameters or also
|
768 |
+
* headers and last_*
|
769 |
+
*
|
770 |
+
* @param bool $clearAll Should all data be cleared?
|
771 |
+
* @return Microsoft_Http_Client
|
772 |
+
*/
|
773 |
+
public function resetParameters($clearAll = false)
|
774 |
+
{
|
775 |
+
// Reset parameter data
|
776 |
+
$this->paramsGet = array();
|
777 |
+
$this->paramsPost = array();
|
778 |
+
$this->files = array();
|
779 |
+
$this->raw_post_data = null;
|
780 |
+
|
781 |
+
if($clearAll) {
|
782 |
+
$this->headers = array();
|
783 |
+
$this->last_request = null;
|
784 |
+
$this->last_response = null;
|
785 |
+
} else {
|
786 |
+
// Clear outdated headers
|
787 |
+
if (isset($this->headers[strtolower(self::CONTENT_TYPE)])) {
|
788 |
+
unset($this->headers[strtolower(self::CONTENT_TYPE)]);
|
789 |
+
}
|
790 |
+
if (isset($this->headers[strtolower(self::CONTENT_LENGTH)])) {
|
791 |
+
unset($this->headers[strtolower(self::CONTENT_LENGTH)]);
|
792 |
+
}
|
793 |
+
}
|
794 |
+
|
795 |
+
return $this;
|
796 |
+
}
|
797 |
+
|
798 |
+
/**
|
799 |
+
* Get the last HTTP request as string
|
800 |
+
*
|
801 |
+
* @return string
|
802 |
+
*/
|
803 |
+
public function getLastRequest()
|
804 |
+
{
|
805 |
+
return $this->last_request;
|
806 |
+
}
|
807 |
+
|
808 |
+
/**
|
809 |
+
* Get the last HTTP response received by this client
|
810 |
+
*
|
811 |
+
* If $config['storeresponse'] is set to false, or no response was
|
812 |
+
* stored yet, will return null
|
813 |
+
*
|
814 |
+
* @return Microsoft_Http_Response or null if none
|
815 |
+
*/
|
816 |
+
public function getLastResponse()
|
817 |
+
{
|
818 |
+
return $this->last_response;
|
819 |
+
}
|
820 |
+
|
821 |
+
/**
|
822 |
+
* Load the connection adapter
|
823 |
+
*
|
824 |
+
* While this method is not called more than one for a client, it is
|
825 |
+
* seperated from ->request() to preserve logic and readability
|
826 |
+
*
|
827 |
+
* @param Microsoft_Http_Client_Adapter_Interface|string $adapter
|
828 |
+
* @return null
|
829 |
+
* @throws Microsoft_Http_Client_Exception
|
830 |
+
*/
|
831 |
+
public function setAdapter($adapter)
|
832 |
+
{
|
833 |
+
if (is_string($adapter)) {
|
834 |
+
if (!class_exists($adapter)) {
|
835 |
+
@require_once( str_replace('_', '/', $adapter) . '.php' );
|
836 |
+
}
|
837 |
+
|
838 |
+
$adapter = new $adapter;
|
839 |
+
}
|
840 |
+
|
841 |
+
if (! $adapter instanceof Microsoft_Http_Client_Adapter_Interface) {
|
842 |
+
/** @see Microsoft_Http_Client_Exception */
|
843 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
844 |
+
throw new Microsoft_Http_Client_Exception('Passed adapter is not a HTTP connection adapter');
|
845 |
+
}
|
846 |
+
|
847 |
+
$this->adapter = $adapter;
|
848 |
+
$config = $this->config;
|
849 |
+
unset($config['adapter']);
|
850 |
+
$this->adapter->setConfig($config);
|
851 |
+
}
|
852 |
+
|
853 |
+
/**
|
854 |
+
* Load the connection adapter
|
855 |
+
*
|
856 |
+
* @return Microsoft_Http_Client_Adapter_Interface $adapter
|
857 |
+
*/
|
858 |
+
public function getAdapter()
|
859 |
+
{
|
860 |
+
return $this->adapter;
|
861 |
+
}
|
862 |
+
|
863 |
+
/**
|
864 |
+
* Set streaming for received data
|
865 |
+
*
|
866 |
+
* @param string|boolean $streamfile Stream file, true for temp file, false/null for no streaming
|
867 |
+
* @return Microsoft_Http_Client
|
868 |
+
*/
|
869 |
+
public function setStream($streamfile = true)
|
870 |
+
{
|
871 |
+
$this->setConfig(array("output_stream" => $streamfile));
|
872 |
+
return $this;
|
873 |
+
}
|
874 |
+
|
875 |
+
/**
|
876 |
+
* Get status of streaming for received data
|
877 |
+
* @return boolean|string
|
878 |
+
*/
|
879 |
+
public function getStream()
|
880 |
+
{
|
881 |
+
return $this->config["output_stream"];
|
882 |
+
}
|
883 |
+
|
884 |
+
/**
|
885 |
+
* Create temporary stream
|
886 |
+
*
|
887 |
+
* @return resource
|
888 |
+
*/
|
889 |
+
protected function _openTempStream()
|
890 |
+
{
|
891 |
+
$this->_stream_name = $this->config['output_stream'];
|
892 |
+
if(!is_string($this->_stream_name)) {
|
893 |
+
// If name is not given, create temp name
|
894 |
+
$this->_stream_name = tempnam(isset($this->config['stream_tmp_dir'])?$this->config['stream_tmp_dir']:sys_get_temp_dir(),
|
895 |
+
'Microsoft_Http_Client');
|
896 |
+
}
|
897 |
+
|
898 |
+
$fp = fopen($this->_stream_name, "w+b");
|
899 |
+
if(!$fp) {
|
900 |
+
$this->close();
|
901 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
902 |
+
throw new Microsoft_Http_Client_Exception("Could not open temp file $name");
|
903 |
+
|
904 |
+
}
|
905 |
+
return $fp;
|
906 |
+
}
|
907 |
+
|
908 |
+
/**
|
909 |
+
* Send the HTTP request and return an HTTP response object
|
910 |
+
*
|
911 |
+
* @param string $method
|
912 |
+
* @return Microsoft_Http_Response
|
913 |
+
* @throws Microsoft_Http_Client_Exception
|
914 |
+
*/
|
915 |
+
public function request($method = null)
|
916 |
+
{
|
917 |
+
if (! $this->uri instanceof Microsoft_Uri_Http) {
|
918 |
+
/** @see Microsoft_Http_Client_Exception */
|
919 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
920 |
+
throw new Microsoft_Http_Client_Exception('No valid URI has been passed to the client');
|
921 |
+
}
|
922 |
+
|
923 |
+
if ($method) {
|
924 |
+
$this->setMethod($method);
|
925 |
+
}
|
926 |
+
$this->redirectCounter = 0;
|
927 |
+
$response = null;
|
928 |
+
|
929 |
+
// Make sure the adapter is loaded
|
930 |
+
if ($this->adapter == null) {
|
931 |
+
$this->setAdapter($this->config['adapter']);
|
932 |
+
}
|
933 |
+
|
934 |
+
// Send the first request. If redirected, continue.
|
935 |
+
do {
|
936 |
+
// Clone the URI and add the additional GET parameters to it
|
937 |
+
$uri = clone $this->uri;
|
938 |
+
if (! empty($this->paramsGet)) {
|
939 |
+
$query = $uri->getQuery();
|
940 |
+
if (! empty($query)) {
|
941 |
+
$query .= '&';
|
942 |
+
}
|
943 |
+
$query .= http_build_query($this->paramsGet, null, '&');
|
944 |
+
|
945 |
+
$uri->setQuery($query);
|
946 |
+
}
|
947 |
+
|
948 |
+
$body = $this->_prepareBody();
|
949 |
+
$headers = $this->_prepareHeaders();
|
950 |
+
|
951 |
+
// check that adapter supports streaming before using it
|
952 |
+
if(is_resource($body) && !($this->adapter instanceof Microsoft_Http_Client_Adapter_Stream)) {
|
953 |
+
/** @see Microsoft_Http_Client_Exception */
|
954 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
955 |
+
throw new Microsoft_Http_Client_Exception('Adapter does not support streaming');
|
956 |
+
}
|
957 |
+
|
958 |
+
// Open the connection, send the request and read the response
|
959 |
+
$this->adapter->connect($uri->getHost(), $uri->getPort(),
|
960 |
+
($uri->getScheme() == 'https' ? true : false));
|
961 |
+
|
962 |
+
if($this->config['output_stream']) {
|
963 |
+
if($this->adapter instanceof Microsoft_Http_Client_Adapter_Stream) {
|
964 |
+
$stream = $this->_openTempStream();
|
965 |
+
$this->adapter->setOutputStream($stream);
|
966 |
+
} else {
|
967 |
+
/** @see Microsoft_Http_Client_Exception */
|
968 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
969 |
+
throw new Microsoft_Http_Client_Exception('Adapter does not support streaming');
|
970 |
+
}
|
971 |
+
}
|
972 |
+
|
973 |
+
$this->last_request = $this->adapter->write($this->method,
|
974 |
+
$uri, $this->config['httpversion'], $headers, $body);
|
975 |
+
|
976 |
+
$response = $this->adapter->read();
|
977 |
+
if (! $response) {
|
978 |
+
/** @see Microsoft_Http_Client_Exception */
|
979 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
980 |
+
throw new Microsoft_Http_Client_Exception('Unable to read response, or response is empty');
|
981 |
+
}
|
982 |
+
|
983 |
+
if($this->config['output_stream']) {
|
984 |
+
rewind($stream);
|
985 |
+
// cleanup the adapter
|
986 |
+
$this->adapter->setOutputStream(null);
|
987 |
+
$response = Microsoft_Http_Response_Stream::fromStream($response, $stream);
|
988 |
+
$response->setStreamName($this->_stream_name);
|
989 |
+
if(!is_string($this->config['output_stream'])) {
|
990 |
+
// we used temp name, will need to clean up
|
991 |
+
$response->setCleanup(true);
|
992 |
+
}
|
993 |
+
} else {
|
994 |
+
$response = Microsoft_Http_Response::fromString($response);
|
995 |
+
}
|
996 |
+
|
997 |
+
if ($this->config['storeresponse']) {
|
998 |
+
$this->last_response = $response;
|
999 |
+
}
|
1000 |
+
|
1001 |
+
// Load cookies into cookie jar
|
1002 |
+
if (isset($this->cookiejar)) {
|
1003 |
+
$this->cookiejar->addCookiesFromResponse($response, $uri);
|
1004 |
+
}
|
1005 |
+
|
1006 |
+
// If we got redirected, look for the Location header
|
1007 |
+
if ($response->isRedirect() && ($location = $response->getHeader('location'))) {
|
1008 |
+
|
1009 |
+
// Check whether we send the exact same request again, or drop the parameters
|
1010 |
+
// and send a GET request
|
1011 |
+
if ($response->getStatus() == 303 ||
|
1012 |
+
((! $this->config['strictredirects']) && ($response->getStatus() == 302 ||
|
1013 |
+
$response->getStatus() == 301))) {
|
1014 |
+
|
1015 |
+
$this->resetParameters();
|
1016 |
+
$this->setMethod(self::GET);
|
1017 |
+
}
|
1018 |
+
|
1019 |
+
// If we got a well formed absolute URI
|
1020 |
+
if (Microsoft_Uri_Http::check($location)) {
|
1021 |
+
$this->setHeaders('host', null);
|
1022 |
+
$this->setUri($location);
|
1023 |
+
|
1024 |
+
} else {
|
1025 |
+
|
1026 |
+
// Split into path and query and set the query
|
1027 |
+
if (strpos($location, '?') !== false) {
|
1028 |
+
list($location, $query) = explode('?', $location, 2);
|
1029 |
+
} else {
|
1030 |
+
$query = '';
|
1031 |
+
}
|
1032 |
+
$this->uri->setQuery($query);
|
1033 |
+
|
1034 |
+
// Else, if we got just an absolute path, set it
|
1035 |
+
if(strpos($location, '/') === 0) {
|
1036 |
+
$this->uri->setPath($location);
|
1037 |
+
|
1038 |
+
// Else, assume we have a relative path
|
1039 |
+
} else {
|
1040 |
+
// Get the current path directory, removing any trailing slashes
|
1041 |
+
$path = $this->uri->getPath();
|
1042 |
+
$path = rtrim(substr($path, 0, strrpos($path, '/')), "/");
|
1043 |
+
$this->uri->setPath($path . '/' . $location);
|
1044 |
+
}
|
1045 |
+
}
|
1046 |
+
++$this->redirectCounter;
|
1047 |
+
|
1048 |
+
} else {
|
1049 |
+
// If we didn't get any location, stop redirecting
|
1050 |
+
break;
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
} while ($this->redirectCounter < $this->config['maxredirects']);
|
1054 |
+
|
1055 |
+
return $response;
|
1056 |
+
}
|
1057 |
+
|
1058 |
+
/**
|
1059 |
+
* Prepare the request headers
|
1060 |
+
*
|
1061 |
+
* @return array
|
1062 |
+
*/
|
1063 |
+
protected function _prepareHeaders()
|
1064 |
+
{
|
1065 |
+
$headers = array();
|
1066 |
+
|
1067 |
+
// Set the host header
|
1068 |
+
if (! isset($this->headers['host'])) {
|
1069 |
+
$host = $this->uri->getHost();
|
1070 |
+
|
1071 |
+
// If the port is not default, add it
|
1072 |
+
if (! (($this->uri->getScheme() == 'http' && $this->uri->getPort() == 80) ||
|
1073 |
+
($this->uri->getScheme() == 'https' && $this->uri->getPort() == 443))) {
|
1074 |
+
$host .= ':' . $this->uri->getPort();
|
1075 |
+
}
|
1076 |
+
|
1077 |
+
$headers[] = "Host: {$host}";
|
1078 |
+
}
|
1079 |
+
|
1080 |
+
// Set the connection header
|
1081 |
+
if (! isset($this->headers['connection'])) {
|
1082 |
+
if (! $this->config['keepalive']) {
|
1083 |
+
$headers[] = "Connection: close";
|
1084 |
+
}
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
// Set the Accept-encoding header if not set - depending on whether
|
1088 |
+
// zlib is available or not.
|
1089 |
+
if (! isset($this->headers['accept-encoding'])) {
|
1090 |
+
if (function_exists('gzinflate')) {
|
1091 |
+
$headers[] = 'Accept-encoding: gzip, deflate';
|
1092 |
+
} else {
|
1093 |
+
$headers[] = 'Accept-encoding: identity';
|
1094 |
+
}
|
1095 |
+
}
|
1096 |
+
|
1097 |
+
// Set the Content-Type header
|
1098 |
+
if ($this->method == self::POST &&
|
1099 |
+
(! isset($this->headers[strtolower(self::CONTENT_TYPE)]) && isset($this->enctype))) {
|
1100 |
+
|
1101 |
+
$headers[] = self::CONTENT_TYPE . ': ' . $this->enctype;
|
1102 |
+
}
|
1103 |
+
|
1104 |
+
// Set the user agent header
|
1105 |
+
if (! isset($this->headers['user-agent']) && isset($this->config['useragent'])) {
|
1106 |
+
$headers[] = "User-Agent: {$this->config['useragent']}";
|
1107 |
+
}
|
1108 |
+
|
1109 |
+
// Set HTTP authentication if needed
|
1110 |
+
if (is_array($this->auth)) {
|
1111 |
+
$auth = self::encodeAuthHeader($this->auth['user'], $this->auth['password'], $this->auth['type']);
|
1112 |
+
$headers[] = "Authorization: {$auth}";
|
1113 |
+
}
|
1114 |
+
|
1115 |
+
// Load cookies from cookie jar
|
1116 |
+
if (isset($this->cookiejar)) {
|
1117 |
+
$cookstr = $this->cookiejar->getMatchingCookies($this->uri,
|
1118 |
+
true, Microsoft_Http_CookieJar::COOKIE_STRING_CONCAT);
|
1119 |
+
|
1120 |
+
if ($cookstr) {
|
1121 |
+
$headers[] = "Cookie: {$cookstr}";
|
1122 |
+
}
|
1123 |
+
}
|
1124 |
+
|
1125 |
+
// Add all other user defined headers
|
1126 |
+
foreach ($this->headers as $header) {
|
1127 |
+
list($name, $value) = $header;
|
1128 |
+
if (is_array($value)) {
|
1129 |
+
$value = implode(', ', $value);
|
1130 |
+
}
|
1131 |
+
|
1132 |
+
$headers[] = "$name: $value";
|
1133 |
+
}
|
1134 |
+
|
1135 |
+
return $headers;
|
1136 |
+
}
|
1137 |
+
|
1138 |
+
/**
|
1139 |
+
* Prepare the request body (for POST and PUT requests)
|
1140 |
+
*
|
1141 |
+
* @return string
|
1142 |
+
* @throws Microsoft_Http_Client_Exception
|
1143 |
+
*/
|
1144 |
+
protected function _prepareBody()
|
1145 |
+
{
|
1146 |
+
// According to RFC2616, a TRACE request should not have a body.
|
1147 |
+
if ($this->method == self::TRACE) {
|
1148 |
+
return '';
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
if (isset($this->raw_post_data) && is_resource($this->raw_post_data)) {
|
1152 |
+
return $this->raw_post_data;
|
1153 |
+
}
|
1154 |
+
// If mbstring overloads substr and strlen functions, we have to
|
1155 |
+
// override it's internal encoding
|
1156 |
+
if (function_exists('mb_internal_encoding') &&
|
1157 |
+
((int) ini_get('mbstring.func_overload')) & 2) {
|
1158 |
+
|
1159 |
+
$mbIntEnc = mb_internal_encoding();
|
1160 |
+
mb_internal_encoding('ASCII');
|
1161 |
+
}
|
1162 |
+
|
1163 |
+
// If we have raw_post_data set, just use it as the body.
|
1164 |
+
if (isset($this->raw_post_data)) {
|
1165 |
+
$this->setHeaders(self::CONTENT_LENGTH, strlen($this->raw_post_data));
|
1166 |
+
if (isset($mbIntEnc)) {
|
1167 |
+
mb_internal_encoding($mbIntEnc);
|
1168 |
+
}
|
1169 |
+
|
1170 |
+
return $this->raw_post_data;
|
1171 |
+
}
|
1172 |
+
|
1173 |
+
$body = '';
|
1174 |
+
|
1175 |
+
// If we have files to upload, force enctype to multipart/form-data
|
1176 |
+
if (count ($this->files) > 0) {
|
1177 |
+
$this->setEncType(self::ENC_FORMDATA);
|
1178 |
+
}
|
1179 |
+
|
1180 |
+
// If we have POST parameters or files, encode and add them to the body
|
1181 |
+
if (count($this->paramsPost) > 0 || count($this->files) > 0) {
|
1182 |
+
switch($this->enctype) {
|
1183 |
+
case self::ENC_FORMDATA:
|
1184 |
+
// Encode body as multipart/form-data
|
1185 |
+
$boundary = '---ZENDHTTPCLIENT-' . md5(microtime());
|
1186 |
+
$this->setHeaders(self::CONTENT_TYPE, self::ENC_FORMDATA . "; boundary={$boundary}");
|
1187 |
+
|
1188 |
+
// Get POST parameters and encode them
|
1189 |
+
$params = self::_flattenParametersArray($this->paramsPost);
|
1190 |
+
foreach ($params as $pp) {
|
1191 |
+
$body .= self::encodeFormData($boundary, $pp[0], $pp[1]);
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
// Encode files
|
1195 |
+
foreach ($this->files as $file) {
|
1196 |
+
$fhead = array(self::CONTENT_TYPE => $file['ctype']);
|
1197 |
+
$body .= self::encodeFormData($boundary, $file['formname'], $file['data'], $file['filename'], $fhead);
|
1198 |
+
}
|
1199 |
+
|
1200 |
+
$body .= "--{$boundary}--\r\n";
|
1201 |
+
break;
|
1202 |
+
|
1203 |
+
case self::ENC_URLENCODED:
|
1204 |
+
// Encode body as application/x-www-form-urlencoded
|
1205 |
+
$this->setHeaders(self::CONTENT_TYPE, self::ENC_URLENCODED);
|
1206 |
+
$body = http_build_query($this->paramsPost, '', '&');
|
1207 |
+
break;
|
1208 |
+
|
1209 |
+
default:
|
1210 |
+
if (isset($mbIntEnc)) {
|
1211 |
+
mb_internal_encoding($mbIntEnc);
|
1212 |
+
}
|
1213 |
+
|
1214 |
+
/** @see Microsoft_Http_Client_Exception */
|
1215 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
1216 |
+
throw new Microsoft_Http_Client_Exception("Cannot handle content type '{$this->enctype}' automatically." .
|
1217 |
+
" Please use Microsoft_Http_Client::setRawData to send this kind of content.");
|
1218 |
+
break;
|
1219 |
+
}
|
1220 |
+
}
|
1221 |
+
|
1222 |
+
// Set the Content-Length if we have a body or if request is POST/PUT
|
1223 |
+
if ($body || $this->method == self::POST || $this->method == self::PUT) {
|
1224 |
+
$this->setHeaders(self::CONTENT_LENGTH, strlen($body));
|
1225 |
+
}
|
1226 |
+
|
1227 |
+
if (isset($mbIntEnc)) {
|
1228 |
+
mb_internal_encoding($mbIntEnc);
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
return $body;
|
1232 |
+
}
|
1233 |
+
|
1234 |
+
/**
|
1235 |
+
* Helper method that gets a possibly multi-level parameters array (get or
|
1236 |
+
* post) and flattens it.
|
1237 |
+
*
|
1238 |
+
* The method returns an array of (key, value) pairs (because keys are not
|
1239 |
+
* necessarily unique. If one of the parameters in as array, it will also
|
1240 |
+
* add a [] suffix to the key.
|
1241 |
+
*
|
1242 |
+
* This method is deprecated since Zend Framework 1.9 in favour of
|
1243 |
+
* self::_flattenParametersArray() and will be dropped in 2.0
|
1244 |
+
*
|
1245 |
+
* @deprecated since 1.9
|
1246 |
+
*
|
1247 |
+
* @param array $parray The parameters array
|
1248 |
+
* @param bool $urlencode Whether to urlencode the name and value
|
1249 |
+
* @return array
|
1250 |
+
*/
|
1251 |
+
protected function _getParametersRecursive($parray, $urlencode = false)
|
1252 |
+
{
|
1253 |
+
// Issue a deprecated notice
|
1254 |
+
trigger_error("The " . __METHOD__ . " method is deprecated and will be dropped in 2.0.",
|
1255 |
+
E_USER_NOTICE);
|
1256 |
+
|
1257 |
+
if (! is_array($parray)) {
|
1258 |
+
return $parray;
|
1259 |
+
}
|
1260 |
+
$parameters = array();
|
1261 |
+
|
1262 |
+
foreach ($parray as $name => $value) {
|
1263 |
+
if ($urlencode) {
|
1264 |
+
$name = urlencode($name);
|
1265 |
+
}
|
1266 |
+
|
1267 |
+
// If $value is an array, iterate over it
|
1268 |
+
if (is_array($value)) {
|
1269 |
+
$name .= ($urlencode ? '%5B%5D' : '[]');
|
1270 |
+
foreach ($value as $subval) {
|
1271 |
+
if ($urlencode) {
|
1272 |
+
$subval = urlencode($subval);
|
1273 |
+
}
|
1274 |
+
$parameters[] = array($name, $subval);
|
1275 |
+
}
|
1276 |
+
} else {
|
1277 |
+
if ($urlencode) {
|
1278 |
+
$value = urlencode($value);
|
1279 |
+
}
|
1280 |
+
$parameters[] = array($name, $value);
|
1281 |
+
}
|
1282 |
+
}
|
1283 |
+
|
1284 |
+
return $parameters;
|
1285 |
+
}
|
1286 |
+
|
1287 |
+
/**
|
1288 |
+
* Attempt to detect the MIME type of a file using available extensions
|
1289 |
+
*
|
1290 |
+
* This method will try to detect the MIME type of a file. If the fileinfo
|
1291 |
+
* extension is available, it will be used. If not, the mime_magic
|
1292 |
+
* extension which is deprected but is still available in many PHP setups
|
1293 |
+
* will be tried.
|
1294 |
+
*
|
1295 |
+
* If neither extension is available, the default application/octet-stream
|
1296 |
+
* MIME type will be returned
|
1297 |
+
*
|
1298 |
+
* @param string $file File path
|
1299 |
+
* @return string MIME type
|
1300 |
+
*/
|
1301 |
+
protected function _detectFileMimeType($file)
|
1302 |
+
{
|
1303 |
+
$type = null;
|
1304 |
+
|
1305 |
+
// First try with fileinfo functions
|
1306 |
+
if (function_exists('finfo_open')) {
|
1307 |
+
if (self::$_fileInfoDb === null) {
|
1308 |
+
self::$_fileInfoDb = @finfo_open(FILEINFO_MIME);
|
1309 |
+
}
|
1310 |
+
|
1311 |
+
if (self::$_fileInfoDb) {
|
1312 |
+
$type = finfo_file(self::$_fileInfoDb, $file);
|
1313 |
+
}
|
1314 |
+
|
1315 |
+
} elseif (function_exists('mime_content_type')) {
|
1316 |
+
$type = mime_content_type($file);
|
1317 |
+
}
|
1318 |
+
|
1319 |
+
// Fallback to the default application/octet-stream
|
1320 |
+
if (! $type) {
|
1321 |
+
$type = 'application/octet-stream';
|
1322 |
+
}
|
1323 |
+
|
1324 |
+
return $type;
|
1325 |
+
}
|
1326 |
+
|
1327 |
+
/**
|
1328 |
+
* Encode data to a multipart/form-data part suitable for a POST request.
|
1329 |
+
*
|
1330 |
+
* @param string $boundary
|
1331 |
+
* @param string $name
|
1332 |
+
* @param mixed $value
|
1333 |
+
* @param string $filename
|
1334 |
+
* @param array $headers Associative array of optional headers @example ("Content-Transfer-Encoding" => "binary")
|
1335 |
+
* @return string
|
1336 |
+
*/
|
1337 |
+
public static function encodeFormData($boundary, $name, $value, $filename = null, $headers = array()) {
|
1338 |
+
$ret = "--{$boundary}\r\n" .
|
1339 |
+
'Content-Disposition: form-data; name="' . $name .'"';
|
1340 |
+
|
1341 |
+
if ($filename) {
|
1342 |
+
$ret .= '; filename="' . $filename . '"';
|
1343 |
+
}
|
1344 |
+
$ret .= "\r\n";
|
1345 |
+
|
1346 |
+
foreach ($headers as $hname => $hvalue) {
|
1347 |
+
$ret .= "{$hname}: {$hvalue}\r\n";
|
1348 |
+
}
|
1349 |
+
$ret .= "\r\n";
|
1350 |
+
|
1351 |
+
$ret .= "{$value}\r\n";
|
1352 |
+
|
1353 |
+
return $ret;
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
/**
|
1357 |
+
* Create a HTTP authentication "Authorization:" header according to the
|
1358 |
+
* specified user, password and authentication method.
|
1359 |
+
*
|
1360 |
+
* @see http://www.faqs.org/rfcs/rfc2617.html
|
1361 |
+
* @param string $user
|
1362 |
+
* @param string $password
|
1363 |
+
* @param string $type
|
1364 |
+
* @return string
|
1365 |
+
* @throws Microsoft_Http_Client_Exception
|
1366 |
+
*/
|
1367 |
+
public static function encodeAuthHeader($user, $password, $type = self::AUTH_BASIC)
|
1368 |
+
{
|
1369 |
+
$authHeader = null;
|
1370 |
+
|
1371 |
+
switch ($type) {
|
1372 |
+
case self::AUTH_BASIC:
|
1373 |
+
// In basic authentication, the user name cannot contain ":"
|
1374 |
+
if (strpos($user, ':') !== false) {
|
1375 |
+
/** @see Microsoft_Http_Client_Exception */
|
1376 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
1377 |
+
throw new Microsoft_Http_Client_Exception("The user name cannot contain ':' in 'Basic' HTTP authentication");
|
1378 |
+
}
|
1379 |
+
|
1380 |
+
$authHeader = 'Basic ' . base64_encode($user . ':' . $password);
|
1381 |
+
break;
|
1382 |
+
|
1383 |
+
//case self::AUTH_DIGEST:
|
1384 |
+
/**
|
1385 |
+
* @todo Implement digest authentication
|
1386 |
+
*/
|
1387 |
+
// break;
|
1388 |
+
|
1389 |
+
default:
|
1390 |
+
/** @see Microsoft_Http_Client_Exception */
|
1391 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
1392 |
+
throw new Microsoft_Http_Client_Exception("Not a supported HTTP authentication type: '$type'");
|
1393 |
+
}
|
1394 |
+
|
1395 |
+
return $authHeader;
|
1396 |
+
}
|
1397 |
+
|
1398 |
+
/**
|
1399 |
+
* Convert an array of parameters into a flat array of (key, value) pairs
|
1400 |
+
*
|
1401 |
+
* Will flatten a potentially multi-dimentional array of parameters (such
|
1402 |
+
* as POST parameters) into a flat array of (key, value) paris. In case
|
1403 |
+
* of multi-dimentional arrays, square brackets ([]) will be added to the
|
1404 |
+
* key to indicate an array.
|
1405 |
+
*
|
1406 |
+
* @since 1.9
|
1407 |
+
*
|
1408 |
+
* @param array $parray
|
1409 |
+
* @param string $prefix
|
1410 |
+
* @return array
|
1411 |
+
*/
|
1412 |
+
static protected function _flattenParametersArray($parray, $prefix = null)
|
1413 |
+
{
|
1414 |
+
if (! is_array($parray)) {
|
1415 |
+
return $parray;
|
1416 |
+
}
|
1417 |
+
|
1418 |
+
$parameters = array();
|
1419 |
+
|
1420 |
+
foreach($parray as $name => $value) {
|
1421 |
+
|
1422 |
+
// Calculate array key
|
1423 |
+
if ($prefix) {
|
1424 |
+
if (is_int($name)) {
|
1425 |
+
$key = $prefix . '[]';
|
1426 |
+
} else {
|
1427 |
+
$key = $prefix . "[$name]";
|
1428 |
+
}
|
1429 |
+
} else {
|
1430 |
+
$key = $name;
|
1431 |
+
}
|
1432 |
+
|
1433 |
+
if (is_array($value)) {
|
1434 |
+
$parameters = array_merge($parameters, self::_flattenParametersArray($value, $key));
|
1435 |
+
|
1436 |
+
} else {
|
1437 |
+
$parameters[] = array($key, $value);
|
1438 |
+
}
|
1439 |
+
}
|
1440 |
+
|
1441 |
+
return $parameters;
|
1442 |
+
}
|
1443 |
+
|
1444 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Curl.php
ADDED
@@ -0,0 +1,498 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client_Adapter
|
19 |
+
* @version $Id: Curl.php 19238 2009-11-25 17:13:38Z bate $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @see Microsoft_Uri_Http
|
26 |
+
*/
|
27 |
+
require_once 'Microsoft/Uri/Http.php';
|
28 |
+
|
29 |
+
/**
|
30 |
+
* @see Microsoft_Http_Client_Adapter_Interface
|
31 |
+
*/
|
32 |
+
require_once 'Microsoft/Http/Client/Adapter/Interface.php';
|
33 |
+
/**
|
34 |
+
* @see Microsoft_Http_Client_Adapter_Stream
|
35 |
+
*/
|
36 |
+
require_once 'Microsoft/Http/Client/Adapter/Stream.php';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* An adapter class for Microsoft_Http_Client based on the curl extension.
|
40 |
+
* Curl requires libcurl. See for full requirements the PHP manual: http://php.net/curl
|
41 |
+
*
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_Http
|
44 |
+
* @subpackage Client_Adapter
|
45 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
46 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
47 |
+
*/
|
48 |
+
class Microsoft_Http_Client_Adapter_Curl implements Microsoft_Http_Client_Adapter_Interface, Microsoft_Http_Client_Adapter_Stream
|
49 |
+
{
|
50 |
+
/**
|
51 |
+
* Parameters array
|
52 |
+
*
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
+
protected $_config = array();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* What host/port are we connected to?
|
59 |
+
*
|
60 |
+
* @var array
|
61 |
+
*/
|
62 |
+
protected $_connected_to = array(null, null);
|
63 |
+
|
64 |
+
/**
|
65 |
+
* The curl session handle
|
66 |
+
*
|
67 |
+
* @var resource|null
|
68 |
+
*/
|
69 |
+
protected $_curl = null;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* List of cURL options that should never be overwritten
|
73 |
+
*
|
74 |
+
* @var array
|
75 |
+
*/
|
76 |
+
protected $_invalidOverwritableCurlOptions = array(
|
77 |
+
CURLOPT_HTTPGET,
|
78 |
+
CURLOPT_POST,
|
79 |
+
CURLOPT_PUT,
|
80 |
+
CURLOPT_CUSTOMREQUEST,
|
81 |
+
CURLOPT_HEADER,
|
82 |
+
CURLOPT_RETURNTRANSFER,
|
83 |
+
CURLOPT_HTTPHEADER,
|
84 |
+
CURLOPT_POSTFIELDS,
|
85 |
+
CURLOPT_INFILE,
|
86 |
+
CURLOPT_INFILESIZE,
|
87 |
+
CURLOPT_PORT,
|
88 |
+
CURLOPT_MAXREDIRS,
|
89 |
+
CURLOPT_CONNECTTIMEOUT,
|
90 |
+
CURL_HTTP_VERSION_1_1,
|
91 |
+
CURL_HTTP_VERSION_1_0,
|
92 |
+
);
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Response gotten from server
|
96 |
+
*
|
97 |
+
* @var string
|
98 |
+
*/
|
99 |
+
protected $_response = null;
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Stream for storing output
|
103 |
+
*
|
104 |
+
* @var resource
|
105 |
+
*/
|
106 |
+
protected $out_stream;
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Adapter constructor
|
110 |
+
*
|
111 |
+
* Config is set using setConfig()
|
112 |
+
*
|
113 |
+
* @return void
|
114 |
+
* @throws Microsoft_Http_Client_Adapter_Exception
|
115 |
+
*/
|
116 |
+
public function __construct()
|
117 |
+
{
|
118 |
+
if (!extension_loaded('curl')) {
|
119 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
120 |
+
throw new Microsoft_Http_Client_Adapter_Exception('cURL extension has to be loaded to use this Microsoft_Http_Client adapter.');
|
121 |
+
}
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Set the configuration array for the adapter
|
126 |
+
*
|
127 |
+
* @throws Microsoft_Http_Client_Adapter_Exception
|
128 |
+
* @param array $config
|
129 |
+
* @return Microsoft_Http_Client_Adapter_Curl
|
130 |
+
*/
|
131 |
+
public function setConfig($config = array())
|
132 |
+
{
|
133 |
+
if (! is_array($config)) {
|
134 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
135 |
+
throw new Microsoft_Http_Client_Adapter_Exception(
|
136 |
+
'Array expected, got ' . gettype($config)
|
137 |
+
);
|
138 |
+
}
|
139 |
+
|
140 |
+
if(isset($config['proxy_user']) && isset($config['proxy_pass'])) {
|
141 |
+
$this->setCurlOption(CURLOPT_PROXYUSERPWD, $config['proxy_user'].":".$config['proxy_pass']);
|
142 |
+
unset($config['proxy_user'], $config['proxy_pass']);
|
143 |
+
}
|
144 |
+
|
145 |
+
foreach ($config as $k => $v) {
|
146 |
+
$option = strtolower($k);
|
147 |
+
switch($option) {
|
148 |
+
case 'proxy_host':
|
149 |
+
$this->setCurlOption(CURLOPT_PROXY, $v);
|
150 |
+
break;
|
151 |
+
case 'proxy_port':
|
152 |
+
$this->setCurlOption(CURLOPT_PROXYPORT, $v);
|
153 |
+
break;
|
154 |
+
default:
|
155 |
+
$this->_config[$option] = $v;
|
156 |
+
break;
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
return $this;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Retrieve the array of all configuration options
|
165 |
+
*
|
166 |
+
* @return array
|
167 |
+
*/
|
168 |
+
public function getConfig()
|
169 |
+
{
|
170 |
+
return $this->_config;
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Direct setter for cURL adapter related options.
|
175 |
+
*
|
176 |
+
* @param string|int $option
|
177 |
+
* @param mixed $value
|
178 |
+
* @return Microsoft_Http_Adapter_Curl
|
179 |
+
*/
|
180 |
+
public function setCurlOption($option, $value)
|
181 |
+
{
|
182 |
+
if (!isset($this->_config['curloptions'])) {
|
183 |
+
$this->_config['curloptions'] = array();
|
184 |
+
}
|
185 |
+
$this->_config['curloptions'][$option] = $value;
|
186 |
+
return $this;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Initialize curl
|
191 |
+
*
|
192 |
+
* @param string $host
|
193 |
+
* @param int $port
|
194 |
+
* @param boolean $secure
|
195 |
+
* @return void
|
196 |
+
* @throws Microsoft_Http_Client_Adapter_Exception if unable to connect
|
197 |
+
*/
|
198 |
+
public function connect($host, $port = 80, $secure = false)
|
199 |
+
{
|
200 |
+
// If we're already connected, disconnect first
|
201 |
+
if ($this->_curl) {
|
202 |
+
$this->close();
|
203 |
+
}
|
204 |
+
|
205 |
+
// If we are connected to a different server or port, disconnect first
|
206 |
+
if ($this->_curl
|
207 |
+
&& is_array($this->_connected_to)
|
208 |
+
&& ($this->_connected_to[0] != $host
|
209 |
+
|| $this->_connected_to[1] != $port)
|
210 |
+
) {
|
211 |
+
$this->close();
|
212 |
+
}
|
213 |
+
|
214 |
+
// Do the actual connection
|
215 |
+
$this->_curl = curl_init();
|
216 |
+
if ($port != 80) {
|
217 |
+
curl_setopt($this->_curl, CURLOPT_PORT, intval($port));
|
218 |
+
}
|
219 |
+
|
220 |
+
// Set timeout
|
221 |
+
curl_setopt($this->_curl, CURLOPT_CONNECTTIMEOUT, $this->_config['timeout']);
|
222 |
+
|
223 |
+
// Set Max redirects
|
224 |
+
curl_setopt($this->_curl, CURLOPT_MAXREDIRS, $this->_config['maxredirects']);
|
225 |
+
|
226 |
+
if (!$this->_curl) {
|
227 |
+
$this->close();
|
228 |
+
|
229 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
230 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Unable to Connect to ' . $host . ':' . $port);
|
231 |
+
}
|
232 |
+
|
233 |
+
if ($secure !== false) {
|
234 |
+
// Behave the same like Microsoft_Http_Adapter_Socket on SSL options.
|
235 |
+
if (isset($this->_config['sslcert'])) {
|
236 |
+
curl_setopt($this->_curl, CURLOPT_SSLCERT, $this->_config['sslcert']);
|
237 |
+
}
|
238 |
+
if (isset($this->_config['sslpassphrase'])) {
|
239 |
+
curl_setopt($this->_curl, CURLOPT_SSLCERTPASSWD, $this->_config['sslpassphrase']);
|
240 |
+
}
|
241 |
+
}
|
242 |
+
|
243 |
+
// Update connected_to
|
244 |
+
$this->_connected_to = array($host, $port);
|
245 |
+
}
|
246 |
+
|
247 |
+
/**
|
248 |
+
* Send request to the remote server
|
249 |
+
*
|
250 |
+
* @param string $method
|
251 |
+
* @param Microsoft_Uri_Http $uri
|
252 |
+
* @param float $http_ver
|
253 |
+
* @param array $headers
|
254 |
+
* @param string $body
|
255 |
+
* @return string $request
|
256 |
+
* @throws Microsoft_Http_Client_Adapter_Exception If connection fails, connected to wrong host, no PUT file defined, unsupported method, or unsupported cURL option
|
257 |
+
*/
|
258 |
+
public function write($method, $uri, $httpVersion = 1.1, $headers = array(), $body = '')
|
259 |
+
{
|
260 |
+
// Make sure we're properly connected
|
261 |
+
if (!$this->_curl) {
|
262 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
263 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Trying to write but we are not connected");
|
264 |
+
}
|
265 |
+
|
266 |
+
if ($this->_connected_to[0] != $uri->getHost() || $this->_connected_to[1] != $uri->getPort()) {
|
267 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
268 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong host");
|
269 |
+
}
|
270 |
+
|
271 |
+
// set URL
|
272 |
+
curl_setopt($this->_curl, CURLOPT_URL, $uri->__toString());
|
273 |
+
|
274 |
+
// ensure correct curl call
|
275 |
+
$curlValue = true;
|
276 |
+
switch ($method) {
|
277 |
+
case Microsoft_Http_Client::GET:
|
278 |
+
$curlMethod = CURLOPT_HTTPGET;
|
279 |
+
break;
|
280 |
+
|
281 |
+
case Microsoft_Http_Client::POST:
|
282 |
+
$curlMethod = CURLOPT_POST;
|
283 |
+
break;
|
284 |
+
|
285 |
+
case Microsoft_Http_Client::PUT:
|
286 |
+
// There are two different types of PUT request, either a Raw Data string has been set
|
287 |
+
// or CURLOPT_INFILE and CURLOPT_INFILESIZE are used.
|
288 |
+
if(is_resource($body)) {
|
289 |
+
$this->_config['curloptions'][CURLOPT_INFILE] = $body;
|
290 |
+
}
|
291 |
+
if (isset($this->_config['curloptions'][CURLOPT_INFILE])) {
|
292 |
+
// Now we will probably already have Content-Length set, so that we have to delete it
|
293 |
+
// from $headers at this point:
|
294 |
+
foreach ($headers AS $k => $header) {
|
295 |
+
if (preg_match('/Content-Length:\s*(\d+)/i', $header, $m)) {
|
296 |
+
if(is_resource($body)) {
|
297 |
+
$this->_config['curloptions'][CURLOPT_INFILESIZE] = (int)$m[1];
|
298 |
+
}
|
299 |
+
unset($headers[$k]);
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
if (!isset($this->_config['curloptions'][CURLOPT_INFILESIZE])) {
|
304 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
305 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Cannot set a file-handle for cURL option CURLOPT_INFILE without also setting its size in CURLOPT_INFILESIZE.");
|
306 |
+
}
|
307 |
+
|
308 |
+
if(is_resource($body)) {
|
309 |
+
$body = '';
|
310 |
+
}
|
311 |
+
|
312 |
+
$curlMethod = CURLOPT_PUT;
|
313 |
+
} else {
|
314 |
+
$curlMethod = CURLOPT_CUSTOMREQUEST;
|
315 |
+
$curlValue = "PUT";
|
316 |
+
}
|
317 |
+
break;
|
318 |
+
|
319 |
+
case Microsoft_Http_Client::DELETE:
|
320 |
+
$curlMethod = CURLOPT_CUSTOMREQUEST;
|
321 |
+
$curlValue = "DELETE";
|
322 |
+
break;
|
323 |
+
|
324 |
+
case Microsoft_Http_Client::OPTIONS:
|
325 |
+
$curlMethod = CURLOPT_CUSTOMREQUEST;
|
326 |
+
$curlValue = "OPTIONS";
|
327 |
+
break;
|
328 |
+
|
329 |
+
case Microsoft_Http_Client::TRACE:
|
330 |
+
$curlMethod = CURLOPT_CUSTOMREQUEST;
|
331 |
+
$curlValue = "TRACE";
|
332 |
+
break;
|
333 |
+
|
334 |
+
default:
|
335 |
+
// For now, through an exception for unsupported request methods
|
336 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
337 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Method currently not supported");
|
338 |
+
}
|
339 |
+
|
340 |
+
if(is_resource($body) && $curlMethod != CURLOPT_PUT) {
|
341 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
342 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Streaming requests are allowed only with PUT");
|
343 |
+
}
|
344 |
+
|
345 |
+
// get http version to use
|
346 |
+
$curlHttp = ($httpVersion == 1.1) ? CURL_HTTP_VERSION_1_1 : CURL_HTTP_VERSION_1_0;
|
347 |
+
|
348 |
+
// mark as HTTP request and set HTTP method
|
349 |
+
curl_setopt($this->_curl, $curlHttp, true);
|
350 |
+
curl_setopt($this->_curl, $curlMethod, $curlValue);
|
351 |
+
|
352 |
+
if($this->out_stream) {
|
353 |
+
// headers will be read into the response
|
354 |
+
curl_setopt($this->_curl, CURLOPT_HEADER, false);
|
355 |
+
curl_setopt($this->_curl, CURLOPT_HEADERFUNCTION, array($this, "readHeader"));
|
356 |
+
// and data will be written into the file
|
357 |
+
curl_setopt($this->_curl, CURLOPT_FILE, $this->out_stream);
|
358 |
+
} else {
|
359 |
+
// ensure headers are also returned
|
360 |
+
curl_setopt($this->_curl, CURLOPT_HEADER, true);
|
361 |
+
|
362 |
+
// ensure actual response is returned
|
363 |
+
curl_setopt($this->_curl, CURLOPT_RETURNTRANSFER, true);
|
364 |
+
}
|
365 |
+
|
366 |
+
// set additional headers
|
367 |
+
$headers['Accept'] = '';
|
368 |
+
curl_setopt($this->_curl, CURLOPT_HTTPHEADER, $headers);
|
369 |
+
|
370 |
+
/**
|
371 |
+
* Make sure POSTFIELDS is set after $curlMethod is set:
|
372 |
+
* @link http://de2.php.net/manual/en/function.curl-setopt.php#81161
|
373 |
+
*/
|
374 |
+
if ($method == Microsoft_Http_Client::POST) {
|
375 |
+
curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
|
376 |
+
} elseif ($curlMethod == CURLOPT_PUT) {
|
377 |
+
// this covers a PUT by file-handle:
|
378 |
+
// Make the setting of this options explicit (rather than setting it through the loop following a bit lower)
|
379 |
+
// to group common functionality together.
|
380 |
+
curl_setopt($this->_curl, CURLOPT_INFILE, $this->_config['curloptions'][CURLOPT_INFILE]);
|
381 |
+
curl_setopt($this->_curl, CURLOPT_INFILESIZE, $this->_config['curloptions'][CURLOPT_INFILESIZE]);
|
382 |
+
unset($this->_config['curloptions'][CURLOPT_INFILE]);
|
383 |
+
unset($this->_config['curloptions'][CURLOPT_INFILESIZE]);
|
384 |
+
} elseif ($method == Microsoft_Http_Client::PUT) {
|
385 |
+
// This is a PUT by a setRawData string, not by file-handle
|
386 |
+
curl_setopt($this->_curl, CURLOPT_POSTFIELDS, $body);
|
387 |
+
}
|
388 |
+
|
389 |
+
// set additional curl options
|
390 |
+
if (isset($this->_config['curloptions'])) {
|
391 |
+
foreach ((array)$this->_config['curloptions'] as $k => $v) {
|
392 |
+
if (!in_array($k, $this->_invalidOverwritableCurlOptions)) {
|
393 |
+
if (curl_setopt($this->_curl, $k, $v) == false) {
|
394 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
395 |
+
throw new Microsoft_Http_Client_Exception(sprintf("Unknown or erroreous cURL option '%s' set", $k));
|
396 |
+
}
|
397 |
+
}
|
398 |
+
}
|
399 |
+
}
|
400 |
+
|
401 |
+
// send the request
|
402 |
+
$response = curl_exec($this->_curl);
|
403 |
+
|
404 |
+
// if we used streaming, headers are already there
|
405 |
+
if(!is_resource($this->out_stream)) {
|
406 |
+
$this->_response = $response;
|
407 |
+
}
|
408 |
+
|
409 |
+
$request = curl_getinfo($this->_curl, CURLINFO_HEADER_OUT);
|
410 |
+
$request .= $body;
|
411 |
+
|
412 |
+
if (empty($this->_response)) {
|
413 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
414 |
+
throw new Microsoft_Http_Client_Exception("Error in cURL request: " . curl_error($this->_curl));
|
415 |
+
}
|
416 |
+
|
417 |
+
// cURL automatically decodes chunked-messages, this means we have to disallow the Microsoft_Http_Response to do it again
|
418 |
+
if (stripos($this->_response, "Transfer-Encoding: chunked\r\n")) {
|
419 |
+
$this->_response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $this->_response);
|
420 |
+
}
|
421 |
+
|
422 |
+
// Eliminate multiple HTTP responses.
|
423 |
+
do {
|
424 |
+
$parts = preg_split('|(?:\r?\n){2}|m', $this->_response, 2);
|
425 |
+
$again = false;
|
426 |
+
|
427 |
+
if (isset($parts[1]) && preg_match("|^HTTP/1\.[01](.*?)\r\n|mi", $parts[1])) {
|
428 |
+
$this->_response = $parts[1];
|
429 |
+
$again = true;
|
430 |
+
}
|
431 |
+
} while ($again);
|
432 |
+
|
433 |
+
// cURL automatically handles Proxy rewrites, remove the "HTTP/1.0 200 Connection established" string:
|
434 |
+
if (stripos($this->_response, "HTTP/1.0 200 Connection established\r\n\r\n") !== false) {
|
435 |
+
$this->_response = str_ireplace("HTTP/1.0 200 Connection established\r\n\r\n", '', $this->_response);
|
436 |
+
}
|
437 |
+
|
438 |
+
return $request;
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Return read response from server
|
443 |
+
*
|
444 |
+
* @return string
|
445 |
+
*/
|
446 |
+
public function read()
|
447 |
+
{
|
448 |
+
return $this->_response;
|
449 |
+
}
|
450 |
+
|
451 |
+
/**
|
452 |
+
* Close the connection to the server
|
453 |
+
*
|
454 |
+
*/
|
455 |
+
public function close()
|
456 |
+
{
|
457 |
+
if(is_resource($this->_curl)) {
|
458 |
+
curl_close($this->_curl);
|
459 |
+
}
|
460 |
+
$this->_curl = null;
|
461 |
+
$this->_connected_to = array(null, null);
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Get cUrl Handle
|
466 |
+
*
|
467 |
+
* @return resource
|
468 |
+
*/
|
469 |
+
public function getHandle()
|
470 |
+
{
|
471 |
+
return $this->_curl;
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Set output stream for the response
|
476 |
+
*
|
477 |
+
* @param resource $stream
|
478 |
+
* @return Microsoft_Http_Client_Adapter_Socket
|
479 |
+
*/
|
480 |
+
public function setOutputStream($stream)
|
481 |
+
{
|
482 |
+
$this->out_stream = $stream;
|
483 |
+
return $this;
|
484 |
+
}
|
485 |
+
|
486 |
+
/**
|
487 |
+
* Header reader function for CURL
|
488 |
+
*
|
489 |
+
* @param resource $curl
|
490 |
+
* @param string $header
|
491 |
+
* @return int
|
492 |
+
*/
|
493 |
+
public function readHeader($curl, $header)
|
494 |
+
{
|
495 |
+
$this->_response .= $header;
|
496 |
+
return strlen($header);
|
497 |
+
}
|
498 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Exception.php
ADDED
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Http
|
17 |
+
* @subpackage Client_Adapter_Exception
|
18 |
+
* @version $Id: Exception.php 17026 2009-07-24 09:09:19Z shahar $
|
19 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
20 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
21 |
+
*/
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @see Microsoft_Http_Client_Exception
|
25 |
+
*/
|
26 |
+
require_once 'Microsoft/Http/Client/Exception.php';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @category Microsoft
|
30 |
+
* @package Microsoft_Http
|
31 |
+
* @subpackage Client_Adapter
|
32 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
33 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
34 |
+
*/
|
35 |
+
class Microsoft_Http_Client_Adapter_Exception extends Microsoft_Http_Client_Exception
|
36 |
+
{
|
37 |
+
const READ_TIMEOUT = 1000;
|
38 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Interface.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client_Adapter
|
19 |
+
* @version $Id: Interface.php 16214 2009-06-21 19:34:03Z thomas $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* An interface description for Microsoft_Http_Client_Adapter classes.
|
26 |
+
*
|
27 |
+
* These classes are used as connectors for Microsoft_Http_Client, performing the
|
28 |
+
* tasks of connecting, writing, reading and closing connection to the server.
|
29 |
+
*
|
30 |
+
* @category Microsoft
|
31 |
+
* @package Microsoft_Http
|
32 |
+
* @subpackage Client_Adapter
|
33 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
34 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
35 |
+
*/
|
36 |
+
interface Microsoft_Http_Client_Adapter_Interface
|
37 |
+
{
|
38 |
+
/**
|
39 |
+
* Set the configuration array for the adapter
|
40 |
+
*
|
41 |
+
* @param array $config
|
42 |
+
*/
|
43 |
+
public function setConfig($config = array());
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Connect to the remote server
|
47 |
+
*
|
48 |
+
* @param string $host
|
49 |
+
* @param int $port
|
50 |
+
* @param boolean $secure
|
51 |
+
*/
|
52 |
+
public function connect($host, $port = 80, $secure = false);
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Send request to the remote server
|
56 |
+
*
|
57 |
+
* @param string $method
|
58 |
+
* @param Microsoft_Uri_Http $url
|
59 |
+
* @param string $http_ver
|
60 |
+
* @param array $headers
|
61 |
+
* @param string $body
|
62 |
+
* @return string Request as text
|
63 |
+
*/
|
64 |
+
public function write($method, $url, $http_ver = '1.1', $headers = array(), $body = '');
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Read response from server
|
68 |
+
*
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
public function read();
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Close the connection to the server
|
75 |
+
*
|
76 |
+
*/
|
77 |
+
public function close();
|
78 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Proxy.php
ADDED
@@ -0,0 +1,267 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client_Adapter
|
19 |
+
* @version $Id: Proxy.php 17059 2009-07-25 11:24:49Z shahar $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @see Microsoft_Uri_Http
|
26 |
+
*/
|
27 |
+
require_once 'Microsoft/Uri/Http.php';
|
28 |
+
/**
|
29 |
+
* @see Microsoft_Http_Client
|
30 |
+
*/
|
31 |
+
require_once 'Microsoft/Http/Client.php';
|
32 |
+
/**
|
33 |
+
* @see Microsoft_Http_Client_Adapter_Socket
|
34 |
+
*/
|
35 |
+
require_once 'Microsoft/Http/Client/Adapter/Socket.php';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* HTTP Proxy-supporting Microsoft_Http_Client adapter class, based on the default
|
39 |
+
* socket based adapter.
|
40 |
+
*
|
41 |
+
* Should be used if proxy HTTP access is required. If no proxy is set, will
|
42 |
+
* fall back to Microsoft_Http_Client_Adapter_Socket behavior. Just like the
|
43 |
+
* default Socket adapter, this adapter does not require any special extensions
|
44 |
+
* installed.
|
45 |
+
*
|
46 |
+
* @category Microsoft
|
47 |
+
* @package Microsoft_Http
|
48 |
+
* @subpackage Client_Adapter
|
49 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
50 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
51 |
+
*/
|
52 |
+
class Microsoft_Http_Client_Adapter_Proxy extends Microsoft_Http_Client_Adapter_Socket
|
53 |
+
{
|
54 |
+
/**
|
55 |
+
* Parameters array
|
56 |
+
*
|
57 |
+
* @var array
|
58 |
+
*/
|
59 |
+
protected $config = array(
|
60 |
+
'ssltransport' => 'ssl',
|
61 |
+
'sslcert' => null,
|
62 |
+
'sslpassphrase' => null,
|
63 |
+
'proxy_host' => '',
|
64 |
+
'proxy_port' => 8080,
|
65 |
+
'proxy_user' => '',
|
66 |
+
'proxy_pass' => '',
|
67 |
+
'proxy_auth' => Microsoft_Http_Client::AUTH_BASIC,
|
68 |
+
'persistent' => false
|
69 |
+
);
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Whether HTTPS CONNECT was already negotiated with the proxy or not
|
73 |
+
*
|
74 |
+
* @var boolean
|
75 |
+
*/
|
76 |
+
protected $negotiated = false;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Connect to the remote server
|
80 |
+
*
|
81 |
+
* Will try to connect to the proxy server. If no proxy was set, will
|
82 |
+
* fall back to the target server (behave like regular Socket adapter)
|
83 |
+
*
|
84 |
+
* @param string $host
|
85 |
+
* @param int $port
|
86 |
+
* @param boolean $secure
|
87 |
+
*/
|
88 |
+
public function connect($host, $port = 80, $secure = false)
|
89 |
+
{
|
90 |
+
// If no proxy is set, fall back to Socket adapter
|
91 |
+
if (! $this->config['proxy_host']) {
|
92 |
+
return parent::connect($host, $port, $secure);
|
93 |
+
}
|
94 |
+
|
95 |
+
// Connect (a non-secure connection) to the proxy server
|
96 |
+
return parent::connect(
|
97 |
+
$this->config['proxy_host'],
|
98 |
+
$this->config['proxy_port'],
|
99 |
+
false
|
100 |
+
);
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Send request to the proxy server
|
105 |
+
*
|
106 |
+
* @param string $method
|
107 |
+
* @param Microsoft_Uri_Http $uri
|
108 |
+
* @param string $http_ver
|
109 |
+
* @param array $headers
|
110 |
+
* @param string $body
|
111 |
+
* @return string Request as string
|
112 |
+
*/
|
113 |
+
public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
|
114 |
+
{
|
115 |
+
// If no proxy is set, fall back to default Socket adapter
|
116 |
+
if (! $this->config['proxy_host']) return parent::write($method, $uri, $http_ver, $headers, $body);
|
117 |
+
|
118 |
+
// Make sure we're properly connected
|
119 |
+
if (! $this->socket) {
|
120 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
121 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Trying to write but we are not connected");
|
122 |
+
}
|
123 |
+
|
124 |
+
$host = $this->config['proxy_host'];
|
125 |
+
$port = $this->config['proxy_port'];
|
126 |
+
|
127 |
+
if ($this->connected_to[0] != "tcp://$host" || $this->connected_to[1] != $port) {
|
128 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
129 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Trying to write but we are connected to the wrong proxy server");
|
130 |
+
}
|
131 |
+
|
132 |
+
// Add Proxy-Authorization header
|
133 |
+
if ($this->config['proxy_user'] && ! isset($headers['proxy-authorization'])) {
|
134 |
+
$headers['proxy-authorization'] = Microsoft_Http_Client::encodeAuthHeader(
|
135 |
+
$this->config['proxy_user'], $this->config['proxy_pass'], $this->config['proxy_auth']
|
136 |
+
);
|
137 |
+
}
|
138 |
+
|
139 |
+
// if we are proxying HTTPS, preform CONNECT handshake with the proxy
|
140 |
+
if ($uri->getScheme() == 'https' && (! $this->negotiated)) {
|
141 |
+
$this->connectHandshake($uri->getHost(), $uri->getPort(), $http_ver, $headers);
|
142 |
+
$this->negotiated = true;
|
143 |
+
}
|
144 |
+
|
145 |
+
// Save request method for later
|
146 |
+
$this->method = $method;
|
147 |
+
|
148 |
+
// Build request headers
|
149 |
+
if ($this->negotiated) {
|
150 |
+
$path = $uri->getPath();
|
151 |
+
if ($uri->getQuery()) {
|
152 |
+
$path .= '?' . $uri->getQuery();
|
153 |
+
}
|
154 |
+
$request = "$method $path HTTP/$http_ver\r\n";
|
155 |
+
} else {
|
156 |
+
$request = "$method $uri HTTP/$http_ver\r\n";
|
157 |
+
}
|
158 |
+
|
159 |
+
// Add all headers to the request string
|
160 |
+
foreach ($headers as $k => $v) {
|
161 |
+
if (is_string($k)) $v = "$k: $v";
|
162 |
+
$request .= "$v\r\n";
|
163 |
+
}
|
164 |
+
|
165 |
+
// Add the request body
|
166 |
+
$request .= "\r\n" . $body;
|
167 |
+
|
168 |
+
// Send the request
|
169 |
+
if (! @fwrite($this->socket, $request)) {
|
170 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
171 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Error writing request to proxy server");
|
172 |
+
}
|
173 |
+
|
174 |
+
return $request;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Preform handshaking with HTTPS proxy using CONNECT method
|
179 |
+
*
|
180 |
+
* @param string $host
|
181 |
+
* @param integer $port
|
182 |
+
* @param string $http_ver
|
183 |
+
* @param array $headers
|
184 |
+
*/
|
185 |
+
protected function connectHandshake($host, $port = 443, $http_ver = '1.1', array &$headers = array())
|
186 |
+
{
|
187 |
+
$request = "CONNECT $host:$port HTTP/$http_ver\r\n" .
|
188 |
+
"Host: " . $this->config['proxy_host'] . "\r\n";
|
189 |
+
|
190 |
+
// Add the user-agent header
|
191 |
+
if (isset($this->config['useragent'])) {
|
192 |
+
$request .= "User-agent: " . $this->config['useragent'] . "\r\n";
|
193 |
+
}
|
194 |
+
|
195 |
+
// If the proxy-authorization header is set, send it to proxy but remove
|
196 |
+
// it from headers sent to target host
|
197 |
+
if (isset($headers['proxy-authorization'])) {
|
198 |
+
$request .= "Proxy-authorization: " . $headers['proxy-authorization'] . "\r\n";
|
199 |
+
unset($headers['proxy-authorization']);
|
200 |
+
}
|
201 |
+
|
202 |
+
$request .= "\r\n";
|
203 |
+
|
204 |
+
// Send the request
|
205 |
+
if (! @fwrite($this->socket, $request)) {
|
206 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
207 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Error writing request to proxy server");
|
208 |
+
}
|
209 |
+
|
210 |
+
// Read response headers only
|
211 |
+
$response = '';
|
212 |
+
$gotStatus = false;
|
213 |
+
while ($line = @fgets($this->socket)) {
|
214 |
+
$gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
|
215 |
+
if ($gotStatus) {
|
216 |
+
$response .= $line;
|
217 |
+
if (!chop($line)) break;
|
218 |
+
}
|
219 |
+
}
|
220 |
+
|
221 |
+
// Check that the response from the proxy is 200
|
222 |
+
if (Microsoft_Http_Response::extractCode($response) != 200) {
|
223 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
224 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Unable to connect to HTTPS proxy. Server response: " . $response);
|
225 |
+
}
|
226 |
+
|
227 |
+
// If all is good, switch socket to secure mode. We have to fall back
|
228 |
+
// through the different modes
|
229 |
+
$modes = array(
|
230 |
+
STREAM_CRYPTO_METHOD_TLS_CLIENT,
|
231 |
+
STREAM_CRYPTO_METHOD_SSLv3_CLIENT,
|
232 |
+
STREAM_CRYPTO_METHOD_SSLv23_CLIENT,
|
233 |
+
STREAM_CRYPTO_METHOD_SSLv2_CLIENT
|
234 |
+
);
|
235 |
+
|
236 |
+
$success = false;
|
237 |
+
foreach($modes as $mode) {
|
238 |
+
$success = stream_socket_enable_crypto($this->socket, true, $mode);
|
239 |
+
if ($success) break;
|
240 |
+
}
|
241 |
+
|
242 |
+
if (! $success) {
|
243 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
244 |
+
throw new Microsoft_Http_Client_Adapter_Exception("Unable to connect to" .
|
245 |
+
" HTTPS server through proxy: could not negotiate secure connection.");
|
246 |
+
}
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Close the connection to the server
|
251 |
+
*
|
252 |
+
*/
|
253 |
+
public function close()
|
254 |
+
{
|
255 |
+
parent::close();
|
256 |
+
$this->negotiated = false;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Destructor: make sure the socket is disconnected
|
261 |
+
*
|
262 |
+
*/
|
263 |
+
public function __destruct()
|
264 |
+
{
|
265 |
+
if ($this->socket) $this->close();
|
266 |
+
}
|
267 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Socket.php
ADDED
@@ -0,0 +1,531 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client_Adapter
|
19 |
+
* @version $Id: Socket.php 19219 2009-11-24 22:25:36Z stas $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @see Microsoft_Uri_Http
|
26 |
+
*/
|
27 |
+
require_once 'Microsoft/Uri/Http.php';
|
28 |
+
/**
|
29 |
+
* @see Microsoft_Http_Client_Adapter_Interface
|
30 |
+
*/
|
31 |
+
require_once 'Microsoft/Http/Client/Adapter/Interface.php';
|
32 |
+
/**
|
33 |
+
* @see Microsoft_Http_Client_Adapter_Stream
|
34 |
+
*/
|
35 |
+
require_once 'Microsoft/Http/Client/Adapter/Stream.php';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* A sockets based (stream_socket_client) adapter class for Microsoft_Http_Client. Can be used
|
39 |
+
* on almost every PHP environment, and does not require any special extensions.
|
40 |
+
*
|
41 |
+
* @category Microsoft
|
42 |
+
* @package Microsoft_Http
|
43 |
+
* @subpackage Client_Adapter
|
44 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
45 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
46 |
+
*/
|
47 |
+
class Microsoft_Http_Client_Adapter_Socket implements Microsoft_Http_Client_Adapter_Interface, Microsoft_Http_Client_Adapter_Stream
|
48 |
+
{
|
49 |
+
/**
|
50 |
+
* The socket for server connection
|
51 |
+
*
|
52 |
+
* @var resource|null
|
53 |
+
*/
|
54 |
+
protected $socket = null;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* What host/port are we connected to?
|
58 |
+
*
|
59 |
+
* @var array
|
60 |
+
*/
|
61 |
+
protected $connected_to = array(null, null);
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Stream for storing output
|
65 |
+
*
|
66 |
+
* @var resource
|
67 |
+
*/
|
68 |
+
protected $out_stream = null;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Parameters array
|
72 |
+
*
|
73 |
+
* @var array
|
74 |
+
*/
|
75 |
+
protected $config = array(
|
76 |
+
'persistent' => false,
|
77 |
+
'ssltransport' => 'ssl',
|
78 |
+
'sslcert' => null,
|
79 |
+
'sslpassphrase' => null
|
80 |
+
);
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Request method - will be set by write() and might be used by read()
|
84 |
+
*
|
85 |
+
* @var string
|
86 |
+
*/
|
87 |
+
protected $method = null;
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Stream context
|
91 |
+
*
|
92 |
+
* @var resource
|
93 |
+
*/
|
94 |
+
protected $_context = null;
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Adapter constructor, currently empty. Config is set using setConfig()
|
98 |
+
*
|
99 |
+
*/
|
100 |
+
public function __construct()
|
101 |
+
{
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Set the configuration array for the adapter
|
106 |
+
*
|
107 |
+
* @param array $config
|
108 |
+
*/
|
109 |
+
public function setConfig($config = array())
|
110 |
+
{
|
111 |
+
if (! is_array($config)) {
|
112 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
113 |
+
throw new Microsoft_Http_Client_Adapter_Exception(
|
114 |
+
'Array expected, got ' . gettype($config)
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
foreach ($config as $k => $v) {
|
119 |
+
$this->config[strtolower($k)] = $v;
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* Retrieve the array of all configuration options
|
125 |
+
*
|
126 |
+
* @return array
|
127 |
+
*/
|
128 |
+
public function getConfig()
|
129 |
+
{
|
130 |
+
return $this->config;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Set the stream context for the TCP connection to the server
|
135 |
+
*
|
136 |
+
* Can accept either a pre-existing stream context resource, or an array
|
137 |
+
* of stream options, similar to the options array passed to the
|
138 |
+
* stream_context_create() PHP function. In such case a new stream context
|
139 |
+
* will be created using the passed options.
|
140 |
+
*
|
141 |
+
* @since Zend Framework 1.9
|
142 |
+
*
|
143 |
+
* @param mixed $context Stream context or array of context options
|
144 |
+
* @return Microsoft_Http_Client_Adapter_Socket
|
145 |
+
*/
|
146 |
+
public function setStreamContext($context)
|
147 |
+
{
|
148 |
+
if (is_resource($context) && get_resource_type($context) == 'stream-context') {
|
149 |
+
$this->_context = $context;
|
150 |
+
|
151 |
+
} elseif (is_array($context)) {
|
152 |
+
$this->_context = stream_context_create($context);
|
153 |
+
|
154 |
+
} else {
|
155 |
+
// Invalid parameter
|
156 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
157 |
+
throw new Microsoft_Http_Client_Adapter_Exception(
|
158 |
+
"Expecting either a stream context resource or array, got " . gettype($context)
|
159 |
+
);
|
160 |
+
}
|
161 |
+
|
162 |
+
return $this;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Get the stream context for the TCP connection to the server.
|
167 |
+
*
|
168 |
+
* If no stream context is set, will create a default one.
|
169 |
+
*
|
170 |
+
* @return resource
|
171 |
+
*/
|
172 |
+
public function getStreamContext()
|
173 |
+
{
|
174 |
+
if (! $this->_context) {
|
175 |
+
$this->_context = stream_context_create();
|
176 |
+
}
|
177 |
+
|
178 |
+
return $this->_context;
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Connect to the remote server
|
183 |
+
*
|
184 |
+
* @param string $host
|
185 |
+
* @param int $port
|
186 |
+
* @param boolean $secure
|
187 |
+
*/
|
188 |
+
public function connect($host, $port = 80, $secure = false)
|
189 |
+
{
|
190 |
+
// If the URI should be accessed via SSL, prepend the Hostname with ssl://
|
191 |
+
$host = ($secure ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
|
192 |
+
|
193 |
+
// If we are connected to the wrong host, disconnect first
|
194 |
+
if (($this->connected_to[0] != $host || $this->connected_to[1] != $port)) {
|
195 |
+
if (is_resource($this->socket)) $this->close();
|
196 |
+
}
|
197 |
+
|
198 |
+
// Now, if we are not connected, connect
|
199 |
+
if (! is_resource($this->socket) || ! $this->config['keepalive']) {
|
200 |
+
$context = $this->getStreamContext();
|
201 |
+
if ($secure) {
|
202 |
+
if ($this->config['sslcert'] !== null) {
|
203 |
+
if (! stream_context_set_option($context, 'ssl', 'local_cert',
|
204 |
+
$this->config['sslcert'])) {
|
205 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
206 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Unable to set sslcert option');
|
207 |
+
}
|
208 |
+
}
|
209 |
+
if ($this->config['sslpassphrase'] !== null) {
|
210 |
+
if (! stream_context_set_option($context, 'ssl', 'passphrase',
|
211 |
+
$this->config['sslpassphrase'])) {
|
212 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
213 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Unable to set sslpassphrase option');
|
214 |
+
}
|
215 |
+
}
|
216 |
+
}
|
217 |
+
|
218 |
+
$flags = STREAM_CLIENT_CONNECT;
|
219 |
+
if ($this->config['persistent']) $flags |= STREAM_CLIENT_PERSISTENT;
|
220 |
+
|
221 |
+
$this->socket = @stream_socket_client($host . ':' . $port,
|
222 |
+
$errno,
|
223 |
+
$errstr,
|
224 |
+
(int) $this->config['timeout'],
|
225 |
+
$flags,
|
226 |
+
$context);
|
227 |
+
|
228 |
+
if (! $this->socket) {
|
229 |
+
$this->close();
|
230 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
231 |
+
throw new Microsoft_Http_Client_Adapter_Exception(
|
232 |
+
'Unable to Connect to ' . $host . ':' . $port . '. Error #' . $errno . ': ' . $errstr);
|
233 |
+
}
|
234 |
+
|
235 |
+
// Set the stream timeout
|
236 |
+
if (! stream_set_timeout($this->socket, (int) $this->config['timeout'])) {
|
237 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
238 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Unable to set the connection timeout');
|
239 |
+
}
|
240 |
+
|
241 |
+
// Update connected_to
|
242 |
+
$this->connected_to = array($host, $port);
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
/**
|
247 |
+
* Send request to the remote server
|
248 |
+
*
|
249 |
+
* @param string $method
|
250 |
+
* @param Microsoft_Uri_Http $uri
|
251 |
+
* @param string $http_ver
|
252 |
+
* @param array $headers
|
253 |
+
* @param string $body
|
254 |
+
* @return string Request as string
|
255 |
+
*/
|
256 |
+
public function write($method, $uri, $http_ver = '1.1', $headers = array(), $body = '')
|
257 |
+
{
|
258 |
+
// Make sure we're properly connected
|
259 |
+
if (! $this->socket) {
|
260 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
261 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Trying to write but we are not connected');
|
262 |
+
}
|
263 |
+
|
264 |
+
$host = $uri->getHost();
|
265 |
+
$host = (strtolower($uri->getScheme()) == 'https' ? $this->config['ssltransport'] : 'tcp') . '://' . $host;
|
266 |
+
if ($this->connected_to[0] != $host || $this->connected_to[1] != $uri->getPort()) {
|
267 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
268 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Trying to write but we are connected to the wrong host');
|
269 |
+
}
|
270 |
+
|
271 |
+
// Save request method for later
|
272 |
+
$this->method = $method;
|
273 |
+
|
274 |
+
// Build request headers
|
275 |
+
$path = $uri->getPath();
|
276 |
+
if ($uri->getQuery()) $path .= '?' . $uri->getQuery();
|
277 |
+
$request = "{$method} {$path} HTTP/{$http_ver}\r\n";
|
278 |
+
foreach ($headers as $k => $v) {
|
279 |
+
if (is_string($k)) $v = ucfirst($k) . ": $v";
|
280 |
+
$request .= "$v\r\n";
|
281 |
+
}
|
282 |
+
|
283 |
+
if(is_resource($body)) {
|
284 |
+
$request .= "\r\n";
|
285 |
+
} else {
|
286 |
+
// Add the request body
|
287 |
+
$request .= "\r\n" . $body;
|
288 |
+
}
|
289 |
+
|
290 |
+
// Send the request
|
291 |
+
if (! @fwrite($this->socket, $request)) {
|
292 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
293 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Error writing request to server');
|
294 |
+
}
|
295 |
+
|
296 |
+
if(is_resource($body)) {
|
297 |
+
if(stream_copy_to_stream($body, $this->socket) == 0) {
|
298 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
299 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Error writing request to server');
|
300 |
+
}
|
301 |
+
}
|
302 |
+
|
303 |
+
return $request;
|
304 |
+
}
|
305 |
+
|
306 |
+
/**
|
307 |
+
* Read response from server
|
308 |
+
*
|
309 |
+
* @return string
|
310 |
+
*/
|
311 |
+
public function read()
|
312 |
+
{
|
313 |
+
// First, read headers only
|
314 |
+
$response = '';
|
315 |
+
$gotStatus = false;
|
316 |
+
$stream = !empty($this->config['stream']);
|
317 |
+
|
318 |
+
while (($line = @fgets($this->socket)) !== false) {
|
319 |
+
$gotStatus = $gotStatus || (strpos($line, 'HTTP') !== false);
|
320 |
+
if ($gotStatus) {
|
321 |
+
$response .= $line;
|
322 |
+
if (rtrim($line) === '') break;
|
323 |
+
}
|
324 |
+
}
|
325 |
+
|
326 |
+
$this->_checkSocketReadTimeout();
|
327 |
+
|
328 |
+
$statusCode = Microsoft_Http_Response::extractCode($response);
|
329 |
+
|
330 |
+
// Handle 100 and 101 responses internally by restarting the read again
|
331 |
+
if ($statusCode == 100 || $statusCode == 101) return $this->read();
|
332 |
+
|
333 |
+
// Check headers to see what kind of connection / transfer encoding we have
|
334 |
+
$headers = Microsoft_Http_Response::extractHeaders($response);
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Responses to HEAD requests and 204 or 304 responses are not expected
|
338 |
+
* to have a body - stop reading here
|
339 |
+
*/
|
340 |
+
if ($statusCode == 304 || $statusCode == 204 ||
|
341 |
+
$this->method == Microsoft_Http_Client::HEAD) {
|
342 |
+
|
343 |
+
// Close the connection if requested to do so by the server
|
344 |
+
if (isset($headers['connection']) && $headers['connection'] == 'close') {
|
345 |
+
$this->close();
|
346 |
+
}
|
347 |
+
return $response;
|
348 |
+
}
|
349 |
+
|
350 |
+
// If we got a 'transfer-encoding: chunked' header
|
351 |
+
if (isset($headers['transfer-encoding'])) {
|
352 |
+
|
353 |
+
if (strtolower($headers['transfer-encoding']) == 'chunked') {
|
354 |
+
|
355 |
+
do {
|
356 |
+
$line = @fgets($this->socket);
|
357 |
+
$this->_checkSocketReadTimeout();
|
358 |
+
|
359 |
+
$chunk = $line;
|
360 |
+
|
361 |
+
// Figure out the next chunk size
|
362 |
+
$chunksize = trim($line);
|
363 |
+
if (! ctype_xdigit($chunksize)) {
|
364 |
+
$this->close();
|
365 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
366 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Invalid chunk size "' .
|
367 |
+
$chunksize . '" unable to read chunked body');
|
368 |
+
}
|
369 |
+
|
370 |
+
// Convert the hexadecimal value to plain integer
|
371 |
+
$chunksize = hexdec($chunksize);
|
372 |
+
|
373 |
+
// Read next chunk
|
374 |
+
$read_to = ftell($this->socket) + $chunksize;
|
375 |
+
|
376 |
+
do {
|
377 |
+
$current_pos = ftell($this->socket);
|
378 |
+
if ($current_pos >= $read_to) break;
|
379 |
+
|
380 |
+
if($this->out_stream) {
|
381 |
+
if(stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
|
382 |
+
$this->_checkSocketReadTimeout();
|
383 |
+
break;
|
384 |
+
}
|
385 |
+
} else {
|
386 |
+
$line = @fread($this->socket, $read_to - $current_pos);
|
387 |
+
if ($line === false || strlen($line) === 0) {
|
388 |
+
$this->_checkSocketReadTimeout();
|
389 |
+
break;
|
390 |
+
}
|
391 |
+
$chunk .= $line;
|
392 |
+
}
|
393 |
+
} while (! feof($this->socket));
|
394 |
+
|
395 |
+
$chunk .= @fgets($this->socket);
|
396 |
+
$this->_checkSocketReadTimeout();
|
397 |
+
|
398 |
+
if(!$this->out_stream) {
|
399 |
+
$response .= $chunk;
|
400 |
+
}
|
401 |
+
} while ($chunksize > 0);
|
402 |
+
} else {
|
403 |
+
$this->close();
|
404 |
+
throw new Microsoft_Http_Client_Adapter_Exception('Cannot handle "' .
|
405 |
+
$headers['transfer-encoding'] . '" transfer encoding');
|
406 |
+
}
|
407 |
+
|
408 |
+
// We automatically decode chunked-messages when writing to a stream
|
409 |
+
// this means we have to disallow the Microsoft_Http_Response to do it again
|
410 |
+
if ($this->out_stream) {
|
411 |
+
$response = str_ireplace("Transfer-Encoding: chunked\r\n", '', $response);
|
412 |
+
}
|
413 |
+
// Else, if we got the content-length header, read this number of bytes
|
414 |
+
} elseif (isset($headers['content-length'])) {
|
415 |
+
|
416 |
+
$current_pos = ftell($this->socket);
|
417 |
+
$chunk = '';
|
418 |
+
|
419 |
+
for ($read_to = $current_pos + $headers['content-length'];
|
420 |
+
$read_to > $current_pos;
|
421 |
+
$current_pos = ftell($this->socket)) {
|
422 |
+
|
423 |
+
if($this->out_stream) {
|
424 |
+
if(@stream_copy_to_stream($this->socket, $this->out_stream, $read_to - $current_pos) == 0) {
|
425 |
+
$this->_checkSocketReadTimeout();
|
426 |
+
break;
|
427 |
+
}
|
428 |
+
} else {
|
429 |
+
$chunk = @fread($this->socket, $read_to - $current_pos);
|
430 |
+
if ($chunk === false || strlen($chunk) === 0) {
|
431 |
+
$this->_checkSocketReadTimeout();
|
432 |
+
break;
|
433 |
+
}
|
434 |
+
|
435 |
+
$response .= $chunk;
|
436 |
+
}
|
437 |
+
|
438 |
+
// Break if the connection ended prematurely
|
439 |
+
if (feof($this->socket)) break;
|
440 |
+
}
|
441 |
+
|
442 |
+
// Fallback: just read the response until EOF
|
443 |
+
} else {
|
444 |
+
|
445 |
+
do {
|
446 |
+
if($this->out_stream) {
|
447 |
+
if(@stream_copy_to_stream($this->socket, $this->out_stream) == 0) {
|
448 |
+
$this->_checkSocketReadTimeout();
|
449 |
+
break;
|
450 |
+
}
|
451 |
+
} else {
|
452 |
+
$buff = @fread($this->socket, 8192);
|
453 |
+
if ($buff === false || strlen($buff) === 0) {
|
454 |
+
$this->_checkSocketReadTimeout();
|
455 |
+
break;
|
456 |
+
} else {
|
457 |
+
$response .= $buff;
|
458 |
+
}
|
459 |
+
}
|
460 |
+
|
461 |
+
} while (feof($this->socket) === false);
|
462 |
+
|
463 |
+
$this->close();
|
464 |
+
}
|
465 |
+
|
466 |
+
// Close the connection if requested to do so by the server
|
467 |
+
if (isset($headers['connection']) && $headers['connection'] == 'close') {
|
468 |
+
$this->close();
|
469 |
+
}
|
470 |
+
|
471 |
+
return $response;
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Close the connection to the server
|
476 |
+
*
|
477 |
+
*/
|
478 |
+
public function close()
|
479 |
+
{
|
480 |
+
if (is_resource($this->socket)) @fclose($this->socket);
|
481 |
+
$this->socket = null;
|
482 |
+
$this->connected_to = array(null, null);
|
483 |
+
}
|
484 |
+
|
485 |
+
/**
|
486 |
+
* Check if the socket has timed out - if so close connection and throw
|
487 |
+
* an exception
|
488 |
+
*
|
489 |
+
* @throws Microsoft_Http_Client_Adapter_Exception with READ_TIMEOUT code
|
490 |
+
*/
|
491 |
+
protected function _checkSocketReadTimeout()
|
492 |
+
{
|
493 |
+
if ($this->socket) {
|
494 |
+
$info = stream_get_meta_data($this->socket);
|
495 |
+
$timedout = $info['timed_out'];
|
496 |
+
if ($timedout) {
|
497 |
+
$this->close();
|
498 |
+
require_once 'Microsoft/Http/Client/Adapter/Exception.php';
|
499 |
+
throw new Microsoft_Http_Client_Adapter_Exception(
|
500 |
+
"Read timed out after {$this->config['timeout']} seconds",
|
501 |
+
Microsoft_Http_Client_Adapter_Exception::READ_TIMEOUT
|
502 |
+
);
|
503 |
+
}
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
/**
|
508 |
+
* Set output stream for the response
|
509 |
+
*
|
510 |
+
* @param resource $stream
|
511 |
+
* @return Microsoft_Http_Client_Adapter_Socket
|
512 |
+
*/
|
513 |
+
public function setOutputStream($stream)
|
514 |
+
{
|
515 |
+
$this->out_stream = $stream;
|
516 |
+
return $this;
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Destructor: make sure the socket is disconnected
|
521 |
+
*
|
522 |
+
* If we are in persistent TCP mode, will not close the connection
|
523 |
+
*
|
524 |
+
*/
|
525 |
+
public function __destruct()
|
526 |
+
{
|
527 |
+
if (! $this->config['persistent']) {
|
528 |
+
if ($this->socket) $this->close();
|
529 |
+
}
|
530 |
+
}
|
531 |
+
}
|
app/libs/Microsoft/Http/Client/Adapter/Stream.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Client_Adapter
|
19 |
+
* @version $Id: Interface.php 16214 2009-06-21 19:34:03Z thomas $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* An interface description for Microsoft_Http_Client_Adapter_Stream classes.
|
26 |
+
*
|
27 |
+
* This interface decribes Microsoft_Http_Client_Adapter which supports streaming.
|
28 |
+
*
|
29 |
+
* @category Microsoft
|
30 |
+
* @package Microsoft_Http
|
31 |
+
* @subpackage Client_Adapter
|
32 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
33 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
34 |
+
*/
|
35 |
+
interface Microsoft_Http_Client_Adapter_Stream
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Set output stream
|
39 |
+
*
|
40 |
+
* This function sets output stream where the result will be stored.
|
41 |
+
*
|
42 |
+
* @param resource $stream Stream to write the output to
|
43 |
+
*
|
44 |
+
*/
|
45 |
+
function setOutputStream($stream);
|
46 |
+
}
|
app/libs/Microsoft/Http/Client/Exception.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Http
|
17 |
+
* @subpackage Client_Exception
|
18 |
+
* @version $Id: Exception.php 16872 2009-07-20 11:47:08Z mikaelkael $
|
19 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
20 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
21 |
+
*/
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @see Microsoft_Http_Exception
|
25 |
+
*/
|
26 |
+
require_once 'Microsoft/Http/Exception.php';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @category Microsoft
|
30 |
+
* @package Microsoft_Http
|
31 |
+
* @subpackage Client
|
32 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
33 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
34 |
+
*/
|
35 |
+
class Microsoft_Http_Client_Exception extends Microsoft_Http_Exception
|
36 |
+
{}
|
app/libs/Microsoft/Http/Cookie.php
ADDED
@@ -0,0 +1,408 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Cookie
|
19 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
20 |
+
* @version $Id: Cookie.php 17131 2009-07-26 10:03:39Z shahar $
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* @see Microsoft_Uri_Http
|
26 |
+
*/
|
27 |
+
require_once 'Microsoft/Uri/Http.php';
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Microsoft_Http_Cookie is a class describing an HTTP cookie and all it's parameters.
|
32 |
+
*
|
33 |
+
* Microsoft_Http_Cookie is a class describing an HTTP cookie and all it's parameters. The
|
34 |
+
* class also enables validating whether the cookie should be sent to the server in
|
35 |
+
* a specified scenario according to the request URI, the expiry time and whether
|
36 |
+
* session cookies should be used or not. Generally speaking cookies should be
|
37 |
+
* contained in a Cookiejar object, or instantiated manually and added to an HTTP
|
38 |
+
* request.
|
39 |
+
*
|
40 |
+
* See http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
|
41 |
+
*
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_Http
|
44 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
45 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
46 |
+
*/
|
47 |
+
class Microsoft_Http_Cookie
|
48 |
+
{
|
49 |
+
/**
|
50 |
+
* Cookie name
|
51 |
+
*
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
protected $name;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Cookie value
|
58 |
+
*
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
protected $value;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Cookie expiry date
|
65 |
+
*
|
66 |
+
* @var int
|
67 |
+
*/
|
68 |
+
protected $expires;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Cookie domain
|
72 |
+
*
|
73 |
+
* @var string
|
74 |
+
*/
|
75 |
+
protected $domain;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Cookie path
|
79 |
+
*
|
80 |
+
* @var string
|
81 |
+
*/
|
82 |
+
protected $path;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Whether the cookie is secure or not
|
86 |
+
*
|
87 |
+
* @var boolean
|
88 |
+
*/
|
89 |
+
protected $secure;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Cookie object constructor
|
93 |
+
*
|
94 |
+
* @todo Add validation of each one of the parameters (legal domain, etc.)
|
95 |
+
*
|
96 |
+
* @param string $name
|
97 |
+
* @param string $value
|
98 |
+
* @param string $domain
|
99 |
+
* @param int $expires
|
100 |
+
* @param string $path
|
101 |
+
* @param bool $secure
|
102 |
+
*/
|
103 |
+
public function __construct($name, $value, $domain, $expires = null, $path = null, $secure = false)
|
104 |
+
{
|
105 |
+
if (preg_match("/[=,; \t\r\n\013\014]/", $name)) {
|
106 |
+
require_once 'Microsoft/Http/Exception.php';
|
107 |
+
throw new Microsoft_Http_Exception("Cookie name cannot contain these characters: =,; \\t\\r\\n\\013\\014 ({$name})");
|
108 |
+
}
|
109 |
+
|
110 |
+
if (! $this->name = (string) $name) {
|
111 |
+
require_once 'Microsoft/Http/Exception.php';
|
112 |
+
throw new Microsoft_Http_Exception('Cookies must have a name');
|
113 |
+
}
|
114 |
+
|
115 |
+
if (! $this->domain = (string) $domain) {
|
116 |
+
require_once 'Microsoft/Http/Exception.php';
|
117 |
+
throw new Microsoft_Http_Exception('Cookies must have a domain');
|
118 |
+
}
|
119 |
+
|
120 |
+
$this->value = (string) $value;
|
121 |
+
$this->expires = ($expires === null ? null : (int) $expires);
|
122 |
+
$this->path = ($path ? $path : '/');
|
123 |
+
$this->secure = $secure;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Get Cookie name
|
128 |
+
*
|
129 |
+
* @return string
|
130 |
+
*/
|
131 |
+
public function getName()
|
132 |
+
{
|
133 |
+
return $this->name;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Get cookie value
|
138 |
+
*
|
139 |
+
* @return string
|
140 |
+
*/
|
141 |
+
public function getValue()
|
142 |
+
{
|
143 |
+
return $this->value;
|
144 |
+
}
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Get cookie domain
|
148 |
+
*
|
149 |
+
* @return string
|
150 |
+
*/
|
151 |
+
public function getDomain()
|
152 |
+
{
|
153 |
+
return $this->domain;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Get the cookie path
|
158 |
+
*
|
159 |
+
* @return string
|
160 |
+
*/
|
161 |
+
public function getPath()
|
162 |
+
{
|
163 |
+
return $this->path;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Get the expiry time of the cookie, or null if no expiry time is set
|
168 |
+
*
|
169 |
+
* @return int|null
|
170 |
+
*/
|
171 |
+
public function getExpiryTime()
|
172 |
+
{
|
173 |
+
return $this->expires;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Check whether the cookie should only be sent over secure connections
|
178 |
+
*
|
179 |
+
* @return boolean
|
180 |
+
*/
|
181 |
+
public function isSecure()
|
182 |
+
{
|
183 |
+
return $this->secure;
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Check whether the cookie has expired
|
188 |
+
*
|
189 |
+
* Always returns false if the cookie is a session cookie (has no expiry time)
|
190 |
+
*
|
191 |
+
* @param int $now Timestamp to consider as "now"
|
192 |
+
* @return boolean
|
193 |
+
*/
|
194 |
+
public function isExpired($now = null)
|
195 |
+
{
|
196 |
+
if ($now === null) $now = time();
|
197 |
+
if (is_int($this->expires) && $this->expires < $now) {
|
198 |
+
return true;
|
199 |
+
} else {
|
200 |
+
return false;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Check whether the cookie is a session cookie (has no expiry time set)
|
206 |
+
*
|
207 |
+
* @return boolean
|
208 |
+
*/
|
209 |
+
public function isSessionCookie()
|
210 |
+
{
|
211 |
+
return ($this->expires === null);
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Checks whether the cookie should be sent or not in a specific scenario
|
216 |
+
*
|
217 |
+
* @param string|Microsoft_Uri_Http $uri URI to check against (secure, domain, path)
|
218 |
+
* @param boolean $matchSessionCookies Whether to send session cookies
|
219 |
+
* @param int $now Override the current time when checking for expiry time
|
220 |
+
* @return boolean
|
221 |
+
*/
|
222 |
+
public function match($uri, $matchSessionCookies = true, $now = null)
|
223 |
+
{
|
224 |
+
if (is_string ($uri)) {
|
225 |
+
$uri = Microsoft_Uri_Http::factory($uri);
|
226 |
+
}
|
227 |
+
|
228 |
+
// Make sure we have a valid Microsoft_Uri_Http object
|
229 |
+
if (! ($uri->valid() && ($uri->getScheme() == 'http' || $uri->getScheme() =='https'))) {
|
230 |
+
require_once 'Microsoft/Http/Exception.php';
|
231 |
+
throw new Microsoft_Http_Exception('Passed URI is not a valid HTTP or HTTPS URI');
|
232 |
+
}
|
233 |
+
|
234 |
+
// Check that the cookie is secure (if required) and not expired
|
235 |
+
if ($this->secure && $uri->getScheme() != 'https') return false;
|
236 |
+
if ($this->isExpired($now)) return false;
|
237 |
+
if ($this->isSessionCookie() && ! $matchSessionCookies) return false;
|
238 |
+
|
239 |
+
// Check if the domain matches
|
240 |
+
if (! self::matchCookieDomain($this->getDomain(), $uri->getHost())) {
|
241 |
+
return false;
|
242 |
+
}
|
243 |
+
|
244 |
+
// Check that path matches using prefix match
|
245 |
+
if (! self::matchCookiePath($this->getPath(), $uri->getPath())) {
|
246 |
+
return false;
|
247 |
+
}
|
248 |
+
|
249 |
+
// If we didn't die until now, return true.
|
250 |
+
return true;
|
251 |
+
}
|
252 |
+
|
253 |
+
/**
|
254 |
+
* Get the cookie as a string, suitable for sending as a "Cookie" header in an
|
255 |
+
* HTTP request
|
256 |
+
*
|
257 |
+
* @return string
|
258 |
+
*/
|
259 |
+
public function __toString()
|
260 |
+
{
|
261 |
+
return $this->name . '=' . urlencode($this->value) . ';';
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* Generate a new Cookie object from a cookie string
|
266 |
+
* (for example the value of the Set-Cookie HTTP header)
|
267 |
+
*
|
268 |
+
* @param string $cookieStr
|
269 |
+
* @param Microsoft_Uri_Http|string $ref_uri Reference URI for default values (domain, path)
|
270 |
+
* @return Microsoft_Http_Cookie A new Microsoft_Http_Cookie object or false on failure.
|
271 |
+
*/
|
272 |
+
public static function fromString($cookieStr, $ref_uri = null)
|
273 |
+
{
|
274 |
+
// Set default values
|
275 |
+
if (is_string($ref_uri)) {
|
276 |
+
$ref_uri = Microsoft_Uri_Http::factory($ref_uri);
|
277 |
+
}
|
278 |
+
|
279 |
+
$name = '';
|
280 |
+
$value = '';
|
281 |
+
$domain = '';
|
282 |
+
$path = '';
|
283 |
+
$expires = null;
|
284 |
+
$secure = false;
|
285 |
+
$parts = explode(';', $cookieStr);
|
286 |
+
|
287 |
+
// If first part does not include '=', fail
|
288 |
+
if (strpos($parts[0], '=') === false) return false;
|
289 |
+
|
290 |
+
// Get the name and value of the cookie
|
291 |
+
list($name, $value) = explode('=', trim(array_shift($parts)), 2);
|
292 |
+
$name = trim($name);
|
293 |
+
$value = urldecode(trim($value));
|
294 |
+
|
295 |
+
// Set default domain and path
|
296 |
+
if ($ref_uri instanceof Microsoft_Uri_Http) {
|
297 |
+
$domain = $ref_uri->getHost();
|
298 |
+
$path = $ref_uri->getPath();
|
299 |
+
$path = substr($path, 0, strrpos($path, '/'));
|
300 |
+
}
|
301 |
+
|
302 |
+
// Set other cookie parameters
|
303 |
+
foreach ($parts as $part) {
|
304 |
+
$part = trim($part);
|
305 |
+
if (strtolower($part) == 'secure') {
|
306 |
+
$secure = true;
|
307 |
+
continue;
|
308 |
+
}
|
309 |
+
|
310 |
+
$keyValue = explode('=', $part, 2);
|
311 |
+
if (count($keyValue) == 2) {
|
312 |
+
list($k, $v) = $keyValue;
|
313 |
+
switch (strtolower($k)) {
|
314 |
+
case 'expires':
|
315 |
+
if(($expires = strtotime($v)) === false) {
|
316 |
+
/**
|
317 |
+
* The expiration is past Tue, 19 Jan 2038 03:14:07 UTC
|
318 |
+
* the maximum for 32-bit signed integer. Microsoft_Date
|
319 |
+
* can get around that limit.
|
320 |
+
*
|
321 |
+
* @see Microsoft_Date
|
322 |
+
*/
|
323 |
+
require_once 'Microsoft/Date.php';
|
324 |
+
|
325 |
+
$expireDate = new Microsoft_Date($v);
|
326 |
+
$expires = $expireDate->getTimestamp();
|
327 |
+
}
|
328 |
+
break;
|
329 |
+
|
330 |
+
case 'path':
|
331 |
+
$path = $v;
|
332 |
+
break;
|
333 |
+
|
334 |
+
case 'domain':
|
335 |
+
$domain = $v;
|
336 |
+
break;
|
337 |
+
|
338 |
+
default:
|
339 |
+
break;
|
340 |
+
}
|
341 |
+
}
|
342 |
+
}
|
343 |
+
|
344 |
+
if ($name !== '') {
|
345 |
+
return new self($name, $value, $domain, $expires, $path, $secure);
|
346 |
+
} else {
|
347 |
+
return false;
|
348 |
+
}
|
349 |
+
}
|
350 |
+
|
351 |
+
/**
|
352 |
+
* Check if a cookie's domain matches a host name.
|
353 |
+
*
|
354 |
+
* Used by Microsoft_Http_Cookie and Microsoft_Http_CookieJar for cookie matching
|
355 |
+
*
|
356 |
+
* @param string $cookieDomain
|
357 |
+
* @param string $host
|
358 |
+
*
|
359 |
+
* @return boolean
|
360 |
+
*/
|
361 |
+
public static function matchCookieDomain($cookieDomain, $host)
|
362 |
+
{
|
363 |
+
if (! $cookieDomain) {
|
364 |
+
require_once 'Microsoft/Http/Exception.php';
|
365 |
+
throw new Microsoft_Http_Exception("\$cookieDomain is expected to be a cookie domain");
|
366 |
+
}
|
367 |
+
|
368 |
+
if (! $host) {
|
369 |
+
require_once 'Microsoft/Http/Exception.php';
|
370 |
+
throw new Microsoft_Http_Exception("\$host is expected to be a host name");
|
371 |
+
}
|
372 |
+
|
373 |
+
$cookieDomain = strtolower($cookieDomain);
|
374 |
+
$host = strtolower($host);
|
375 |
+
|
376 |
+
if ($cookieDomain[0] == '.') {
|
377 |
+
$cookieDomain = substr($cookieDomain, 1);
|
378 |
+
}
|
379 |
+
|
380 |
+
// Check for either exact match or suffix match
|
381 |
+
return ($cookieDomain == $host ||
|
382 |
+
preg_match("/\.$cookieDomain$/", $host));
|
383 |
+
}
|
384 |
+
|
385 |
+
/**
|
386 |
+
* Check if a cookie's path matches a URL path
|
387 |
+
*
|
388 |
+
* Used by Microsoft_Http_Cookie and Microsoft_Http_CookieJar for cookie matching
|
389 |
+
*
|
390 |
+
* @param string $cookiePath
|
391 |
+
* @param string $path
|
392 |
+
* @return boolean
|
393 |
+
*/
|
394 |
+
public static function matchCookiePath($cookiePath, $path)
|
395 |
+
{
|
396 |
+
if (! $cookiePath) {
|
397 |
+
require_once 'Microsoft/Http/Exception.php';
|
398 |
+
throw new Microsoft_Http_Exception("\$cookiePath is expected to be a cookie path");
|
399 |
+
}
|
400 |
+
|
401 |
+
if (! $path) {
|
402 |
+
require_once 'Microsoft/Http/Exception.php';
|
403 |
+
throw new Microsoft_Http_Exception("\$path is expected to be a host name");
|
404 |
+
}
|
405 |
+
|
406 |
+
return (strpos($path, $cookiePath) === 0);
|
407 |
+
}
|
408 |
+
}
|
app/libs/Microsoft/Http/CookieJar.php
ADDED
@@ -0,0 +1,403 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Http
|
17 |
+
* @subpackage CookieJar
|
18 |
+
* @version $Id: CookieJar.php 17131 2009-07-26 10:03:39Z shahar $
|
19 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
20 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
21 |
+
*/
|
22 |
+
|
23 |
+
/**
|
24 |
+
* @see Microsoft_Uri
|
25 |
+
*/
|
26 |
+
require_once "Microsoft/Uri.php";
|
27 |
+
/**
|
28 |
+
* @see Microsoft_Http_Cookie
|
29 |
+
*/
|
30 |
+
require_once "Microsoft/Http/Cookie.php";
|
31 |
+
/**
|
32 |
+
* @see Microsoft_Http_Response
|
33 |
+
*/
|
34 |
+
require_once "Microsoft/Http/Response.php";
|
35 |
+
|
36 |
+
/**
|
37 |
+
* A Microsoft_Http_CookieJar object is designed to contain and maintain HTTP cookies, and should
|
38 |
+
* be used along with Microsoft_Http_Client in order to manage cookies across HTTP requests and
|
39 |
+
* responses.
|
40 |
+
*
|
41 |
+
* The class contains an array of Microsoft_Http_Cookie objects. Cookies can be added to the jar
|
42 |
+
* automatically from a request or manually. Then, the jar can find and return the cookies
|
43 |
+
* needed for a specific HTTP request.
|
44 |
+
*
|
45 |
+
* A special parameter can be passed to all methods of this class that return cookies: Cookies
|
46 |
+
* can be returned either in their native form (as Microsoft_Http_Cookie objects) or as strings -
|
47 |
+
* the later is suitable for sending as the value of the "Cookie" header in an HTTP request.
|
48 |
+
* You can also choose, when returning more than one cookie, whether to get an array of strings
|
49 |
+
* (by passing Microsoft_Http_CookieJar::COOKIE_STRING_ARRAY) or one unified string for all cookies
|
50 |
+
* (by passing Microsoft_Http_CookieJar::COOKIE_STRING_CONCAT).
|
51 |
+
*
|
52 |
+
* @link http://wp.netscape.com/newsref/std/cookie_spec.html for some specs.
|
53 |
+
*
|
54 |
+
* @category Microsoft
|
55 |
+
* @package Microsoft_Http
|
56 |
+
* @subpackage CookieJar
|
57 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
58 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
59 |
+
*/
|
60 |
+
class Microsoft_Http_CookieJar implements Countable, IteratorAggregate
|
61 |
+
{
|
62 |
+
/**
|
63 |
+
* Return cookie(s) as a Microsoft_Http_Cookie object
|
64 |
+
*
|
65 |
+
*/
|
66 |
+
const COOKIE_OBJECT = 0;
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Return cookie(s) as a string (suitable for sending in an HTTP request)
|
70 |
+
*
|
71 |
+
*/
|
72 |
+
const COOKIE_STRING_ARRAY = 1;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Return all cookies as one long string (suitable for sending in an HTTP request)
|
76 |
+
*
|
77 |
+
*/
|
78 |
+
const COOKIE_STRING_CONCAT = 2;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Array storing cookies
|
82 |
+
*
|
83 |
+
* Cookies are stored according to domain and path:
|
84 |
+
* $cookies
|
85 |
+
* + www.mydomain.com
|
86 |
+
* + /
|
87 |
+
* - cookie1
|
88 |
+
* - cookie2
|
89 |
+
* + /somepath
|
90 |
+
* - othercookie
|
91 |
+
* + www.otherdomain.net
|
92 |
+
* + /
|
93 |
+
* - alsocookie
|
94 |
+
*
|
95 |
+
* @var array
|
96 |
+
*/
|
97 |
+
protected $cookies = array();
|
98 |
+
|
99 |
+
/**
|
100 |
+
* The Microsoft_Http_Cookie array
|
101 |
+
*
|
102 |
+
* @var array
|
103 |
+
*/
|
104 |
+
protected $_rawCookies = array();
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Construct a new CookieJar object
|
108 |
+
*
|
109 |
+
*/
|
110 |
+
public function __construct()
|
111 |
+
{ }
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Add a cookie to the jar. Cookie should be passed either as a Microsoft_Http_Cookie object
|
115 |
+
* or as a string - in which case an object is created from the string.
|
116 |
+
*
|
117 |
+
* @param Microsoft_Http_Cookie|string $cookie
|
118 |
+
* @param Microsoft_Uri_Http|string $ref_uri Optional reference URI (for domain, path, secure)
|
119 |
+
*/
|
120 |
+
public function addCookie($cookie, $ref_uri = null)
|
121 |
+
{
|
122 |
+
if (is_string($cookie)) {
|
123 |
+
$cookie = Microsoft_Http_Cookie::fromString($cookie, $ref_uri);
|
124 |
+
}
|
125 |
+
|
126 |
+
if ($cookie instanceof Microsoft_Http_Cookie) {
|
127 |
+
$domain = $cookie->getDomain();
|
128 |
+
$path = $cookie->getPath();
|
129 |
+
if (! isset($this->cookies[$domain])) $this->cookies[$domain] = array();
|
130 |
+
if (! isset($this->cookies[$domain][$path])) $this->cookies[$domain][$path] = array();
|
131 |
+
$this->cookies[$domain][$path][$cookie->getName()] = $cookie;
|
132 |
+
$this->_rawCookies[] = $cookie;
|
133 |
+
} else {
|
134 |
+
require_once 'Microsoft/Http/Exception.php';
|
135 |
+
throw new Microsoft_Http_Exception('Supplient argument is not a valid cookie string or object');
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Parse an HTTP response, adding all the cookies set in that response
|
141 |
+
* to the cookie jar.
|
142 |
+
*
|
143 |
+
* @param Microsoft_Http_Response $response
|
144 |
+
* @param Microsoft_Uri_Http|string $ref_uri Requested URI
|
145 |
+
*/
|
146 |
+
public function addCookiesFromResponse($response, $ref_uri)
|
147 |
+
{
|
148 |
+
if (! $response instanceof Microsoft_Http_Response) {
|
149 |
+
require_once 'Microsoft/Http/Exception.php';
|
150 |
+
throw new Microsoft_Http_Exception('$response is expected to be a Response object, ' .
|
151 |
+
gettype($response) . ' was passed');
|
152 |
+
}
|
153 |
+
|
154 |
+
$cookie_hdrs = $response->getHeader('Set-Cookie');
|
155 |
+
|
156 |
+
if (is_array($cookie_hdrs)) {
|
157 |
+
foreach ($cookie_hdrs as $cookie) {
|
158 |
+
$this->addCookie($cookie, $ref_uri);
|
159 |
+
}
|
160 |
+
} elseif (is_string($cookie_hdrs)) {
|
161 |
+
$this->addCookie($cookie_hdrs, $ref_uri);
|
162 |
+
}
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Get all cookies in the cookie jar as an array
|
167 |
+
*
|
168 |
+
* @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
|
169 |
+
* @return array|string
|
170 |
+
*/
|
171 |
+
public function getAllCookies($ret_as = self::COOKIE_OBJECT)
|
172 |
+
{
|
173 |
+
$cookies = $this->_flattenCookiesArray($this->cookies, $ret_as);
|
174 |
+
return $cookies;
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Return an array of all cookies matching a specific request according to the request URI,
|
179 |
+
* whether session cookies should be sent or not, and the time to consider as "now" when
|
180 |
+
* checking cookie expiry time.
|
181 |
+
*
|
182 |
+
* @param string|Microsoft_Uri_Http $uri URI to check against (secure, domain, path)
|
183 |
+
* @param boolean $matchSessionCookies Whether to send session cookies
|
184 |
+
* @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
|
185 |
+
* @param int $now Override the current time when checking for expiry time
|
186 |
+
* @return array|string
|
187 |
+
*/
|
188 |
+
public function getMatchingCookies($uri, $matchSessionCookies = true,
|
189 |
+
$ret_as = self::COOKIE_OBJECT, $now = null)
|
190 |
+
{
|
191 |
+
if (is_string($uri)) $uri = Microsoft_Uri::factory($uri);
|
192 |
+
if (! $uri instanceof Microsoft_Uri_Http) {
|
193 |
+
require_once 'Microsoft/Http/Exception.php';
|
194 |
+
throw new Microsoft_Http_Exception("Invalid URI string or object passed");
|
195 |
+
}
|
196 |
+
|
197 |
+
// First, reduce the array of cookies to only those matching domain and path
|
198 |
+
$cookies = $this->_matchDomain($uri->getHost());
|
199 |
+
$cookies = $this->_matchPath($cookies, $uri->getPath());
|
200 |
+
$cookies = $this->_flattenCookiesArray($cookies, self::COOKIE_OBJECT);
|
201 |
+
|
202 |
+
// Next, run Cookie->match on all cookies to check secure, time and session mathcing
|
203 |
+
$ret = array();
|
204 |
+
foreach ($cookies as $cookie)
|
205 |
+
if ($cookie->match($uri, $matchSessionCookies, $now))
|
206 |
+
$ret[] = $cookie;
|
207 |
+
|
208 |
+
// Now, use self::_flattenCookiesArray again - only to convert to the return format ;)
|
209 |
+
$ret = $this->_flattenCookiesArray($ret, $ret_as);
|
210 |
+
|
211 |
+
return $ret;
|
212 |
+
}
|
213 |
+
|
214 |
+
/**
|
215 |
+
* Get a specific cookie according to a URI and name
|
216 |
+
*
|
217 |
+
* @param Microsoft_Uri_Http|string $uri The uri (domain and path) to match
|
218 |
+
* @param string $cookie_name The cookie's name
|
219 |
+
* @param int $ret_as Whether to return cookies as objects of Microsoft_Http_Cookie or as strings
|
220 |
+
* @return Microsoft_Http_Cookie|string
|
221 |
+
*/
|
222 |
+
public function getCookie($uri, $cookie_name, $ret_as = self::COOKIE_OBJECT)
|
223 |
+
{
|
224 |
+
if (is_string($uri)) {
|
225 |
+
$uri = Microsoft_Uri::factory($uri);
|
226 |
+
}
|
227 |
+
|
228 |
+
if (! $uri instanceof Microsoft_Uri_Http) {
|
229 |
+
require_once 'Microsoft/Http/Exception.php';
|
230 |
+
throw new Microsoft_Http_Exception('Invalid URI specified');
|
231 |
+
}
|
232 |
+
|
233 |
+
// Get correct cookie path
|
234 |
+
$path = $uri->getPath();
|
235 |
+
$path = substr($path, 0, strrpos($path, '/'));
|
236 |
+
if (! $path) $path = '/';
|
237 |
+
|
238 |
+
if (isset($this->cookies[$uri->getHost()][$path][$cookie_name])) {
|
239 |
+
$cookie = $this->cookies[$uri->getHost()][$path][$cookie_name];
|
240 |
+
|
241 |
+
switch ($ret_as) {
|
242 |
+
case self::COOKIE_OBJECT:
|
243 |
+
return $cookie;
|
244 |
+
break;
|
245 |
+
|
246 |
+
case self::COOKIE_STRING_ARRAY:
|
247 |
+
case self::COOKIE_STRING_CONCAT:
|
248 |
+
return $cookie->__toString();
|
249 |
+
break;
|
250 |
+
|
251 |
+
default:
|
252 |
+
require_once 'Microsoft/Http/Exception.php';
|
253 |
+
throw new Microsoft_Http_Exception("Invalid value passed for \$ret_as: {$ret_as}");
|
254 |
+
break;
|
255 |
+
}
|
256 |
+
} else {
|
257 |
+
return false;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
|
261 |
+
/**
|
262 |
+
* Helper function to recursivly flatten an array. Shoud be used when exporting the
|
263 |
+
* cookies array (or parts of it)
|
264 |
+
*
|
265 |
+
* @param Microsoft_Http_Cookie|array $ptr
|
266 |
+
* @param int $ret_as What value to return
|
267 |
+
* @return array|string
|
268 |
+
*/
|
269 |
+
protected function _flattenCookiesArray($ptr, $ret_as = self::COOKIE_OBJECT) {
|
270 |
+
if (is_array($ptr)) {
|
271 |
+
$ret = ($ret_as == self::COOKIE_STRING_CONCAT ? '' : array());
|
272 |
+
foreach ($ptr as $item) {
|
273 |
+
if ($ret_as == self::COOKIE_STRING_CONCAT) {
|
274 |
+
$ret .= $this->_flattenCookiesArray($item, $ret_as);
|
275 |
+
} else {
|
276 |
+
$ret = array_merge($ret, $this->_flattenCookiesArray($item, $ret_as));
|
277 |
+
}
|
278 |
+
}
|
279 |
+
return $ret;
|
280 |
+
} elseif ($ptr instanceof Microsoft_Http_Cookie) {
|
281 |
+
switch ($ret_as) {
|
282 |
+
case self::COOKIE_STRING_ARRAY:
|
283 |
+
return array($ptr->__toString());
|
284 |
+
break;
|
285 |
+
|
286 |
+
case self::COOKIE_STRING_CONCAT:
|
287 |
+
return $ptr->__toString();
|
288 |
+
break;
|
289 |
+
|
290 |
+
case self::COOKIE_OBJECT:
|
291 |
+
default:
|
292 |
+
return array($ptr);
|
293 |
+
break;
|
294 |
+
}
|
295 |
+
}
|
296 |
+
|
297 |
+
return null;
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Return a subset of the cookies array matching a specific domain
|
302 |
+
*
|
303 |
+
* @param string $domain
|
304 |
+
* @return array
|
305 |
+
*/
|
306 |
+
protected function _matchDomain($domain)
|
307 |
+
{
|
308 |
+
$ret = array();
|
309 |
+
|
310 |
+
foreach (array_keys($this->cookies) as $cdom) {
|
311 |
+
if (Microsoft_Http_Cookie::matchCookieDomain($cdom, $domain)) {
|
312 |
+
$ret[$cdom] = $this->cookies[$cdom];
|
313 |
+
}
|
314 |
+
}
|
315 |
+
|
316 |
+
return $ret;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Return a subset of a domain-matching cookies that also match a specified path
|
321 |
+
*
|
322 |
+
* @param array $dom_array
|
323 |
+
* @param string $path
|
324 |
+
* @return array
|
325 |
+
*/
|
326 |
+
protected function _matchPath($domains, $path)
|
327 |
+
{
|
328 |
+
$ret = array();
|
329 |
+
|
330 |
+
foreach ($domains as $dom => $paths_array) {
|
331 |
+
foreach (array_keys($paths_array) as $cpath) {
|
332 |
+
if (Microsoft_Http_Cookie::matchCookiePath($cpath, $path)) {
|
333 |
+
if (! isset($ret[$dom])) {
|
334 |
+
$ret[$dom] = array();
|
335 |
+
}
|
336 |
+
|
337 |
+
$ret[$dom][$cpath] = $paths_array[$cpath];
|
338 |
+
}
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
return $ret;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Create a new CookieJar object and automatically load into it all the
|
347 |
+
* cookies set in an Http_Response object. If $uri is set, it will be
|
348 |
+
* considered as the requested URI for setting default domain and path
|
349 |
+
* of the cookie.
|
350 |
+
*
|
351 |
+
* @param Microsoft_Http_Response $response HTTP Response object
|
352 |
+
* @param Microsoft_Uri_Http|string $uri The requested URI
|
353 |
+
* @return Microsoft_Http_CookieJar
|
354 |
+
* @todo Add the $uri functionality.
|
355 |
+
*/
|
356 |
+
public static function fromResponse(Microsoft_Http_Response $response, $ref_uri)
|
357 |
+
{
|
358 |
+
$jar = new self();
|
359 |
+
$jar->addCookiesFromResponse($response, $ref_uri);
|
360 |
+
return $jar;
|
361 |
+
}
|
362 |
+
|
363 |
+
/**
|
364 |
+
* Required by Countable interface
|
365 |
+
*
|
366 |
+
* @return int
|
367 |
+
*/
|
368 |
+
public function count()
|
369 |
+
{
|
370 |
+
return count($this->_rawCookies);
|
371 |
+
}
|
372 |
+
|
373 |
+
/**
|
374 |
+
* Required by IteratorAggregate interface
|
375 |
+
*
|
376 |
+
* @return ArrayIterator
|
377 |
+
*/
|
378 |
+
public function getIterator()
|
379 |
+
{
|
380 |
+
return new ArrayIterator($this->_rawCookies);
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Tells if the jar is empty of any cookie
|
385 |
+
*
|
386 |
+
* @return bool
|
387 |
+
*/
|
388 |
+
public function isEmpty()
|
389 |
+
{
|
390 |
+
return count($this) == 0;
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Empties the cookieJar of any cookie
|
395 |
+
*
|
396 |
+
* @return Microsoft_Http_CookieJar
|
397 |
+
*/
|
398 |
+
public function reset()
|
399 |
+
{
|
400 |
+
$this->cookies = $this->_rawCookies = array();
|
401 |
+
return $this;
|
402 |
+
}
|
403 |
+
}
|
app/libs/Microsoft/Http/Exception.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_Http
|
30 |
+
* @subpackage Exception
|
31 |
+
* @version $Id: Exception.php 45259 2010-04-16 12:13:55Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_Http
|
44 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
45 |
+
* @license http://phpazure.codeplex.com/license
|
46 |
+
*/
|
47 |
+
class Microsoft_Http_Exception extends Microsoft_Exception
|
48 |
+
{}
|
app/libs/Microsoft/Http/Response.php
ADDED
@@ -0,0 +1,664 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Response
|
19 |
+
* @version $Id: Response.php 35835 2009-12-17 09:40:36Z unknown $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Microsoft_Http_Response represents an HTTP 1.0 / 1.1 response message. It
|
26 |
+
* includes easy access to all the response's different elemts, as well as some
|
27 |
+
* convenience methods for parsing and validating HTTP responses.
|
28 |
+
*
|
29 |
+
* @package Microsoft_Http
|
30 |
+
* @subpackage Response
|
31 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
32 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
33 |
+
*/
|
34 |
+
class Microsoft_Http_Response
|
35 |
+
{
|
36 |
+
/**
|
37 |
+
* List of all known HTTP response codes - used by responseCodeAsText() to
|
38 |
+
* translate numeric codes to messages.
|
39 |
+
*
|
40 |
+
* @var array
|
41 |
+
*/
|
42 |
+
protected static $messages = array(
|
43 |
+
// Informational 1xx
|
44 |
+
100 => 'Continue',
|
45 |
+
101 => 'Switching Protocols',
|
46 |
+
|
47 |
+
// Success 2xx
|
48 |
+
200 => 'OK',
|
49 |
+
201 => 'Created',
|
50 |
+
202 => 'Accepted',
|
51 |
+
203 => 'Non-Authoritative Information',
|
52 |
+
204 => 'No Content',
|
53 |
+
205 => 'Reset Content',
|
54 |
+
206 => 'Partial Content',
|
55 |
+
|
56 |
+
// Redirection 3xx
|
57 |
+
300 => 'Multiple Choices',
|
58 |
+
301 => 'Moved Permanently',
|
59 |
+
302 => 'Found', // 1.1
|
60 |
+
303 => 'See Other',
|
61 |
+
304 => 'Not Modified',
|
62 |
+
305 => 'Use Proxy',
|
63 |
+
// 306 is deprecated but reserved
|
64 |
+
307 => 'Temporary Redirect',
|
65 |
+
|
66 |
+
// Client Error 4xx
|
67 |
+
400 => 'Bad Request',
|
68 |
+
401 => 'Unauthorized',
|
69 |
+
402 => 'Payment Required',
|
70 |
+
403 => 'Forbidden',
|
71 |
+
404 => 'Not Found',
|
72 |
+
405 => 'Method Not Allowed',
|
73 |
+
406 => 'Not Acceptable',
|
74 |
+
407 => 'Proxy Authentication Required',
|
75 |
+
408 => 'Request Timeout',
|
76 |
+
409 => 'Conflict',
|
77 |
+
410 => 'Gone',
|
78 |
+
411 => 'Length Required',
|
79 |
+
412 => 'Precondition Failed',
|
80 |
+
413 => 'Request Entity Too Large',
|
81 |
+
414 => 'Request-URI Too Long',
|
82 |
+
415 => 'Unsupported Media Type',
|
83 |
+
416 => 'Requested Range Not Satisfiable',
|
84 |
+
417 => 'Expectation Failed',
|
85 |
+
|
86 |
+
// Server Error 5xx
|
87 |
+
500 => 'Internal Server Error',
|
88 |
+
501 => 'Not Implemented',
|
89 |
+
502 => 'Bad Gateway',
|
90 |
+
503 => 'Service Unavailable',
|
91 |
+
504 => 'Gateway Timeout',
|
92 |
+
505 => 'HTTP Version Not Supported',
|
93 |
+
509 => 'Bandwidth Limit Exceeded'
|
94 |
+
);
|
95 |
+
|
96 |
+
/**
|
97 |
+
* The HTTP version (1.0, 1.1)
|
98 |
+
*
|
99 |
+
* @var string
|
100 |
+
*/
|
101 |
+
protected $version;
|
102 |
+
|
103 |
+
/**
|
104 |
+
* The HTTP response code
|
105 |
+
*
|
106 |
+
* @var int
|
107 |
+
*/
|
108 |
+
protected $code;
|
109 |
+
|
110 |
+
/**
|
111 |
+
* The HTTP response code as string
|
112 |
+
* (e.g. 'Not Found' for 404 or 'Internal Server Error' for 500)
|
113 |
+
*
|
114 |
+
* @var string
|
115 |
+
*/
|
116 |
+
protected $message;
|
117 |
+
|
118 |
+
/**
|
119 |
+
* The HTTP response headers array
|
120 |
+
*
|
121 |
+
* @var array
|
122 |
+
*/
|
123 |
+
protected $headers = array();
|
124 |
+
|
125 |
+
/**
|
126 |
+
* The HTTP response body
|
127 |
+
*
|
128 |
+
* @var string
|
129 |
+
*/
|
130 |
+
protected $body;
|
131 |
+
|
132 |
+
/**
|
133 |
+
* HTTP response constructor
|
134 |
+
*
|
135 |
+
* In most cases, you would use Microsoft_Http_Response::fromString to parse an HTTP
|
136 |
+
* response string and create a new Microsoft_Http_Response object.
|
137 |
+
*
|
138 |
+
* NOTE: The constructor no longer accepts nulls or empty values for the code and
|
139 |
+
* headers and will throw an exception if the passed values do not form a valid HTTP
|
140 |
+
* responses.
|
141 |
+
*
|
142 |
+
* If no message is passed, the message will be guessed according to the response code.
|
143 |
+
*
|
144 |
+
* @param int $code Response code (200, 404, ...)
|
145 |
+
* @param array $headers Headers array
|
146 |
+
* @param string $body Response body
|
147 |
+
* @param string $version HTTP version
|
148 |
+
* @param string $message Response code as text
|
149 |
+
* @throws Microsoft_Http_Exception
|
150 |
+
*/
|
151 |
+
public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
|
152 |
+
{
|
153 |
+
// Make sure the response code is valid and set it
|
154 |
+
if (self::responseCodeAsText($code) === null) {
|
155 |
+
require_once 'Microsoft/Http/Exception.php';
|
156 |
+
throw new Microsoft_Http_Exception("{$code} is not a valid HTTP response code");
|
157 |
+
}
|
158 |
+
|
159 |
+
$this->code = $code;
|
160 |
+
|
161 |
+
// Make sure we got valid headers and set them
|
162 |
+
if (! is_array($headers)) {
|
163 |
+
require_once 'Microsoft/Http/Exception.php';
|
164 |
+
throw new Microsoft_Http_Exception('No valid headers were passed');
|
165 |
+
}
|
166 |
+
|
167 |
+
foreach ($headers as $name => $value) {
|
168 |
+
if (is_int($name))
|
169 |
+
list($name, $value) = explode(": ", $value, 1);
|
170 |
+
|
171 |
+
$this->headers[ucwords(strtolower($name))] = $value;
|
172 |
+
}
|
173 |
+
|
174 |
+
// Set the body
|
175 |
+
$this->body = $body;
|
176 |
+
|
177 |
+
// Set the HTTP version
|
178 |
+
if (! preg_match('|^\d\.\d$|', $version)) {
|
179 |
+
require_once 'Microsoft/Http/Exception.php';
|
180 |
+
throw new Microsoft_Http_Exception("Invalid HTTP response version: $version");
|
181 |
+
}
|
182 |
+
|
183 |
+
$this->version = $version;
|
184 |
+
|
185 |
+
// If we got the response message, set it. Else, set it according to
|
186 |
+
// the response code
|
187 |
+
if (is_string($message)) {
|
188 |
+
$this->message = $message;
|
189 |
+
} else {
|
190 |
+
$this->message = self::responseCodeAsText($code);
|
191 |
+
}
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Check whether the response is an error
|
196 |
+
*
|
197 |
+
* @return boolean
|
198 |
+
*/
|
199 |
+
public function isError()
|
200 |
+
{
|
201 |
+
$restype = floor($this->code / 100);
|
202 |
+
if ($restype == 4 || $restype == 5) {
|
203 |
+
return true;
|
204 |
+
}
|
205 |
+
|
206 |
+
return false;
|
207 |
+
}
|
208 |
+
|
209 |
+
/**
|
210 |
+
* Check whether the response in successful
|
211 |
+
*
|
212 |
+
* @return boolean
|
213 |
+
*/
|
214 |
+
public function isSuccessful()
|
215 |
+
{
|
216 |
+
$restype = floor($this->code / 100);
|
217 |
+
if ($restype == 2 || $restype == 1) { // Shouldn't 3xx count as success as well ???
|
218 |
+
return true;
|
219 |
+
}
|
220 |
+
|
221 |
+
return false;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Check whether the response is a redirection
|
226 |
+
*
|
227 |
+
* @return boolean
|
228 |
+
*/
|
229 |
+
public function isRedirect()
|
230 |
+
{
|
231 |
+
$restype = floor($this->code / 100);
|
232 |
+
if ($restype == 3) {
|
233 |
+
return true;
|
234 |
+
}
|
235 |
+
|
236 |
+
return false;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Get the response body as string
|
241 |
+
*
|
242 |
+
* This method returns the body of the HTTP response (the content), as it
|
243 |
+
* should be in it's readable version - that is, after decoding it (if it
|
244 |
+
* was decoded), deflating it (if it was gzip compressed), etc.
|
245 |
+
*
|
246 |
+
* If you want to get the raw body (as transfered on wire) use
|
247 |
+
* $this->getRawBody() instead.
|
248 |
+
*
|
249 |
+
* @return string
|
250 |
+
*/
|
251 |
+
public function getBody()
|
252 |
+
{
|
253 |
+
$body = '';
|
254 |
+
|
255 |
+
// Decode the body if it was transfer-encoded
|
256 |
+
switch (strtolower($this->getHeader('transfer-encoding'))) {
|
257 |
+
|
258 |
+
// Handle chunked body
|
259 |
+
case 'chunked':
|
260 |
+
$body = self::decodeChunkedBody($this->body);
|
261 |
+
break;
|
262 |
+
|
263 |
+
// No transfer encoding, or unknown encoding extension:
|
264 |
+
// return body as is
|
265 |
+
default:
|
266 |
+
$body = $this->body;
|
267 |
+
break;
|
268 |
+
}
|
269 |
+
|
270 |
+
// Decode any content-encoding (gzip or deflate) if needed
|
271 |
+
switch (strtolower($this->getHeader('content-encoding'))) {
|
272 |
+
|
273 |
+
// Handle gzip encoding
|
274 |
+
case 'gzip':
|
275 |
+
$body = self::decodeGzip($body);
|
276 |
+
break;
|
277 |
+
|
278 |
+
// Handle deflate encoding
|
279 |
+
case 'deflate':
|
280 |
+
$body = self::decodeDeflate($body);
|
281 |
+
break;
|
282 |
+
|
283 |
+
default:
|
284 |
+
break;
|
285 |
+
}
|
286 |
+
|
287 |
+
return $body;
|
288 |
+
}
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Get the raw response body (as transfered "on wire") as string
|
292 |
+
*
|
293 |
+
* If the body is encoded (with Transfer-Encoding, not content-encoding -
|
294 |
+
* IE "chunked" body), gzip compressed, etc. it will not be decoded.
|
295 |
+
*
|
296 |
+
* @return string
|
297 |
+
*/
|
298 |
+
public function getRawBody()
|
299 |
+
{
|
300 |
+
return $this->body;
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Get the HTTP version of the response
|
305 |
+
*
|
306 |
+
* @return string
|
307 |
+
*/
|
308 |
+
public function getVersion()
|
309 |
+
{
|
310 |
+
return $this->version;
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Get the HTTP response status code
|
315 |
+
*
|
316 |
+
* @return int
|
317 |
+
*/
|
318 |
+
public function getStatus()
|
319 |
+
{
|
320 |
+
return $this->code;
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Return a message describing the HTTP response code
|
325 |
+
* (Eg. "OK", "Not Found", "Moved Permanently")
|
326 |
+
*
|
327 |
+
* @return string
|
328 |
+
*/
|
329 |
+
public function getMessage()
|
330 |
+
{
|
331 |
+
return $this->message;
|
332 |
+
}
|
333 |
+
|
334 |
+
/**
|
335 |
+
* Get the response headers
|
336 |
+
*
|
337 |
+
* @return array
|
338 |
+
*/
|
339 |
+
public function getHeaders()
|
340 |
+
{
|
341 |
+
return $this->headers;
|
342 |
+
}
|
343 |
+
|
344 |
+
/**
|
345 |
+
* Get a specific header as string, or null if it is not set
|
346 |
+
*
|
347 |
+
* @param string$header
|
348 |
+
* @return string|array|null
|
349 |
+
*/
|
350 |
+
public function getHeader($header)
|
351 |
+
{
|
352 |
+
$header = ucwords(strtolower($header));
|
353 |
+
if (! is_string($header) || ! isset($this->headers[$header])) return null;
|
354 |
+
|
355 |
+
return $this->headers[$header];
|
356 |
+
}
|
357 |
+
|
358 |
+
/**
|
359 |
+
* Get all headers as string
|
360 |
+
*
|
361 |
+
* @param boolean $status_line Whether to return the first status line (IE "HTTP 200 OK")
|
362 |
+
* @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
|
363 |
+
* @return string
|
364 |
+
*/
|
365 |
+
public function getHeadersAsString($status_line = true, $br = "\n")
|
366 |
+
{
|
367 |
+
$str = '';
|
368 |
+
|
369 |
+
if ($status_line) {
|
370 |
+
$str = "HTTP/{$this->version} {$this->code} {$this->message}{$br}";
|
371 |
+
}
|
372 |
+
|
373 |
+
// Iterate over the headers and stringify them
|
374 |
+
foreach ($this->headers as $name => $value)
|
375 |
+
{
|
376 |
+
if (is_string($value))
|
377 |
+
$str .= "{$name}: {$value}{$br}";
|
378 |
+
|
379 |
+
elseif (is_array($value)) {
|
380 |
+
foreach ($value as $subval) {
|
381 |
+
$str .= "{$name}: {$subval}{$br}";
|
382 |
+
}
|
383 |
+
}
|
384 |
+
}
|
385 |
+
|
386 |
+
return $str;
|
387 |
+
}
|
388 |
+
|
389 |
+
/**
|
390 |
+
* Get the entire response as string
|
391 |
+
*
|
392 |
+
* @param string $br Line breaks (eg. "\n", "\r\n", "<br />")
|
393 |
+
* @return string
|
394 |
+
*/
|
395 |
+
public function asString($br = "\n")
|
396 |
+
{
|
397 |
+
return $this->getHeadersAsString(true, $br) . $br . $this->getRawBody();
|
398 |
+
}
|
399 |
+
|
400 |
+
/**
|
401 |
+
* Implements magic __toString()
|
402 |
+
*
|
403 |
+
* @return string
|
404 |
+
*/
|
405 |
+
public function __toString()
|
406 |
+
{
|
407 |
+
return $this->asString();
|
408 |
+
}
|
409 |
+
|
410 |
+
/**
|
411 |
+
* A convenience function that returns a text representation of
|
412 |
+
* HTTP response codes. Returns 'Unknown' for unknown codes.
|
413 |
+
* Returns array of all codes, if $code is not specified.
|
414 |
+
*
|
415 |
+
* Conforms to HTTP/1.1 as defined in RFC 2616 (except for 'Unknown')
|
416 |
+
* See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10 for reference
|
417 |
+
*
|
418 |
+
* @param int $code HTTP response code
|
419 |
+
* @param boolean $http11 Use HTTP version 1.1
|
420 |
+
* @return string
|
421 |
+
*/
|
422 |
+
public static function responseCodeAsText($code = null, $http11 = true)
|
423 |
+
{
|
424 |
+
$messages = self::$messages;
|
425 |
+
if (! $http11) $messages[302] = 'Moved Temporarily';
|
426 |
+
|
427 |
+
if ($code === null) {
|
428 |
+
return $messages;
|
429 |
+
} elseif (isset($messages[$code])) {
|
430 |
+
return $messages[$code];
|
431 |
+
} else {
|
432 |
+
return 'Unknown';
|
433 |
+
}
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* Extract the response code from a response string
|
438 |
+
*
|
439 |
+
* @param string $response_str
|
440 |
+
* @return int
|
441 |
+
*/
|
442 |
+
public static function extractCode($response_str)
|
443 |
+
{
|
444 |
+
preg_match("|^HTTP/[\d\.x]+ (\d+)|", $response_str, $m);
|
445 |
+
|
446 |
+
if (isset($m[1])) {
|
447 |
+
return (int) $m[1];
|
448 |
+
} else {
|
449 |
+
return false;
|
450 |
+
}
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Extract the HTTP message from a response
|
455 |
+
*
|
456 |
+
* @param string $response_str
|
457 |
+
* @return string
|
458 |
+
*/
|
459 |
+
public static function extractMessage($response_str)
|
460 |
+
{
|
461 |
+
preg_match("|^HTTP/[\d\.x]+ \d+ ([^\r\n]+)|", $response_str, $m);
|
462 |
+
|
463 |
+
if (isset($m[1])) {
|
464 |
+
return $m[1];
|
465 |
+
} else {
|
466 |
+
return false;
|
467 |
+
}
|
468 |
+
}
|
469 |
+
|
470 |
+
/**
|
471 |
+
* Extract the HTTP version from a response
|
472 |
+
*
|
473 |
+
* @param string $response_str
|
474 |
+
* @return string
|
475 |
+
*/
|
476 |
+
public static function extractVersion($response_str)
|
477 |
+
{
|
478 |
+
preg_match("|^HTTP/([\d\.x]+) \d+|", $response_str, $m);
|
479 |
+
|
480 |
+
if (isset($m[1])) {
|
481 |
+
return $m[1];
|
482 |
+
} else {
|
483 |
+
return false;
|
484 |
+
}
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Extract the headers from a response string
|
489 |
+
*
|
490 |
+
* @param string $response_str
|
491 |
+
* @return array
|
492 |
+
*/
|
493 |
+
public static function extractHeaders($response_str)
|
494 |
+
{
|
495 |
+
$headers = array();
|
496 |
+
|
497 |
+
// First, split body and headers
|
498 |
+
$parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
|
499 |
+
if (! $parts[0]) return $headers;
|
500 |
+
|
501 |
+
// Split headers part to lines
|
502 |
+
$lines = explode("\n", $parts[0]);
|
503 |
+
unset($parts);
|
504 |
+
$last_header = null;
|
505 |
+
|
506 |
+
foreach($lines as $line) {
|
507 |
+
$line = trim($line, "\r\n");
|
508 |
+
if ($line == "") break;
|
509 |
+
|
510 |
+
if (preg_match("|^([\w-]+):\s+(.+)|", $line, $m)) {
|
511 |
+
unset($last_header);
|
512 |
+
$h_name = strtolower($m[1]);
|
513 |
+
$h_value = $m[2];
|
514 |
+
|
515 |
+
if (isset($headers[$h_name])) {
|
516 |
+
if (! is_array($headers[$h_name])) {
|
517 |
+
$headers[$h_name] = array($headers[$h_name]);
|
518 |
+
}
|
519 |
+
|
520 |
+
$headers[$h_name][] = $h_value;
|
521 |
+
} else {
|
522 |
+
$headers[$h_name] = $h_value;
|
523 |
+
}
|
524 |
+
$last_header = $h_name;
|
525 |
+
} elseif (preg_match("|^\s+(.+)$|", $line, $m) && $last_header !== null) {
|
526 |
+
if (is_array($headers[$last_header])) {
|
527 |
+
end($headers[$last_header]);
|
528 |
+
$last_header_key = key($headers[$last_header]);
|
529 |
+
$headers[$last_header][$last_header_key] .= $m[1];
|
530 |
+
} else {
|
531 |
+
$headers[$last_header] .= $m[1];
|
532 |
+
}
|
533 |
+
}
|
534 |
+
}
|
535 |
+
|
536 |
+
return $headers;
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* Extract the body from a response string
|
541 |
+
*
|
542 |
+
* @param string $response_str
|
543 |
+
* @return string
|
544 |
+
*/
|
545 |
+
public static function extractBody($response_str)
|
546 |
+
{
|
547 |
+
$parts = preg_split('|(?:\r?\n){2}|m', $response_str, 2);
|
548 |
+
if (isset($parts[1])) {
|
549 |
+
return $parts[1];
|
550 |
+
}
|
551 |
+
return '';
|
552 |
+
}
|
553 |
+
|
554 |
+
/**
|
555 |
+
* Decode a "chunked" transfer-encoded body and return the decoded text
|
556 |
+
*
|
557 |
+
* @param string $body
|
558 |
+
* @return string
|
559 |
+
*/
|
560 |
+
public static function decodeChunkedBody($body)
|
561 |
+
{
|
562 |
+
$decBody = '';
|
563 |
+
|
564 |
+
// If mbstring overloads substr and strlen functions, we have to
|
565 |
+
// override it's internal encoding
|
566 |
+
if (function_exists('mb_internal_encoding') &&
|
567 |
+
((int) ini_get('mbstring.func_overload')) & 2) {
|
568 |
+
|
569 |
+
$mbIntEnc = mb_internal_encoding();
|
570 |
+
mb_internal_encoding('ASCII');
|
571 |
+
}
|
572 |
+
|
573 |
+
while (trim($body)) {
|
574 |
+
if (! preg_match("/^([\da-fA-F]+)[^\r\n]*\r\n/sm", $body, $m)) {
|
575 |
+
require_once 'Microsoft/Http/Exception.php';
|
576 |
+
throw new Microsoft_Http_Exception("Error parsing body - doesn't seem to be a chunked message");
|
577 |
+
}
|
578 |
+
|
579 |
+
$length = hexdec(trim($m[1]));
|
580 |
+
$cut = strlen($m[0]);
|
581 |
+
$decBody .= substr($body, $cut, $length);
|
582 |
+
$body = substr($body, $cut + $length + 2);
|
583 |
+
}
|
584 |
+
|
585 |
+
if (isset($mbIntEnc)) {
|
586 |
+
mb_internal_encoding($mbIntEnc);
|
587 |
+
}
|
588 |
+
|
589 |
+
return $decBody;
|
590 |
+
}
|
591 |
+
|
592 |
+
/**
|
593 |
+
* Decode a gzip encoded message (when Content-encoding = gzip)
|
594 |
+
*
|
595 |
+
* Currently requires PHP with zlib support
|
596 |
+
*
|
597 |
+
* @param string $body
|
598 |
+
* @return string
|
599 |
+
*/
|
600 |
+
public static function decodeGzip($body)
|
601 |
+
{
|
602 |
+
if (! function_exists('gzinflate')) {
|
603 |
+
require_once 'Microsoft/Http/Exception.php';
|
604 |
+
throw new Microsoft_Http_Exception(
|
605 |
+
'zlib extension is required in order to decode "gzip" encoding'
|
606 |
+
);
|
607 |
+
}
|
608 |
+
|
609 |
+
return gzinflate(substr($body, 10));
|
610 |
+
}
|
611 |
+
|
612 |
+
/**
|
613 |
+
* Decode a zlib deflated message (when Content-encoding = deflate)
|
614 |
+
*
|
615 |
+
* Currently requires PHP with zlib support
|
616 |
+
*
|
617 |
+
* @param string $body
|
618 |
+
* @return string
|
619 |
+
*/
|
620 |
+
public static function decodeDeflate($body)
|
621 |
+
{
|
622 |
+
if (! function_exists('gzuncompress')) {
|
623 |
+
require_once 'Microsoft/Http/Exception.php';
|
624 |
+
throw new Microsoft_Http_Exception(
|
625 |
+
'zlib extension is required in order to decode "deflate" encoding'
|
626 |
+
);
|
627 |
+
}
|
628 |
+
|
629 |
+
/**
|
630 |
+
* Some servers (IIS ?) send a broken deflate response, without the
|
631 |
+
* RFC-required zlib header.
|
632 |
+
*
|
633 |
+
* We try to detect the zlib header, and if it does not exsit we
|
634 |
+
* teat the body is plain DEFLATE content.
|
635 |
+
*
|
636 |
+
* This method was adapted from PEAR HTTP_Request2 by (c) Alexey Borzov
|
637 |
+
*
|
638 |
+
* @link http://framework.zend.com/issues/browse/ZF-6040
|
639 |
+
*/
|
640 |
+
$zlibHeader = unpack('n', substr($body, 0, 2));
|
641 |
+
if ($zlibHeader[1] % 31 == 0) {
|
642 |
+
return gzuncompress($body);
|
643 |
+
} else {
|
644 |
+
return gzinflate($body);
|
645 |
+
}
|
646 |
+
}
|
647 |
+
|
648 |
+
/**
|
649 |
+
* Create a new Microsoft_Http_Response object from a string
|
650 |
+
*
|
651 |
+
* @param string $response_str
|
652 |
+
* @return Microsoft_Http_Response
|
653 |
+
*/
|
654 |
+
public static function fromString($response_str)
|
655 |
+
{
|
656 |
+
$code = self::extractCode($response_str);
|
657 |
+
$headers = self::extractHeaders($response_str);
|
658 |
+
$body = self::extractBody($response_str);
|
659 |
+
$version = self::extractVersion($response_str);
|
660 |
+
$message = self::extractMessage($response_str);
|
661 |
+
|
662 |
+
return new Microsoft_Http_Response($code, $headers, $body, $version, $message);
|
663 |
+
}
|
664 |
+
}
|
app/libs/Microsoft/Http/Response/Stream.php
ADDED
@@ -0,0 +1,235 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Zend Framework
|
5 |
+
*
|
6 |
+
* LICENSE
|
7 |
+
*
|
8 |
+
* This source file is subject to the new BSD license that is bundled
|
9 |
+
* with this package in the file LICENSE.txt.
|
10 |
+
* It is also available through the world-wide-web at this URL:
|
11 |
+
* http://framework.zend.com/license/new-bsd
|
12 |
+
* If you did not receive a copy of the license and are unable to
|
13 |
+
* obtain it through the world-wide-web, please send an email
|
14 |
+
* to license@zend.com so we can send you a copy immediately.
|
15 |
+
*
|
16 |
+
* @category Microsoft
|
17 |
+
* @package Microsoft_Http
|
18 |
+
* @subpackage Response
|
19 |
+
* @version $Id: Response.php 17131 2009-07-26 10:03:39Z shahar $
|
20 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
21 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
22 |
+
*/
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Microsoft_Http_Response represents an HTTP 1.0 / 1.1 response message. It
|
26 |
+
* includes easy access to all the response's different elemts, as well as some
|
27 |
+
* convenience methods for parsing and validating HTTP responses.
|
28 |
+
*
|
29 |
+
* @package Microsoft_Http
|
30 |
+
* @subpackage Response
|
31 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
32 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
33 |
+
*/
|
34 |
+
class Microsoft_Http_Response_Stream extends Microsoft_Http_Response
|
35 |
+
{
|
36 |
+
/**
|
37 |
+
* Response as stream
|
38 |
+
*
|
39 |
+
* @var resource
|
40 |
+
*/
|
41 |
+
protected $stream;
|
42 |
+
|
43 |
+
/**
|
44 |
+
* The name of the file containing the stream
|
45 |
+
*
|
46 |
+
* Will be empty if stream is not file-based.
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
protected $stream_name;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Should we clean up the stream file when this response is closed?
|
54 |
+
*
|
55 |
+
* @var boolean
|
56 |
+
*/
|
57 |
+
protected $_cleanup;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Get the response as stream
|
61 |
+
*
|
62 |
+
* @return resourse
|
63 |
+
*/
|
64 |
+
public function getStream()
|
65 |
+
{
|
66 |
+
return $this->stream;
|
67 |
+
}
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Set the response stream
|
71 |
+
*
|
72 |
+
* @param resourse $stream
|
73 |
+
* @return Microsoft_Http_Response_Stream
|
74 |
+
*/
|
75 |
+
public function setStream($stream)
|
76 |
+
{
|
77 |
+
$this->stream = $stream;
|
78 |
+
return $this;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Get the cleanup trigger
|
83 |
+
*
|
84 |
+
* @return boolean
|
85 |
+
*/
|
86 |
+
public function getCleanup() {
|
87 |
+
return $this->_cleanup;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Set the cleanup trigger
|
92 |
+
*
|
93 |
+
* @param $cleanup Set cleanup trigger
|
94 |
+
*/
|
95 |
+
public function setCleanup($cleanup = true) {
|
96 |
+
$this->_cleanup = $cleanup;
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Get file name associated with the stream
|
101 |
+
*
|
102 |
+
* @return string
|
103 |
+
*/
|
104 |
+
public function getStreamName() {
|
105 |
+
return $this->stream_name;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Set file name associated with the stream
|
110 |
+
*
|
111 |
+
* @param string $stream_name Name to set
|
112 |
+
* @return Microsoft_Http_Response_Stream
|
113 |
+
*/
|
114 |
+
public function setStreamName($stream_name) {
|
115 |
+
$this->stream_name = $stream_name;
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
/**
|
121 |
+
* HTTP response constructor
|
122 |
+
*
|
123 |
+
* In most cases, you would use Microsoft_Http_Response::fromString to parse an HTTP
|
124 |
+
* response string and create a new Microsoft_Http_Response object.
|
125 |
+
*
|
126 |
+
* NOTE: The constructor no longer accepts nulls or empty values for the code and
|
127 |
+
* headers and will throw an exception if the passed values do not form a valid HTTP
|
128 |
+
* responses.
|
129 |
+
*
|
130 |
+
* If no message is passed, the message will be guessed according to the response code.
|
131 |
+
*
|
132 |
+
* @param int $code Response code (200, 404, ...)
|
133 |
+
* @param array $headers Headers array
|
134 |
+
* @param string $body Response body
|
135 |
+
* @param string $version HTTP version
|
136 |
+
* @param string $message Response code as text
|
137 |
+
* @throws Microsoft_Http_Exception
|
138 |
+
*/
|
139 |
+
public function __construct($code, $headers, $body = null, $version = '1.1', $message = null)
|
140 |
+
{
|
141 |
+
|
142 |
+
if(is_resource($body)) {
|
143 |
+
$this->setStream($body);
|
144 |
+
$body = '';
|
145 |
+
}
|
146 |
+
parent::__construct($code, $headers, $body, $version, $message);
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Create a new Microsoft_Http_Response_Stream object from a string
|
151 |
+
*
|
152 |
+
* @param string $response_str
|
153 |
+
* @param resource $stream
|
154 |
+
* @return Microsoft_Http_Response_Stream
|
155 |
+
*/
|
156 |
+
public static function fromStream($response_str, $stream)
|
157 |
+
{
|
158 |
+
$code = self::extractCode($response_str);
|
159 |
+
$headers = self::extractHeaders($response_str);
|
160 |
+
$version = self::extractVersion($response_str);
|
161 |
+
$message = self::extractMessage($response_str);
|
162 |
+
|
163 |
+
return new self($code, $headers, $stream, $version, $message);
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Get the response body as string
|
168 |
+
*
|
169 |
+
* This method returns the body of the HTTP response (the content), as it
|
170 |
+
* should be in it's readable version - that is, after decoding it (if it
|
171 |
+
* was decoded), deflating it (if it was gzip compressed), etc.
|
172 |
+
*
|
173 |
+
* If you want to get the raw body (as transfered on wire) use
|
174 |
+
* $this->getRawBody() instead.
|
175 |
+
*
|
176 |
+
* @return string
|
177 |
+
*/
|
178 |
+
public function getBody()
|
179 |
+
{
|
180 |
+
if($this->stream != null) {
|
181 |
+
$this->readStream();
|
182 |
+
}
|
183 |
+
return parent::getBody();
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Get the raw response body (as transfered "on wire") as string
|
188 |
+
*
|
189 |
+
* If the body is encoded (with Transfer-Encoding, not content-encoding -
|
190 |
+
* IE "chunked" body), gzip compressed, etc. it will not be decoded.
|
191 |
+
*
|
192 |
+
* @return string
|
193 |
+
*/
|
194 |
+
public function getRawBody()
|
195 |
+
{
|
196 |
+
if($this->stream) {
|
197 |
+
$this->readStream();
|
198 |
+
}
|
199 |
+
return $this->body;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Read stream content and return it as string
|
204 |
+
*
|
205 |
+
* Function reads the remainder of the body from the stream and closes the stream.
|
206 |
+
*
|
207 |
+
* @return string
|
208 |
+
*/
|
209 |
+
protected function readStream()
|
210 |
+
{
|
211 |
+
if(!is_resource($this->stream)) {
|
212 |
+
return '';
|
213 |
+
}
|
214 |
+
|
215 |
+
if(isset($headers['content-length'])) {
|
216 |
+
$this->body = stream_get_contents($this->stream, $headers['content-length']);
|
217 |
+
} else {
|
218 |
+
$this->body = stream_get_contents($this->stream);
|
219 |
+
}
|
220 |
+
fclose($this->stream);
|
221 |
+
$this->stream = null;
|
222 |
+
}
|
223 |
+
|
224 |
+
public function __destruct()
|
225 |
+
{
|
226 |
+
if(is_resource($this->stream)) {
|
227 |
+
fclose($this->stream);
|
228 |
+
$this->stream = null;
|
229 |
+
}
|
230 |
+
if($this->_cleanup) {
|
231 |
+
@unlink($this->stream_name);
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
+
}
|
app/libs/Microsoft/Uri.php
ADDED
@@ -0,0 +1,188 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Uri
|
17 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
18 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
19 |
+
* @version $Id: Uri.php 18950 2009-11-12 15:37:56Z alexander $
|
20 |
+
*/
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Abstract class for all Microsoft_Uri handlers
|
24 |
+
*
|
25 |
+
* @category Microsoft
|
26 |
+
* @package Microsoft_Uri
|
27 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
28 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
29 |
+
*/
|
30 |
+
abstract class Microsoft_Uri
|
31 |
+
{
|
32 |
+
/**
|
33 |
+
* Scheme of this URI (http, ftp, etc.)
|
34 |
+
*
|
35 |
+
* @var string
|
36 |
+
*/
|
37 |
+
protected $_scheme = '';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Global configuration array
|
41 |
+
*
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
static protected $_config = array(
|
45 |
+
'allow_unwise' => false
|
46 |
+
);
|
47 |
+
|
48 |
+
/**
|
49 |
+
* Return a string representation of this URI.
|
50 |
+
*
|
51 |
+
* @see getUri()
|
52 |
+
* @return string
|
53 |
+
*/
|
54 |
+
public function __toString()
|
55 |
+
{
|
56 |
+
return $this->getUri();
|
57 |
+
}
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Convenience function, checks that a $uri string is well-formed
|
61 |
+
* by validating it but not returning an object. Returns TRUE if
|
62 |
+
* $uri is a well-formed URI, or FALSE otherwise.
|
63 |
+
*
|
64 |
+
* @param string $uri The URI to check
|
65 |
+
* @return boolean
|
66 |
+
*/
|
67 |
+
public static function check($uri)
|
68 |
+
{
|
69 |
+
try {
|
70 |
+
$uri = self::factory($uri);
|
71 |
+
} catch (Exception $e) {
|
72 |
+
return false;
|
73 |
+
}
|
74 |
+
|
75 |
+
return $uri->valid();
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Create a new Microsoft_Uri object for a URI. If building a new URI, then $uri should contain
|
80 |
+
* only the scheme (http, ftp, etc). Otherwise, supply $uri with the complete URI.
|
81 |
+
*
|
82 |
+
* @param string $uri The URI form which a Microsoft_Uri instance is created
|
83 |
+
* @throws Microsoft_Uri_Exception When an empty string was supplied for the scheme
|
84 |
+
* @throws Microsoft_Uri_Exception When an illegal scheme is supplied
|
85 |
+
* @throws Microsoft_Uri_Exception When the scheme is not supported
|
86 |
+
* @return Microsoft_Uri
|
87 |
+
* @link http://www.faqs.org/rfcs/rfc2396.html
|
88 |
+
*/
|
89 |
+
public static function factory($uri = 'http')
|
90 |
+
{
|
91 |
+
// Separate the scheme from the scheme-specific parts
|
92 |
+
$uri = explode(':', $uri, 2);
|
93 |
+
$scheme = strtolower($uri[0]);
|
94 |
+
$schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
|
95 |
+
|
96 |
+
if (strlen($scheme) === 0) {
|
97 |
+
require_once 'Microsoft/Uri/Exception.php';
|
98 |
+
throw new Microsoft_Uri_Exception('An empty string was supplied for the scheme');
|
99 |
+
}
|
100 |
+
|
101 |
+
// Security check: $scheme is used to load a class file, so only alphanumerics are allowed.
|
102 |
+
if (ctype_alnum($scheme) === false) {
|
103 |
+
require_once 'Microsoft/Uri/Exception.php';
|
104 |
+
throw new Microsoft_Uri_Exception('Illegal scheme supplied, only alphanumeric characters are permitted');
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Create a new Microsoft_Uri object for the $uri. If a subclass of Microsoft_Uri exists for the
|
109 |
+
* scheme, return an instance of that class. Otherwise, a Microsoft_Uri_Exception is thrown.
|
110 |
+
*/
|
111 |
+
switch ($scheme) {
|
112 |
+
case 'http':
|
113 |
+
// Break intentionally omitted
|
114 |
+
case 'https':
|
115 |
+
$className = 'Microsoft_Uri_Http';
|
116 |
+
break;
|
117 |
+
|
118 |
+
case 'mailto':
|
119 |
+
// TODO
|
120 |
+
default:
|
121 |
+
require_once 'Microsoft/Uri/Exception.php';
|
122 |
+
throw new Microsoft_Uri_Exception("Scheme \"$scheme\" is not supported");
|
123 |
+
break;
|
124 |
+
}
|
125 |
+
|
126 |
+
if (!class_exists($className)) {
|
127 |
+
require_once str_replace('_', '/', $className) . '.php';
|
128 |
+
}
|
129 |
+
$schemeHandler = new $className($scheme, $schemeSpecific);
|
130 |
+
|
131 |
+
return $schemeHandler;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Get the URI's scheme
|
136 |
+
*
|
137 |
+
* @return string|false Scheme or false if no scheme is set.
|
138 |
+
*/
|
139 |
+
public function getScheme()
|
140 |
+
{
|
141 |
+
if (empty($this->_scheme) === false) {
|
142 |
+
return $this->_scheme;
|
143 |
+
} else {
|
144 |
+
return false;
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Set global configuration options
|
150 |
+
*
|
151 |
+
* @param Microsoft_Config|array $config
|
152 |
+
*/
|
153 |
+
static public function setConfig($config)
|
154 |
+
{
|
155 |
+
if ($config instanceof Microsoft_Config) {
|
156 |
+
$config = $config->toArray();
|
157 |
+
} elseif (!is_array($config)) {
|
158 |
+
throw new Microsoft_Uri_Exception("Config must be an array or an instance of Microsoft_Config.");
|
159 |
+
}
|
160 |
+
|
161 |
+
foreach ($config as $k => $v) {
|
162 |
+
self::$_config[$k] = $v;
|
163 |
+
}
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Microsoft_Uri and its subclasses cannot be instantiated directly.
|
168 |
+
* Use Microsoft_Uri::factory() to return a new Microsoft_Uri object.
|
169 |
+
*
|
170 |
+
* @param string $scheme The scheme of the URI
|
171 |
+
* @param string $schemeSpecific The scheme-specific part of the URI
|
172 |
+
*/
|
173 |
+
abstract protected function __construct($scheme, $schemeSpecific = '');
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Return a string representation of this URI.
|
177 |
+
*
|
178 |
+
* @return string
|
179 |
+
*/
|
180 |
+
abstract public function getUri();
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Returns TRUE if this URI is valid, or FALSE otherwise.
|
184 |
+
*
|
185 |
+
* @return boolean
|
186 |
+
*/
|
187 |
+
abstract public function valid();
|
188 |
+
}
|
app/libs/Microsoft/Uri/Exception.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Uri
|
17 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
18 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
19 |
+
* @version $Id: Exception.php 16208 2009-06-21 19:19:26Z thomas $
|
20 |
+
*/
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @see Microsoft_Exception
|
24 |
+
*/
|
25 |
+
require_once 'Microsoft/Exception.php';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Exceptions for Microsoft_Uri
|
29 |
+
*
|
30 |
+
* @category Microsoft
|
31 |
+
* @package Microsoft_Uri
|
32 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
33 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
34 |
+
*/
|
35 |
+
class Microsoft_Uri_Exception extends Microsoft_Exception
|
36 |
+
{
|
37 |
+
}
|
app/libs/Microsoft/Uri/Http.php
ADDED
@@ -0,0 +1,761 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Zend Framework
|
4 |
+
*
|
5 |
+
* LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the new BSD license that is bundled
|
8 |
+
* with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://framework.zend.com/license/new-bsd
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@zend.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* @category Microsoft
|
16 |
+
* @package Microsoft_Uri
|
17 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
18 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
19 |
+
* @version $Id: Http.php 19041 2009-11-19 15:19:07Z sgehrig $
|
20 |
+
*/
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @see Microsoft_Uri
|
24 |
+
*/
|
25 |
+
require_once 'Microsoft/Uri.php';
|
26 |
+
|
27 |
+
/**
|
28 |
+
* HTTP(S) URI handler
|
29 |
+
*
|
30 |
+
* @category Microsoft
|
31 |
+
* @package Microsoft_Uri
|
32 |
+
* @uses Microsoft_Uri
|
33 |
+
* @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com)
|
34 |
+
* @license http://framework.zend.com/license/new-bsd New BSD License
|
35 |
+
*/
|
36 |
+
class Microsoft_Uri_Http extends Microsoft_Uri
|
37 |
+
{
|
38 |
+
/**
|
39 |
+
* Character classes for validation regular expressions
|
40 |
+
*/
|
41 |
+
const CHAR_ALNUM = 'A-Za-z0-9';
|
42 |
+
const CHAR_MARK = '-_.!~*\'()\[\]';
|
43 |
+
const CHAR_RESERVED = ';\/?:@&=+$,';
|
44 |
+
const CHAR_SEGMENT = ':@&=+$,;';
|
45 |
+
const CHAR_UNWISE = '{}|\\\\^`';
|
46 |
+
|
47 |
+
/**
|
48 |
+
* HTTP username
|
49 |
+
*
|
50 |
+
* @var string
|
51 |
+
*/
|
52 |
+
protected $_username = '';
|
53 |
+
|
54 |
+
/**
|
55 |
+
* HTTP password
|
56 |
+
*
|
57 |
+
* @var string
|
58 |
+
*/
|
59 |
+
protected $_password = '';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* HTTP host
|
63 |
+
*
|
64 |
+
* @var string
|
65 |
+
*/
|
66 |
+
protected $_host = '';
|
67 |
+
|
68 |
+
/**
|
69 |
+
* HTTP post
|
70 |
+
*
|
71 |
+
* @var string
|
72 |
+
*/
|
73 |
+
protected $_port = '';
|
74 |
+
|
75 |
+
/**
|
76 |
+
* HTTP part
|
77 |
+
*
|
78 |
+
* @var string
|
79 |
+
*/
|
80 |
+
protected $_path = '';
|
81 |
+
|
82 |
+
/**
|
83 |
+
* HTTP query
|
84 |
+
*
|
85 |
+
* @var string
|
86 |
+
*/
|
87 |
+
protected $_query = '';
|
88 |
+
|
89 |
+
/**
|
90 |
+
* HTTP fragment
|
91 |
+
*
|
92 |
+
* @var string
|
93 |
+
*/
|
94 |
+
protected $_fragment = '';
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Regular expression grammar rules for validation; values added by constructor
|
98 |
+
*
|
99 |
+
* @var array
|
100 |
+
*/
|
101 |
+
protected $_regex = array();
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Constructor accepts a string $scheme (e.g., http, https) and a scheme-specific part of the URI
|
105 |
+
* (e.g., example.com/path/to/resource?query=param#fragment)
|
106 |
+
*
|
107 |
+
* @param string $scheme The scheme of the URI
|
108 |
+
* @param string $schemeSpecific The scheme-specific part of the URI
|
109 |
+
* @throws Microsoft_Uri_Exception When the URI is not valid
|
110 |
+
*/
|
111 |
+
protected function __construct($scheme, $schemeSpecific = '')
|
112 |
+
{
|
113 |
+
// Set the scheme
|
114 |
+
$this->_scheme = $scheme;
|
115 |
+
|
116 |
+
// Set up grammar rules for validation via regular expressions. These
|
117 |
+
// are to be used with slash-delimited regular expression strings.
|
118 |
+
|
119 |
+
// Escaped special characters (eg. '%25' for '%')
|
120 |
+
$this->_regex['escaped'] = '%[[:xdigit:]]{2}';
|
121 |
+
|
122 |
+
// Unreserved characters
|
123 |
+
$this->_regex['unreserved'] = '[' . self::CHAR_ALNUM . self::CHAR_MARK . ']';
|
124 |
+
|
125 |
+
// Segment can use escaped, unreserved or a set of additional chars
|
126 |
+
$this->_regex['segment'] = '(?:' . $this->_regex['escaped'] . '|[' .
|
127 |
+
self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_SEGMENT . '])*';
|
128 |
+
|
129 |
+
// Path can be a series of segmets char strings seperated by '/'
|
130 |
+
$this->_regex['path'] = '(?:\/(?:' . $this->_regex['segment'] . ')?)+';
|
131 |
+
|
132 |
+
// URI characters can be escaped, alphanumeric, mark or reserved chars
|
133 |
+
$this->_regex['uric'] = '(?:' . $this->_regex['escaped'] . '|[' .
|
134 |
+
self::CHAR_ALNUM . self::CHAR_MARK . self::CHAR_RESERVED .
|
135 |
+
|
136 |
+
// If unwise chars are allowed, add them to the URI chars class
|
137 |
+
(self::$_config['allow_unwise'] ? self::CHAR_UNWISE : '') . '])';
|
138 |
+
|
139 |
+
// If no scheme-specific part was supplied, the user intends to create
|
140 |
+
// a new URI with this object. No further parsing is required.
|
141 |
+
if (strlen($schemeSpecific) === 0) {
|
142 |
+
return;
|
143 |
+
}
|
144 |
+
|
145 |
+
// Parse the scheme-specific URI parts into the instance variables.
|
146 |
+
$this->_parseUri($schemeSpecific);
|
147 |
+
|
148 |
+
// Validate the URI
|
149 |
+
if ($this->valid() === false) {
|
150 |
+
require_once 'Microsoft/Uri/Exception.php';
|
151 |
+
throw new Microsoft_Uri_Exception('Invalid URI supplied');
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Creates a Microsoft_Uri_Http from the given string
|
157 |
+
*
|
158 |
+
* @param string $uri String to create URI from, must start with
|
159 |
+
* 'http://' or 'https://'
|
160 |
+
* @throws InvalidArgumentException When the given $uri is not a string or
|
161 |
+
* does not start with http:// or https://
|
162 |
+
* @throws Microsoft_Uri_Exception When the given $uri is invalid
|
163 |
+
* @return Microsoft_Uri_Http
|
164 |
+
*/
|
165 |
+
public static function fromString($uri)
|
166 |
+
{
|
167 |
+
if (is_string($uri) === false) {
|
168 |
+
require_once 'Microsoft/Uri/Exception.php';
|
169 |
+
throw new Microsoft_Uri_Exception('$uri is not a string');
|
170 |
+
}
|
171 |
+
|
172 |
+
$uri = explode(':', $uri, 2);
|
173 |
+
$scheme = strtolower($uri[0]);
|
174 |
+
$schemeSpecific = isset($uri[1]) === true ? $uri[1] : '';
|
175 |
+
|
176 |
+
if (in_array($scheme, array('http', 'https')) === false) {
|
177 |
+
require_once 'Microsoft/Uri/Exception.php';
|
178 |
+
throw new Microsoft_Uri_Exception("Invalid scheme: '$scheme'");
|
179 |
+
}
|
180 |
+
|
181 |
+
$schemeHandler = new Microsoft_Uri_Http($scheme, $schemeSpecific);
|
182 |
+
return $schemeHandler;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Parse the scheme-specific portion of the URI and place its parts into instance variables.
|
187 |
+
*
|
188 |
+
* @param string $schemeSpecific The scheme-specific portion to parse
|
189 |
+
* @throws Microsoft_Uri_Exception When scheme-specific decoposition fails
|
190 |
+
* @throws Microsoft_Uri_Exception When authority decomposition fails
|
191 |
+
* @return void
|
192 |
+
*/
|
193 |
+
protected function _parseUri($schemeSpecific)
|
194 |
+
{
|
195 |
+
// High-level decomposition parser
|
196 |
+
$pattern = '~^((//)([^/?#]*))([^?#]*)(\?([^#]*))?(#(.*))?$~';
|
197 |
+
$status = @preg_match($pattern, $schemeSpecific, $matches);
|
198 |
+
if ($status === false) {
|
199 |
+
require_once 'Microsoft/Uri/Exception.php';
|
200 |
+
throw new Microsoft_Uri_Exception('Internal error: scheme-specific decomposition failed');
|
201 |
+
}
|
202 |
+
|
203 |
+
// Failed decomposition; no further processing needed
|
204 |
+
if ($status === false) {
|
205 |
+
return;
|
206 |
+
}
|
207 |
+
|
208 |
+
// Save URI components that need no further decomposition
|
209 |
+
$this->_path = isset($matches[4]) === true ? $matches[4] : '';
|
210 |
+
$this->_query = isset($matches[6]) === true ? $matches[6] : '';
|
211 |
+
$this->_fragment = isset($matches[8]) === true ? $matches[8] : '';
|
212 |
+
|
213 |
+
// Additional decomposition to get username, password, host, and port
|
214 |
+
$combo = isset($matches[3]) === true ? $matches[3] : '';
|
215 |
+
$pattern = '~^(([^:@]*)(:([^@]*))?@)?([^:]+)(:(.*))?$~';
|
216 |
+
$status = @preg_match($pattern, $combo, $matches);
|
217 |
+
if ($status === false) {
|
218 |
+
require_once 'Microsoft/Uri/Exception.php';
|
219 |
+
throw new Microsoft_Uri_Exception('Internal error: authority decomposition failed');
|
220 |
+
}
|
221 |
+
|
222 |
+
// Failed decomposition; no further processing needed
|
223 |
+
if ($status === false) {
|
224 |
+
return;
|
225 |
+
}
|
226 |
+
|
227 |
+
// Save remaining URI components
|
228 |
+
$this->_username = isset($matches[2]) === true ? $matches[2] : '';
|
229 |
+
$this->_password = isset($matches[4]) === true ? $matches[4] : '';
|
230 |
+
$this->_host = isset($matches[5]) === true ? $matches[5] : '';
|
231 |
+
$this->_port = isset($matches[7]) === true ? $matches[7] : '';
|
232 |
+
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Returns a URI based on current values of the instance variables. If any
|
237 |
+
* part of the URI does not pass validation, then an exception is thrown.
|
238 |
+
*
|
239 |
+
* @throws Microsoft_Uri_Exception When one or more parts of the URI are invalid
|
240 |
+
* @return string
|
241 |
+
*/
|
242 |
+
public function getUri()
|
243 |
+
{
|
244 |
+
if ($this->valid() === false) {
|
245 |
+
require_once 'Microsoft/Uri/Exception.php';
|
246 |
+
throw new Microsoft_Uri_Exception('One or more parts of the URI are invalid');
|
247 |
+
}
|
248 |
+
|
249 |
+
$password = strlen($this->_password) > 0 ? ":$this->_password" : '';
|
250 |
+
$auth = strlen($this->_username) > 0 ? "$this->_username$password@" : '';
|
251 |
+
$port = strlen($this->_port) > 0 ? ":$this->_port" : '';
|
252 |
+
$query = strlen($this->_query) > 0 ? "?$this->_query" : '';
|
253 |
+
$fragment = strlen($this->_fragment) > 0 ? "#$this->_fragment" : '';
|
254 |
+
|
255 |
+
return $this->_scheme
|
256 |
+
. '://'
|
257 |
+
. $auth
|
258 |
+
. $this->_host
|
259 |
+
. $port
|
260 |
+
. $this->_path
|
261 |
+
. $query
|
262 |
+
. $fragment;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Validate the current URI from the instance variables. Returns true if and only if all
|
267 |
+
* parts pass validation.
|
268 |
+
*
|
269 |
+
* @return boolean
|
270 |
+
*/
|
271 |
+
public function valid()
|
272 |
+
{
|
273 |
+
// Return true if and only if all parts of the URI have passed validation
|
274 |
+
return $this->validateUsername()
|
275 |
+
and $this->validatePassword()
|
276 |
+
and $this->validateHost()
|
277 |
+
and $this->validatePort()
|
278 |
+
and $this->validatePath()
|
279 |
+
and $this->validateQuery()
|
280 |
+
and $this->validateFragment();
|
281 |
+
}
|
282 |
+
|
283 |
+
/**
|
284 |
+
* Returns the username portion of the URL, or FALSE if none.
|
285 |
+
*
|
286 |
+
* @return string
|
287 |
+
*/
|
288 |
+
public function getUsername()
|
289 |
+
{
|
290 |
+
return strlen($this->_username) > 0 ? $this->_username : false;
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Returns true if and only if the username passes validation. If no username is passed,
|
295 |
+
* then the username contained in the instance variable is used.
|
296 |
+
*
|
297 |
+
* @param string $username The HTTP username
|
298 |
+
* @throws Microsoft_Uri_Exception When username validation fails
|
299 |
+
* @return boolean
|
300 |
+
* @link http://www.faqs.org/rfcs/rfc2396.html
|
301 |
+
*/
|
302 |
+
public function validateUsername($username = null)
|
303 |
+
{
|
304 |
+
if ($username === null) {
|
305 |
+
$username = $this->_username;
|
306 |
+
}
|
307 |
+
|
308 |
+
// If the username is empty, then it is considered valid
|
309 |
+
if (strlen($username) === 0) {
|
310 |
+
return true;
|
311 |
+
}
|
312 |
+
|
313 |
+
// Check the username against the allowed values
|
314 |
+
$status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' .
|
315 |
+
self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $username);
|
316 |
+
|
317 |
+
if ($status === false) {
|
318 |
+
require_once 'Microsoft/Uri/Exception.php';
|
319 |
+
throw new Microsoft_Uri_Exception('Internal error: username validation failed');
|
320 |
+
}
|
321 |
+
|
322 |
+
return $status === 1;
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Sets the username for the current URI, and returns the old username
|
327 |
+
*
|
328 |
+
* @param string $username The HTTP username
|
329 |
+
* @throws Microsoft_Uri_Exception When $username is not a valid HTTP username
|
330 |
+
* @return string
|
331 |
+
*/
|
332 |
+
public function setUsername($username)
|
333 |
+
{
|
334 |
+
if ($this->validateUsername($username) === false) {
|
335 |
+
require_once 'Microsoft/Uri/Exception.php';
|
336 |
+
throw new Microsoft_Uri_Exception("Username \"$username\" is not a valid HTTP username");
|
337 |
+
}
|
338 |
+
|
339 |
+
$oldUsername = $this->_username;
|
340 |
+
$this->_username = $username;
|
341 |
+
|
342 |
+
return $oldUsername;
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Returns the password portion of the URL, or FALSE if none.
|
347 |
+
*
|
348 |
+
* @return string
|
349 |
+
*/
|
350 |
+
public function getPassword()
|
351 |
+
{
|
352 |
+
return strlen($this->_password) > 0 ? $this->_password : false;
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Returns true if and only if the password passes validation. If no password is passed,
|
357 |
+
* then the password contained in the instance variable is used.
|
358 |
+
*
|
359 |
+
* @param string $password The HTTP password
|
360 |
+
* @throws Microsoft_Uri_Exception When password validation fails
|
361 |
+
* @return boolean
|
362 |
+
* @link http://www.faqs.org/rfcs/rfc2396.html
|
363 |
+
*/
|
364 |
+
public function validatePassword($password = null)
|
365 |
+
{
|
366 |
+
if ($password === null) {
|
367 |
+
$password = $this->_password;
|
368 |
+
}
|
369 |
+
|
370 |
+
// If the password is empty, then it is considered valid
|
371 |
+
if (strlen($password) === 0) {
|
372 |
+
return true;
|
373 |
+
}
|
374 |
+
|
375 |
+
// If the password is nonempty, but there is no username, then it is considered invalid
|
376 |
+
if (strlen($password) > 0 and strlen($this->_username) === 0) {
|
377 |
+
return false;
|
378 |
+
}
|
379 |
+
|
380 |
+
// Check the password against the allowed values
|
381 |
+
$status = @preg_match('/^(?:' . $this->_regex['escaped'] . '|[' .
|
382 |
+
self::CHAR_ALNUM . self::CHAR_MARK . ';:&=+$,' . '])+$/', $password);
|
383 |
+
|
384 |
+
if ($status === false) {
|
385 |
+
require_once 'Microsoft/Uri/Exception.php';
|
386 |
+
throw new Microsoft_Uri_Exception('Internal error: password validation failed.');
|
387 |
+
}
|
388 |
+
|
389 |
+
return $status == 1;
|
390 |
+
}
|
391 |
+
|
392 |
+
/**
|
393 |
+
* Sets the password for the current URI, and returns the old password
|
394 |
+
*
|
395 |
+
* @param string $password The HTTP password
|
396 |
+
* @throws Microsoft_Uri_Exception When $password is not a valid HTTP password
|
397 |
+
* @return string
|
398 |
+
*/
|
399 |
+
public function setPassword($password)
|
400 |
+
{
|
401 |
+
if ($this->validatePassword($password) === false) {
|
402 |
+
require_once 'Microsoft/Uri/Exception.php';
|
403 |
+
throw new Microsoft_Uri_Exception("Password \"$password\" is not a valid HTTP password.");
|
404 |
+
}
|
405 |
+
|
406 |
+
$oldPassword = $this->_password;
|
407 |
+
$this->_password = $password;
|
408 |
+
|
409 |
+
return $oldPassword;
|
410 |
+
}
|
411 |
+
|
412 |
+
/**
|
413 |
+
* Returns the domain or host IP portion of the URL, or FALSE if none.
|
414 |
+
*
|
415 |
+
* @return string
|
416 |
+
*/
|
417 |
+
public function getHost()
|
418 |
+
{
|
419 |
+
return strlen($this->_host) > 0 ? $this->_host : false;
|
420 |
+
}
|
421 |
+
|
422 |
+
/**
|
423 |
+
* Returns true if and only if the host string passes validation. If no host is passed,
|
424 |
+
* then the host contained in the instance variable is used.
|
425 |
+
*
|
426 |
+
* @param string $host The HTTP host
|
427 |
+
* @return boolean
|
428 |
+
* @uses Microsoft_Filter
|
429 |
+
*/
|
430 |
+
public function validateHost($host = null)
|
431 |
+
{
|
432 |
+
if ($host === null) {
|
433 |
+
$host = $this->_host;
|
434 |
+
}
|
435 |
+
|
436 |
+
// If the host is empty, then it is considered invalid
|
437 |
+
if (strlen($host) === 0) {
|
438 |
+
return false;
|
439 |
+
}
|
440 |
+
|
441 |
+
return true;
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Sets the host for the current URI, and returns the old host
|
446 |
+
*
|
447 |
+
* @param string $host The HTTP host
|
448 |
+
* @throws Microsoft_Uri_Exception When $host is nota valid HTTP host
|
449 |
+
* @return string
|
450 |
+
*/
|
451 |
+
public function setHost($host)
|
452 |
+
{
|
453 |
+
if ($this->validateHost($host) === false) {
|
454 |
+
require_once 'Microsoft/Uri/Exception.php';
|
455 |
+
throw new Microsoft_Uri_Exception("Host \"$host\" is not a valid HTTP host");
|
456 |
+
}
|
457 |
+
|
458 |
+
$oldHost = $this->_host;
|
459 |
+
$this->_host = $host;
|
460 |
+
|
461 |
+
return $oldHost;
|
462 |
+
}
|
463 |
+
|
464 |
+
/**
|
465 |
+
* Returns the TCP port, or FALSE if none.
|
466 |
+
*
|
467 |
+
* @return string
|
468 |
+
*/
|
469 |
+
public function getPort()
|
470 |
+
{
|
471 |
+
return strlen($this->_port) > 0 ? $this->_port : false;
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Returns true if and only if the TCP port string passes validation. If no port is passed,
|
476 |
+
* then the port contained in the instance variable is used.
|
477 |
+
*
|
478 |
+
* @param string $port The HTTP port
|
479 |
+
* @return boolean
|
480 |
+
*/
|
481 |
+
public function validatePort($port = null)
|
482 |
+
{
|
483 |
+
if ($port === null) {
|
484 |
+
$port = $this->_port;
|
485 |
+
}
|
486 |
+
|
487 |
+
// If the port is empty, then it is considered valid
|
488 |
+
if (strlen($port) === 0) {
|
489 |
+
return true;
|
490 |
+
}
|
491 |
+
|
492 |
+
// Check the port against the allowed values
|
493 |
+
return ctype_digit((string) $port) and 1 <= $port and $port <= 65535;
|
494 |
+
}
|
495 |
+
|
496 |
+
/**
|
497 |
+
* Sets the port for the current URI, and returns the old port
|
498 |
+
*
|
499 |
+
* @param string $port The HTTP port
|
500 |
+
* @throws Microsoft_Uri_Exception When $port is not a valid HTTP port
|
501 |
+
* @return string
|
502 |
+
*/
|
503 |
+
public function setPort($port)
|
504 |
+
{
|
505 |
+
if ($this->validatePort($port) === false) {
|
506 |
+
require_once 'Microsoft/Uri/Exception.php';
|
507 |
+
throw new Microsoft_Uri_Exception("Port \"$port\" is not a valid HTTP port.");
|
508 |
+
}
|
509 |
+
|
510 |
+
$oldPort = $this->_port;
|
511 |
+
$this->_port = $port;
|
512 |
+
|
513 |
+
return $oldPort;
|
514 |
+
}
|
515 |
+
|
516 |
+
/**
|
517 |
+
* Returns the path and filename portion of the URL, or FALSE if none.
|
518 |
+
*
|
519 |
+
* @return string
|
520 |
+
*/
|
521 |
+
public function getPath()
|
522 |
+
{
|
523 |
+
return strlen($this->_path) > 0 ? $this->_path : '/';
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Returns true if and only if the path string passes validation. If no path is passed,
|
528 |
+
* then the path contained in the instance variable is used.
|
529 |
+
*
|
530 |
+
* @param string $path The HTTP path
|
531 |
+
* @throws Microsoft_Uri_Exception When path validation fails
|
532 |
+
* @return boolean
|
533 |
+
*/
|
534 |
+
public function validatePath($path = null)
|
535 |
+
{
|
536 |
+
if ($path === null) {
|
537 |
+
$path = $this->_path;
|
538 |
+
}
|
539 |
+
|
540 |
+
// If the path is empty, then it is considered valid
|
541 |
+
if (strlen($path) === 0) {
|
542 |
+
return true;
|
543 |
+
}
|
544 |
+
|
545 |
+
// Determine whether the path is well-formed
|
546 |
+
$pattern = '/^' . $this->_regex['path'] . '$/';
|
547 |
+
$status = @preg_match($pattern, $path);
|
548 |
+
if ($status === false) {
|
549 |
+
require_once 'Microsoft/Uri/Exception.php';
|
550 |
+
throw new Microsoft_Uri_Exception('Internal error: path validation failed');
|
551 |
+
}
|
552 |
+
|
553 |
+
return (boolean) $status;
|
554 |
+
}
|
555 |
+
|
556 |
+
/**
|
557 |
+
* Sets the path for the current URI, and returns the old path
|
558 |
+
*
|
559 |
+
* @param string $path The HTTP path
|
560 |
+
* @throws Microsoft_Uri_Exception When $path is not a valid HTTP path
|
561 |
+
* @return string
|
562 |
+
*/
|
563 |
+
public function setPath($path)
|
564 |
+
{
|
565 |
+
if ($this->validatePath($path) === false) {
|
566 |
+
require_once 'Microsoft/Uri/Exception.php';
|
567 |
+
throw new Microsoft_Uri_Exception("Path \"$path\" is not a valid HTTP path");
|
568 |
+
}
|
569 |
+
|
570 |
+
$oldPath = $this->_path;
|
571 |
+
$this->_path = $path;
|
572 |
+
|
573 |
+
return $oldPath;
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Returns the query portion of the URL (after ?), or FALSE if none.
|
578 |
+
*
|
579 |
+
* @return string
|
580 |
+
*/
|
581 |
+
public function getQuery()
|
582 |
+
{
|
583 |
+
return strlen($this->_query) > 0 ? $this->_query : false;
|
584 |
+
}
|
585 |
+
|
586 |
+
/**
|
587 |
+
* Returns the query portion of the URL (after ?) as a
|
588 |
+
* key-value-array. If the query is empty an empty array
|
589 |
+
* is returned
|
590 |
+
*
|
591 |
+
* @return array
|
592 |
+
*/
|
593 |
+
public function getQueryAsArray()
|
594 |
+
{
|
595 |
+
$query = $this->getQuery();
|
596 |
+
$querryArray = array();
|
597 |
+
if ($query !== false) {
|
598 |
+
parse_str($query, $querryArray);
|
599 |
+
}
|
600 |
+
return $querryArray;
|
601 |
+
}
|
602 |
+
|
603 |
+
/**
|
604 |
+
* Returns true if and only if the query string passes validation. If no query is passed,
|
605 |
+
* then the query string contained in the instance variable is used.
|
606 |
+
*
|
607 |
+
* @param string $query The query to validate
|
608 |
+
* @throws Microsoft_Uri_Exception When query validation fails
|
609 |
+
* @return boolean
|
610 |
+
* @link http://www.faqs.org/rfcs/rfc2396.html
|
611 |
+
*/
|
612 |
+
public function validateQuery($query = null)
|
613 |
+
{
|
614 |
+
if ($query === null) {
|
615 |
+
$query = $this->_query;
|
616 |
+
}
|
617 |
+
|
618 |
+
// If query is empty, it is considered to be valid
|
619 |
+
if (strlen($query) === 0) {
|
620 |
+
return true;
|
621 |
+
}
|
622 |
+
|
623 |
+
// Determine whether the query is well-formed
|
624 |
+
$pattern = '/^' . $this->_regex['uric'] . '*$/';
|
625 |
+
$status = @preg_match($pattern, $query);
|
626 |
+
if ($status === false) {
|
627 |
+
require_once 'Microsoft/Uri/Exception.php';
|
628 |
+
throw new Microsoft_Uri_Exception('Internal error: query validation failed');
|
629 |
+
}
|
630 |
+
|
631 |
+
return $status == 1;
|
632 |
+
}
|
633 |
+
|
634 |
+
/**
|
635 |
+
* Add or replace params in the query string for the current URI, and
|
636 |
+
* return the old query.
|
637 |
+
*
|
638 |
+
* @param array $queryParams
|
639 |
+
* @return string Old query string
|
640 |
+
*/
|
641 |
+
public function addReplaceQueryParameters(array $queryParams)
|
642 |
+
{
|
643 |
+
$queryParams = array_merge($this->getQueryAsArray(), $queryParams);
|
644 |
+
return $this->setQuery($queryParams);
|
645 |
+
}
|
646 |
+
|
647 |
+
/**
|
648 |
+
* Remove params in the query string for the current URI, and
|
649 |
+
* return the old query.
|
650 |
+
*
|
651 |
+
* @param array $queryParamKeys
|
652 |
+
* @return string Old query string
|
653 |
+
*/
|
654 |
+
public function removeQueryParameters(array $queryParamKeys)
|
655 |
+
{
|
656 |
+
$queryParams = array_diff_key($this->getQueryAsArray(), array_fill_keys($queryParamKeys, 0));
|
657 |
+
return $this->setQuery($queryParams);
|
658 |
+
}
|
659 |
+
|
660 |
+
/**
|
661 |
+
* Set the query string for the current URI, and return the old query
|
662 |
+
* string This method accepts both strings and arrays.
|
663 |
+
*
|
664 |
+
* @param string|array $query The query string or array
|
665 |
+
* @throws Microsoft_Uri_Exception When $query is not a valid query string
|
666 |
+
* @return string Old query string
|
667 |
+
*/
|
668 |
+
public function setQuery($query)
|
669 |
+
{
|
670 |
+
$oldQuery = $this->_query;
|
671 |
+
|
672 |
+
// If query is empty, set an empty string
|
673 |
+
if (empty($query) === true) {
|
674 |
+
$this->_query = '';
|
675 |
+
return $oldQuery;
|
676 |
+
}
|
677 |
+
|
678 |
+
// If query is an array, make a string out of it
|
679 |
+
if (is_array($query) === true) {
|
680 |
+
$query = http_build_query($query, '', '&');
|
681 |
+
} else {
|
682 |
+
// If it is a string, make sure it is valid. If not parse and encode it
|
683 |
+
$query = (string) $query;
|
684 |
+
if ($this->validateQuery($query) === false) {
|
685 |
+
parse_str($query, $queryArray);
|
686 |
+
$query = http_build_query($queryArray, '', '&');
|
687 |
+
}
|
688 |
+
}
|
689 |
+
|
690 |
+
// Make sure the query is valid, and set it
|
691 |
+
if ($this->validateQuery($query) === false) {
|
692 |
+
require_once 'Microsoft/Uri/Exception.php';
|
693 |
+
throw new Microsoft_Uri_Exception("'$query' is not a valid query string");
|
694 |
+
}
|
695 |
+
|
696 |
+
$this->_query = $query;
|
697 |
+
|
698 |
+
return $oldQuery;
|
699 |
+
}
|
700 |
+
|
701 |
+
/**
|
702 |
+
* Returns the fragment portion of the URL (after #), or FALSE if none.
|
703 |
+
*
|
704 |
+
* @return string|false
|
705 |
+
*/
|
706 |
+
public function getFragment()
|
707 |
+
{
|
708 |
+
return strlen($this->_fragment) > 0 ? $this->_fragment : false;
|
709 |
+
}
|
710 |
+
|
711 |
+
/**
|
712 |
+
* Returns true if and only if the fragment passes validation. If no fragment is passed,
|
713 |
+
* then the fragment contained in the instance variable is used.
|
714 |
+
*
|
715 |
+
* @param string $fragment Fragment of an URI
|
716 |
+
* @throws Microsoft_Uri_Exception When fragment validation fails
|
717 |
+
* @return boolean
|
718 |
+
* @link http://www.faqs.org/rfcs/rfc2396.html
|
719 |
+
*/
|
720 |
+
public function validateFragment($fragment = null)
|
721 |
+
{
|
722 |
+
if ($fragment === null) {
|
723 |
+
$fragment = $this->_fragment;
|
724 |
+
}
|
725 |
+
|
726 |
+
// If fragment is empty, it is considered to be valid
|
727 |
+
if (strlen($fragment) === 0) {
|
728 |
+
return true;
|
729 |
+
}
|
730 |
+
|
731 |
+
// Determine whether the fragment is well-formed
|
732 |
+
$pattern = '/^' . $this->_regex['uric'] . '*$/';
|
733 |
+
$status = @preg_match($pattern, $fragment);
|
734 |
+
if ($status === false) {
|
735 |
+
require_once 'Microsoft/Uri/Exception.php';
|
736 |
+
throw new Microsoft_Uri_Exception('Internal error: fragment validation failed');
|
737 |
+
}
|
738 |
+
|
739 |
+
return (boolean) $status;
|
740 |
+
}
|
741 |
+
|
742 |
+
/**
|
743 |
+
* Sets the fragment for the current URI, and returns the old fragment
|
744 |
+
*
|
745 |
+
* @param string $fragment Fragment of the current URI
|
746 |
+
* @throws Microsoft_Uri_Exception When $fragment is not a valid HTTP fragment
|
747 |
+
* @return string
|
748 |
+
*/
|
749 |
+
public function setFragment($fragment)
|
750 |
+
{
|
751 |
+
if ($this->validateFragment($fragment) === false) {
|
752 |
+
require_once 'Microsoft/Uri/Exception.php';
|
753 |
+
throw new Microsoft_Uri_Exception("Fragment \"$fragment\" is not a valid HTTP fragment");
|
754 |
+
}
|
755 |
+
|
756 |
+
$oldFragment = $this->_fragment;
|
757 |
+
$this->_fragment = $fragment;
|
758 |
+
|
759 |
+
return $oldFragment;
|
760 |
+
}
|
761 |
+
}
|
app/libs/Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php
ADDED
@@ -0,0 +1,257 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
31 |
+
* @license http://phpazure.codeplex.com/license
|
32 |
+
* @version $Id: SharedKeyCredentials.php 14561 2009-05-07 08:05:12Z unknown $
|
33 |
+
*/
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @see Microsoft_Http_Client
|
37 |
+
*/
|
38 |
+
require_once 'Microsoft/Http/Client.php';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @see Microsoft_WindowsAzure_Credentials_Exception
|
42 |
+
*/
|
43 |
+
require_once 'Microsoft/WindowsAzure/Credentials/Exception.php';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @category Microsoft
|
47 |
+
* @package Microsoft_WindowsAzure
|
48 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
49 |
+
* @license http://phpazure.codeplex.com/license
|
50 |
+
*/
|
51 |
+
abstract class Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
52 |
+
{
|
53 |
+
/**
|
54 |
+
* Development storage account and key
|
55 |
+
*/
|
56 |
+
const DEVSTORE_ACCOUNT = "devstoreaccount1";
|
57 |
+
const DEVSTORE_KEY = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==";
|
58 |
+
|
59 |
+
/**
|
60 |
+
* HTTP header prefixes
|
61 |
+
*/
|
62 |
+
const PREFIX_PROPERTIES = "x-ms-prop-";
|
63 |
+
const PREFIX_METADATA = "x-ms-meta-";
|
64 |
+
const PREFIX_STORAGE_HEADER = "x-ms-";
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Permissions
|
68 |
+
*/
|
69 |
+
const PERMISSION_READ = "r";
|
70 |
+
const PERMISSION_WRITE = "w";
|
71 |
+
const PERMISSION_DELETE = "d";
|
72 |
+
const PERMISSION_LIST = "l";
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Account name for Windows Azure
|
76 |
+
*
|
77 |
+
* @var string
|
78 |
+
*/
|
79 |
+
protected $_accountName = '';
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Account key for Windows Azure
|
83 |
+
*
|
84 |
+
* @var string
|
85 |
+
*/
|
86 |
+
protected $_accountKey = '';
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Use path-style URI's
|
90 |
+
*
|
91 |
+
* @var boolean
|
92 |
+
*/
|
93 |
+
protected $_usePathStyleUri = false;
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Creates a new Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
|
97 |
+
*
|
98 |
+
* @param string $accountName Account name for Windows Azure
|
99 |
+
* @param string $accountKey Account key for Windows Azure
|
100 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
101 |
+
*/
|
102 |
+
public function __construct(
|
103 |
+
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
|
104 |
+
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
|
105 |
+
$usePathStyleUri = false
|
106 |
+
) {
|
107 |
+
$this->_accountName = $accountName;
|
108 |
+
$this->_accountKey = base64_decode($accountKey);
|
109 |
+
$this->_usePathStyleUri = $usePathStyleUri;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Set account name for Windows Azure
|
114 |
+
*
|
115 |
+
* @param string $value
|
116 |
+
* @return Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
117 |
+
*/
|
118 |
+
public function setAccountName($value = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT)
|
119 |
+
{
|
120 |
+
$this->_accountName = $value;
|
121 |
+
return $this;
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Set account key for Windows Azure
|
126 |
+
*
|
127 |
+
* @param string $value
|
128 |
+
* @return Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
129 |
+
*/
|
130 |
+
public function setAccountkey($value = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY)
|
131 |
+
{
|
132 |
+
$this->_accountKey = base64_decode($value);
|
133 |
+
return $this;
|
134 |
+
}
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Set use path-style URI's
|
138 |
+
*
|
139 |
+
* @param boolean $value
|
140 |
+
* @return Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
141 |
+
*/
|
142 |
+
public function setUsePathStyleUri($value = false)
|
143 |
+
{
|
144 |
+
$this->_usePathStyleUri = $value;
|
145 |
+
return $this;
|
146 |
+
}
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Sign request URL with credentials
|
150 |
+
*
|
151 |
+
* @param string $requestUrl Request URL
|
152 |
+
* @param string $resourceType Resource type
|
153 |
+
* @param string $requiredPermission Required permission
|
154 |
+
* @return string Signed request URL
|
155 |
+
*/
|
156 |
+
abstract public function signRequestUrl(
|
157 |
+
$requestUrl = '',
|
158 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
159 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
160 |
+
);
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Sign request headers with credentials
|
164 |
+
*
|
165 |
+
* @param string $httpVerb HTTP verb the request will use
|
166 |
+
* @param string $path Path for the request
|
167 |
+
* @param string $queryString Query string for the request
|
168 |
+
* @param array $headers x-ms headers to add
|
169 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
170 |
+
* @param string $resourceType Resource type
|
171 |
+
* @param string $requiredPermission Required permission
|
172 |
+
* @param mixed $rawData Raw post data
|
173 |
+
* @return array Array of headers
|
174 |
+
*/
|
175 |
+
abstract public function signRequestHeaders(
|
176 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
177 |
+
$path = '/',
|
178 |
+
$queryString = '',
|
179 |
+
$headers = null,
|
180 |
+
$forTableStorage = false,
|
181 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
182 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
|
183 |
+
$rawData = null
|
184 |
+
);
|
185 |
+
|
186 |
+
|
187 |
+
/**
|
188 |
+
* Prepare query string for signing
|
189 |
+
*
|
190 |
+
* @param string $value Original query string
|
191 |
+
* @return string Query string for signing
|
192 |
+
*/
|
193 |
+
protected function _prepareQueryStringForSigning($value)
|
194 |
+
{
|
195 |
+
// Return value
|
196 |
+
$returnValue = array();
|
197 |
+
|
198 |
+
// Prepare query string
|
199 |
+
$queryParts = $this->_makeArrayOfQueryString($value);
|
200 |
+
foreach ($queryParts as $key => $value) {
|
201 |
+
$returnValue[] = $key . '=' . $value;
|
202 |
+
}
|
203 |
+
|
204 |
+
// Return
|
205 |
+
if (count($returnValue) > 0) {
|
206 |
+
return '?' . implode('&', $returnValue);
|
207 |
+
} else {
|
208 |
+
return '';
|
209 |
+
}
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Make array of query string
|
214 |
+
*
|
215 |
+
* @param string $value Query string
|
216 |
+
* @return array Array of key/value pairs
|
217 |
+
*/
|
218 |
+
protected function _makeArrayOfQueryString($value)
|
219 |
+
{
|
220 |
+
// Returnvalue
|
221 |
+
$returnValue = array();
|
222 |
+
|
223 |
+
// Remove front ?
|
224 |
+
if (strlen($value) > 0 && strpos($value, '?') === 0) {
|
225 |
+
$value = substr($value, 1);
|
226 |
+
}
|
227 |
+
|
228 |
+
// Split parts
|
229 |
+
$queryParts = explode('&', $value);
|
230 |
+
foreach ($queryParts as $queryPart) {
|
231 |
+
$queryPart = explode('=', $queryPart, 2);
|
232 |
+
|
233 |
+
if ($queryPart[0] != '') {
|
234 |
+
$returnValue[ $queryPart[0] ] = isset($queryPart[1]) ? $queryPart[1] : '';
|
235 |
+
}
|
236 |
+
}
|
237 |
+
|
238 |
+
// Sort
|
239 |
+
ksort($returnValue);
|
240 |
+
|
241 |
+
// Return
|
242 |
+
return $returnValue;
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Returns an array value if the key is set, otherwide returns $valueIfNotSet
|
247 |
+
*
|
248 |
+
* @param array $array
|
249 |
+
* @param mixed $key
|
250 |
+
* @param mixed $valueIfNotSet
|
251 |
+
* @return mixed
|
252 |
+
*/
|
253 |
+
protected function _issetOr($array, $key, $valueIfNotSet)
|
254 |
+
{
|
255 |
+
return isset($array[$key]) ? $array[$key] : $valueIfNotSet;
|
256 |
+
}
|
257 |
+
}
|
app/libs/Microsoft/WindowsAzure/Credentials/Exception.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Exception
|
31 |
+
* @version $Id: Exception.php 28585 2009-09-07 12:12:56Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
45 |
+
* @license http://phpazure.codeplex.com/license
|
46 |
+
*/
|
47 |
+
class Microsoft_WindowsAzure_Credentials_Exception extends Microsoft_WindowsAzure_Exception
|
48 |
+
{}
|
app/libs/Microsoft/WindowsAzure/Credentials/SharedAccessSignature.php
ADDED
@@ -0,0 +1,320 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
31 |
+
* @license http://phpazure.codeplex.com/license
|
32 |
+
* @version $Id: SharedKeyCredentials.php 24305 2009-07-23 06:30:04Z unknown $
|
33 |
+
*/
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
37 |
+
*/
|
38 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @see Microsoft_WindowsAzure_Storage
|
42 |
+
*/
|
43 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @see Microsoft_Http_Client
|
47 |
+
*/
|
48 |
+
require_once 'Microsoft/Http/Client.php';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @category Microsoft
|
52 |
+
* @package Microsoft_WindowsAzure
|
53 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
54 |
+
* @license http://phpazure.codeplex.com/license
|
55 |
+
*/
|
56 |
+
class Microsoft_WindowsAzure_Credentials_SharedAccessSignature
|
57 |
+
extends Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
58 |
+
{
|
59 |
+
/**
|
60 |
+
* Permission set
|
61 |
+
*
|
62 |
+
* @var array
|
63 |
+
*/
|
64 |
+
protected $_permissionSet = array();
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Creates a new Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance
|
68 |
+
*
|
69 |
+
* @param string $accountName Account name for Windows Azure
|
70 |
+
* @param string $accountKey Account key for Windows Azure
|
71 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
72 |
+
* @param array $permissionSet Permission set
|
73 |
+
*/
|
74 |
+
public function __construct(
|
75 |
+
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
|
76 |
+
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
|
77 |
+
$usePathStyleUri = false, $permissionSet = array()
|
78 |
+
) {
|
79 |
+
parent::__construct($accountName, $accountKey, $usePathStyleUri);
|
80 |
+
$this->_permissionSet = $permissionSet;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Get permission set
|
85 |
+
*
|
86 |
+
* @return array
|
87 |
+
*/
|
88 |
+
public function getPermissionSet()
|
89 |
+
{
|
90 |
+
return $this->_permissionSet;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Set permisison set
|
95 |
+
*
|
96 |
+
* Warning: fine-grained permissions should be added prior to coarse-grained permissions.
|
97 |
+
* For example: first add blob permissions, end with container-wide permissions.
|
98 |
+
*
|
99 |
+
* Warning: the signed access signature URL must match the account name of the
|
100 |
+
* Microsoft_WindowsAzure_Credentials_Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance
|
101 |
+
*
|
102 |
+
* @param array $value Permission set
|
103 |
+
* @return void
|
104 |
+
*/
|
105 |
+
public function setPermissionSet($value = array())
|
106 |
+
{
|
107 |
+
foreach ($value as $url) {
|
108 |
+
if (strpos($url, $this->_accountName) === false) {
|
109 |
+
throw new Microsoft_WindowsAzure_Exception('The permission set can only contain URLs for the account name specified in the Microsoft_WindowsAzure_Credentials_SharedAccessSignature instance.');
|
110 |
+
}
|
111 |
+
}
|
112 |
+
$this->_permissionSet = $value;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Create signature
|
117 |
+
*
|
118 |
+
* @param string $path Path for the request
|
119 |
+
* @param string $resource Signed resource - container (c) - blob (b)
|
120 |
+
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
|
121 |
+
* @param string $start The time at which the Shared Access Signature becomes valid.
|
122 |
+
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
|
123 |
+
* @param string $identifier Signed identifier
|
124 |
+
* @return string
|
125 |
+
*/
|
126 |
+
public function createSignature(
|
127 |
+
$path = '/',
|
128 |
+
$resource = 'b',
|
129 |
+
$permissions = 'r',
|
130 |
+
$start = '',
|
131 |
+
$expiry = '',
|
132 |
+
$identifier = ''
|
133 |
+
) {
|
134 |
+
// Determine path
|
135 |
+
if ($this->_usePathStyleUri) {
|
136 |
+
$path = substr($path, strpos($path, '/'));
|
137 |
+
}
|
138 |
+
|
139 |
+
// Add trailing slash to $path
|
140 |
+
if (substr($path, 0, 1) !== '/') {
|
141 |
+
$path = '/' . $path;
|
142 |
+
}
|
143 |
+
|
144 |
+
// Build canonicalized resource string
|
145 |
+
$canonicalizedResource = '/' . $this->_accountName;
|
146 |
+
/*if ($this->_usePathStyleUri) {
|
147 |
+
$canonicalizedResource .= '/' . $this->_accountName;
|
148 |
+
}*/
|
149 |
+
$canonicalizedResource .= $path;
|
150 |
+
|
151 |
+
// Create string to sign
|
152 |
+
$stringToSign = array();
|
153 |
+
$stringToSign[] = $permissions;
|
154 |
+
$stringToSign[] = $start;
|
155 |
+
$stringToSign[] = $expiry;
|
156 |
+
$stringToSign[] = $canonicalizedResource;
|
157 |
+
$stringToSign[] = $identifier;
|
158 |
+
|
159 |
+
$stringToSign = implode("\n", $stringToSign);
|
160 |
+
$signature = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
|
161 |
+
|
162 |
+
return $signature;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Create signed query string
|
167 |
+
*
|
168 |
+
* @param string $path Path for the request
|
169 |
+
* @param string $queryString Query string for the request
|
170 |
+
* @param string $resource Signed resource - container (c) - blob (b)
|
171 |
+
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
|
172 |
+
* @param string $start The time at which the Shared Access Signature becomes valid.
|
173 |
+
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
|
174 |
+
* @param string $identifier Signed identifier
|
175 |
+
* @return string
|
176 |
+
*/
|
177 |
+
public function createSignedQueryString(
|
178 |
+
$path = '/',
|
179 |
+
$queryString = '',
|
180 |
+
$resource = 'b',
|
181 |
+
$permissions = 'r',
|
182 |
+
$start = '',
|
183 |
+
$expiry = '',
|
184 |
+
$identifier = ''
|
185 |
+
) {
|
186 |
+
// Parts
|
187 |
+
$parts = array();
|
188 |
+
if ($start !== '') {
|
189 |
+
$parts[] = 'st=' . urlencode($start);
|
190 |
+
}
|
191 |
+
$parts[] = 'se=' . urlencode($expiry);
|
192 |
+
$parts[] = 'sr=' . $resource;
|
193 |
+
$parts[] = 'sp=' . $permissions;
|
194 |
+
if ($identifier !== '') {
|
195 |
+
$parts[] = 'si=' . urlencode($identifier);
|
196 |
+
}
|
197 |
+
$parts[] = 'sig=' . urlencode($this->createSignature($path, $resource, $permissions, $start, $expiry, $identifier));
|
198 |
+
|
199 |
+
// Assemble parts and query string
|
200 |
+
if ($queryString != '') {
|
201 |
+
$queryString .= '&';
|
202 |
+
}
|
203 |
+
$queryString .= implode('&', $parts);
|
204 |
+
|
205 |
+
return $queryString;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Permission matches request?
|
210 |
+
*
|
211 |
+
* @param string $permissionUrl Permission URL
|
212 |
+
* @param string $requestUrl Request URL
|
213 |
+
* @param string $resourceType Resource type
|
214 |
+
* @param string $requiredPermission Required permission
|
215 |
+
* @return string Signed request URL
|
216 |
+
*/
|
217 |
+
public function permissionMatchesRequest(
|
218 |
+
$permissionUrl = '',
|
219 |
+
$requestUrl = '',
|
220 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
221 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
222 |
+
) {
|
223 |
+
// Build requirements
|
224 |
+
$requiredResourceType = $resourceType;
|
225 |
+
if ($requiredResourceType == Microsoft_WindowsAzure_Storage::RESOURCE_BLOB) {
|
226 |
+
$requiredResourceType .= Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER;
|
227 |
+
}
|
228 |
+
|
229 |
+
// Parse permission url
|
230 |
+
$parsedPermissionUrl = parse_url($permissionUrl);
|
231 |
+
|
232 |
+
// Parse permission properties
|
233 |
+
$permissionParts = explode('&', $parsedPermissionUrl['query']);
|
234 |
+
|
235 |
+
// Parse request url
|
236 |
+
$parsedRequestUrl = parse_url($requestUrl);
|
237 |
+
|
238 |
+
// Check if permission matches request
|
239 |
+
$matches = true;
|
240 |
+
foreach ($permissionParts as $part) {
|
241 |
+
list($property, $value) = explode('=', $part, 2);
|
242 |
+
|
243 |
+
if ($property == 'sr') {
|
244 |
+
$matches = $matches && (strpbrk($value, $requiredResourceType) !== false);
|
245 |
+
}
|
246 |
+
|
247 |
+
if ($property == 'sp') {
|
248 |
+
$matches = $matches && (strpbrk($value, $requiredPermission) !== false);
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
// Ok, but... does the resource match?
|
253 |
+
$matches = $matches && (strpos($parsedRequestUrl['path'], $parsedPermissionUrl['path']) !== false);
|
254 |
+
|
255 |
+
// Return
|
256 |
+
return $matches;
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Sign request URL with credentials
|
261 |
+
*
|
262 |
+
* @param string $requestUrl Request URL
|
263 |
+
* @param string $resourceType Resource type
|
264 |
+
* @param string $requiredPermission Required permission
|
265 |
+
* @return string Signed request URL
|
266 |
+
*/
|
267 |
+
public function signRequestUrl(
|
268 |
+
$requestUrl = '',
|
269 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
270 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
271 |
+
) {
|
272 |
+
// Look for a matching permission
|
273 |
+
foreach ($this->getPermissionSet() as $permittedUrl) {
|
274 |
+
if ($this->permissionMatchesRequest($permittedUrl, $requestUrl, $resourceType, $requiredPermission)) {
|
275 |
+
// This matches, append signature data
|
276 |
+
$parsedPermittedUrl = parse_url($permittedUrl);
|
277 |
+
|
278 |
+
if (strpos($requestUrl, '?') === false) {
|
279 |
+
$requestUrl .= '?';
|
280 |
+
} else {
|
281 |
+
$requestUrl .= '&';
|
282 |
+
}
|
283 |
+
|
284 |
+
$requestUrl .= $parsedPermittedUrl['query'];
|
285 |
+
|
286 |
+
// Return url
|
287 |
+
return $requestUrl;
|
288 |
+
}
|
289 |
+
}
|
290 |
+
|
291 |
+
// Return url, will be unsigned...
|
292 |
+
return $requestUrl;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Sign request with credentials
|
297 |
+
*
|
298 |
+
* @param string $httpVerb HTTP verb the request will use
|
299 |
+
* @param string $path Path for the request
|
300 |
+
* @param string $queryString Query string for the request
|
301 |
+
* @param array $headers x-ms headers to add
|
302 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
303 |
+
* @param string $resourceType Resource type
|
304 |
+
* @param string $requiredPermission Required permission
|
305 |
+
* @param mixed $rawData Raw post data
|
306 |
+
* @return array Array of headers
|
307 |
+
*/
|
308 |
+
public function signRequestHeaders(
|
309 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
310 |
+
$path = '/',
|
311 |
+
$queryString = '',
|
312 |
+
$headers = null,
|
313 |
+
$forTableStorage = false,
|
314 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
315 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
|
316 |
+
$rawData = null
|
317 |
+
) {
|
318 |
+
return $headers;
|
319 |
+
}
|
320 |
+
}
|
app/libs/Microsoft/WindowsAzure/Credentials/SharedKey.php
ADDED
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
31 |
+
* @license http://phpazure.codeplex.com/license
|
32 |
+
* @version $Id$
|
33 |
+
*/
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
37 |
+
*/
|
38 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @see Microsoft_WindowsAzure_Storage
|
42 |
+
*/
|
43 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @see Microsoft_Http_Client
|
47 |
+
*/
|
48 |
+
require_once 'Microsoft/Http/Client.php';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @see Microsoft_WindowsAzure_Credentials_Exception
|
52 |
+
*/
|
53 |
+
require_once 'Microsoft/WindowsAzure/Credentials/Exception.php';
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @category Microsoft
|
57 |
+
* @package Microsoft_WindowsAzure
|
58 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
59 |
+
* @license http://phpazure.codeplex.com/license
|
60 |
+
*/
|
61 |
+
class Microsoft_WindowsAzure_Credentials_SharedKey
|
62 |
+
extends Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
63 |
+
{
|
64 |
+
/**
|
65 |
+
* Sign request URL with credentials
|
66 |
+
*
|
67 |
+
* @param string $requestUrl Request URL
|
68 |
+
* @param string $resourceType Resource type
|
69 |
+
* @param string $requiredPermission Required permission
|
70 |
+
* @return string Signed request URL
|
71 |
+
*/
|
72 |
+
public function signRequestUrl(
|
73 |
+
$requestUrl = '',
|
74 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
75 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
76 |
+
) {
|
77 |
+
return $requestUrl;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Sign request headers with credentials
|
82 |
+
*
|
83 |
+
* @param string $httpVerb HTTP verb the request will use
|
84 |
+
* @param string $path Path for the request
|
85 |
+
* @param string $queryString Query string for the request
|
86 |
+
* @param array $headers x-ms headers to add
|
87 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
88 |
+
* @param string $resourceType Resource type
|
89 |
+
* @param string $requiredPermission Required permission
|
90 |
+
* @param mixed $rawData Raw post data
|
91 |
+
* @return array Array of headers
|
92 |
+
*/
|
93 |
+
public function signRequestHeaders(
|
94 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
95 |
+
$path = '/',
|
96 |
+
$queryString = '',
|
97 |
+
$headers = null,
|
98 |
+
$forTableStorage = false,
|
99 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
100 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
|
101 |
+
$rawData = null
|
102 |
+
) {
|
103 |
+
// http://github.com/sriramk/winazurestorage/blob/214010a2f8931bac9c96dfeb337d56fe084ca63b/winazurestorage.py
|
104 |
+
|
105 |
+
// Table storage?
|
106 |
+
if ($forTableStorage) {
|
107 |
+
throw new Microsoft_WindowsAzure_Credentials_Exception('The Windows Azure SDK for PHP does not support SharedKey authentication on table storage. Use SharedKeyLite authentication instead.');
|
108 |
+
}
|
109 |
+
|
110 |
+
// Determine path
|
111 |
+
if ($this->_usePathStyleUri) {
|
112 |
+
$path = substr($path, strpos($path, '/'));
|
113 |
+
}
|
114 |
+
|
115 |
+
// Determine query
|
116 |
+
$queryString = $this->_prepareQueryStringForSigning($queryString);
|
117 |
+
|
118 |
+
// Canonicalized headers
|
119 |
+
$canonicalizedHeaders = array();
|
120 |
+
|
121 |
+
// Request date
|
122 |
+
$requestDate = '';
|
123 |
+
if (isset($headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) {
|
124 |
+
$requestDate = $headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'];
|
125 |
+
} else {
|
126 |
+
$requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
|
127 |
+
$canonicalizedHeaders[] = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date:' . $requestDate;
|
128 |
+
}
|
129 |
+
|
130 |
+
// Build canonicalized headers
|
131 |
+
if (!is_null($headers)) {
|
132 |
+
foreach ($headers as $header => $value) {
|
133 |
+
if (is_bool($value)) {
|
134 |
+
$value = $value === true ? 'True' : 'False';
|
135 |
+
}
|
136 |
+
|
137 |
+
$headers[$header] = $value;
|
138 |
+
if (substr($header, 0, strlen(Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER)) == Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER) {
|
139 |
+
$canonicalizedHeaders[] = strtolower($header) . ':' . $value;
|
140 |
+
}
|
141 |
+
}
|
142 |
+
}
|
143 |
+
sort($canonicalizedHeaders);
|
144 |
+
|
145 |
+
// Build canonicalized resource string
|
146 |
+
$canonicalizedResource = '/' . $this->_accountName;
|
147 |
+
if ($this->_usePathStyleUri) {
|
148 |
+
$canonicalizedResource .= '/' . $this->_accountName;
|
149 |
+
}
|
150 |
+
$canonicalizedResource .= $path;
|
151 |
+
if ($queryString !== '') {
|
152 |
+
$queryStringItems = $this->_makeArrayOfQueryString($queryString);
|
153 |
+
foreach ($queryStringItems as $key => $value) {
|
154 |
+
$canonicalizedResource .= "\n" . strtolower($key) . ':' . $value;
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
// Content-Length header
|
159 |
+
$contentLength = '';
|
160 |
+
if (strtoupper($httpVerb) != Microsoft_Http_Client::GET
|
161 |
+
&& strtoupper($httpVerb) != Microsoft_Http_Client::DELETE
|
162 |
+
&& strtoupper($httpVerb) != Microsoft_Http_Client::HEAD) {
|
163 |
+
$contentLength = 0;
|
164 |
+
|
165 |
+
if (!is_null($rawData)) {
|
166 |
+
$contentLength = strlen($rawData);
|
167 |
+
}
|
168 |
+
}
|
169 |
+
|
170 |
+
// Create string to sign
|
171 |
+
$stringToSign = array();
|
172 |
+
$stringToSign[] = strtoupper($httpVerb); // VERB
|
173 |
+
$stringToSign[] = $this->_issetOr($headers, 'Content-Encoding', ''); // Content-Encoding
|
174 |
+
$stringToSign[] = $this->_issetOr($headers, 'Content-Language', ''); // Content-Language
|
175 |
+
$stringToSign[] = $contentLength; // Content-Length
|
176 |
+
$stringToSign[] = $this->_issetOr($headers, 'Content-MD5', ''); // Content-MD5
|
177 |
+
$stringToSign[] = $this->_issetOr($headers, 'Content-Type', ''); // Content-Type
|
178 |
+
$stringToSign[] = ""; // Date
|
179 |
+
$stringToSign[] = $this->_issetOr($headers, 'If-Modified-Since', ''); // If-Modified-Since
|
180 |
+
$stringToSign[] = $this->_issetOr($headers, 'If-Match', ''); // If-Match
|
181 |
+
$stringToSign[] = $this->_issetOr($headers, 'If-None-Match', ''); // If-None-Match
|
182 |
+
$stringToSign[] = $this->_issetOr($headers, 'If-Unmodified-Since', ''); // If-Unmodified-Since
|
183 |
+
$stringToSign[] = $this->_issetOr($headers, 'Range', ''); // Range
|
184 |
+
|
185 |
+
if (!$forTableStorage && count($canonicalizedHeaders) > 0) {
|
186 |
+
$stringToSign[] = implode("\n", $canonicalizedHeaders); // Canonicalized headers
|
187 |
+
}
|
188 |
+
|
189 |
+
$stringToSign[] = $canonicalizedResource; // Canonicalized resource
|
190 |
+
$stringToSign = implode("\n", $stringToSign);
|
191 |
+
$signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
|
192 |
+
|
193 |
+
// Sign request
|
194 |
+
$headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate;
|
195 |
+
$headers['Authorization'] = 'SharedKey ' . $this->_accountName . ':' . $signString;
|
196 |
+
|
197 |
+
// Return headers
|
198 |
+
return $headers;
|
199 |
+
}
|
200 |
+
}
|
app/libs/Microsoft/WindowsAzure/Credentials/SharedKeyLite.php
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
31 |
+
* @license http://phpazure.codeplex.com/license
|
32 |
+
* @version $Id: SharedKeyCredentials.php 14561 2009-05-07 08:05:12Z unknown $
|
33 |
+
*/
|
34 |
+
|
35 |
+
/**
|
36 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
37 |
+
*/
|
38 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
39 |
+
|
40 |
+
/**
|
41 |
+
* @see Microsoft_WindowsAzure_Storage
|
42 |
+
*/
|
43 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
44 |
+
|
45 |
+
/**
|
46 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedKey
|
47 |
+
*/
|
48 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKey.php';
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @see Microsoft_WindowsAzure_Credentials_Exception
|
52 |
+
*/
|
53 |
+
require_once 'Microsoft/WindowsAzure/Credentials/Exception.php';
|
54 |
+
|
55 |
+
/**
|
56 |
+
* @category Microsoft
|
57 |
+
* @package Microsoft_WindowsAzure
|
58 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
59 |
+
* @license http://phpazure.codeplex.com/license
|
60 |
+
*/
|
61 |
+
class Microsoft_WindowsAzure_Credentials_SharedKeyLite
|
62 |
+
extends Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
63 |
+
{
|
64 |
+
/**
|
65 |
+
* Sign request URL with credentials
|
66 |
+
*
|
67 |
+
* @param string $requestUrl Request URL
|
68 |
+
* @param string $resourceType Resource type
|
69 |
+
* @param string $requiredPermission Required permission
|
70 |
+
* @return string Signed request URL
|
71 |
+
*/
|
72 |
+
public function signRequestUrl(
|
73 |
+
$requestUrl = '',
|
74 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
75 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
76 |
+
) {
|
77 |
+
return $requestUrl;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Sign request headers with credentials
|
82 |
+
*
|
83 |
+
* @param string $httpVerb HTTP verb the request will use
|
84 |
+
* @param string $path Path for the request
|
85 |
+
* @param string $queryString Query string for the request
|
86 |
+
* @param array $headers x-ms headers to add
|
87 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
88 |
+
* @param string $resourceType Resource type
|
89 |
+
* @param string $requiredPermission Required permission
|
90 |
+
* @param mixed $rawData Raw post data
|
91 |
+
* @return array Array of headers
|
92 |
+
*/
|
93 |
+
public function signRequestHeaders(
|
94 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
95 |
+
$path = '/',
|
96 |
+
$queryString = '',
|
97 |
+
$headers = null,
|
98 |
+
$forTableStorage = false,
|
99 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
100 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ,
|
101 |
+
$rawData = null
|
102 |
+
) {
|
103 |
+
// Table storage?
|
104 |
+
if (!$forTableStorage) {
|
105 |
+
throw new Microsoft_WindowsAzure_Credentials_Exception('The Windows Azure SDK for PHP does not support SharedKeyLite authentication on blob or queue storage. Use SharedKey authentication instead.');
|
106 |
+
}
|
107 |
+
|
108 |
+
// Determine path
|
109 |
+
if ($this->_usePathStyleUri) {
|
110 |
+
$path = substr($path, strpos($path, '/'));
|
111 |
+
}
|
112 |
+
|
113 |
+
// Determine query
|
114 |
+
$queryString = $this->_prepareQueryStringForSigning($queryString);
|
115 |
+
|
116 |
+
// Build canonicalized resource string
|
117 |
+
$canonicalizedResource = '/' . $this->_accountName;
|
118 |
+
if ($this->_usePathStyleUri) {
|
119 |
+
$canonicalizedResource .= '/' . $this->_accountName;
|
120 |
+
}
|
121 |
+
$canonicalizedResource .= $path;
|
122 |
+
if ($queryString !== '') {
|
123 |
+
$canonicalizedResource .= $queryString;
|
124 |
+
}
|
125 |
+
|
126 |
+
// Request date
|
127 |
+
$requestDate = '';
|
128 |
+
if (isset($headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'])) {
|
129 |
+
$requestDate = $headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'];
|
130 |
+
} else {
|
131 |
+
$requestDate = gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
|
132 |
+
}
|
133 |
+
|
134 |
+
// Create string to sign
|
135 |
+
$stringToSign = array();
|
136 |
+
$stringToSign[] = $requestDate; // Date
|
137 |
+
$stringToSign[] = $canonicalizedResource; // Canonicalized resource
|
138 |
+
$stringToSign = implode("\n", $stringToSign);
|
139 |
+
$signString = base64_encode(hash_hmac('sha256', $stringToSign, $this->_accountKey, true));
|
140 |
+
|
141 |
+
// Sign request
|
142 |
+
$headers[Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PREFIX_STORAGE_HEADER . 'date'] = $requestDate;
|
143 |
+
$headers['Authorization'] = 'SharedKeyLite ' . $this->_accountName . ':' . $signString;
|
144 |
+
|
145 |
+
// Return headers
|
146 |
+
return $headers;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Prepare query string for signing
|
151 |
+
*
|
152 |
+
* @param string $value Original query string
|
153 |
+
* @return string Query string for signing
|
154 |
+
*/
|
155 |
+
protected function _prepareQueryStringForSigning($value)
|
156 |
+
{
|
157 |
+
// Check for 'comp='
|
158 |
+
if (strpos($value, 'comp=') === false) {
|
159 |
+
// If not found, no query string needed
|
160 |
+
return '';
|
161 |
+
} else {
|
162 |
+
// If found, make sure it is the only parameter being used
|
163 |
+
if (strlen($value) > 0 && strpos($value, '?') === 0) {
|
164 |
+
$value = substr($value, 1);
|
165 |
+
}
|
166 |
+
|
167 |
+
// Split parts
|
168 |
+
$queryParts = explode('&', $value);
|
169 |
+
foreach ($queryParts as $queryPart) {
|
170 |
+
if (strpos($queryPart, 'comp=') !== false) {
|
171 |
+
return '?' . $queryPart;
|
172 |
+
}
|
173 |
+
}
|
174 |
+
|
175 |
+
// Should never happen...
|
176 |
+
return '';
|
177 |
+
}
|
178 |
+
}
|
179 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDataSources.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationLogs
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationLogs.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationDiagnosticInfrastructureLogs
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationPerformanceCounters
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationWindowsEventLog
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationDirectories
|
68 |
+
*/
|
69 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationDirectories.php';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @category Microsoft
|
73 |
+
* @package Microsoft_WindowsAzure
|
74 |
+
* @subpackage Diagnostics
|
75 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
76 |
+
* @license http://phpazure.codeplex.com/license
|
77 |
+
*
|
78 |
+
* @property int OverallQuotaInMB Overall quota in MB
|
79 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationLogs Logs Logs
|
80 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationDiagnosticInfrastructureLogs DiagnosticInfrastructureLogs Diagnostic infrastructure logs
|
81 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationPerformanceCounters PerformanceCounters Performance counters
|
82 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationWindowsEventLog WindowsEventLog Windows Event Log
|
83 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationDirectories Directories Directories
|
84 |
+
*/
|
85 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationDataSources
|
86 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
87 |
+
{
|
88 |
+
/**
|
89 |
+
* Constructor
|
90 |
+
*
|
91 |
+
* @param int $overallQuotaInMB Overall quota in MB
|
92 |
+
*/
|
93 |
+
public function __construct($overallQuotaInMB = 0)
|
94 |
+
{
|
95 |
+
$this->_data = array(
|
96 |
+
'overallquotainmb' => $overallQuotaInMB,
|
97 |
+
'logs' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationLogs(),
|
98 |
+
'diagnosticinfrastructurelogs' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationDiagnosticInfrastructureLogs(),
|
99 |
+
'performancecounters' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationPerformanceCounters(),
|
100 |
+
'windowseventlog' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationWindowsEventLog(),
|
101 |
+
'directories' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationDirectories()
|
102 |
+
);
|
103 |
+
}
|
104 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDiagnosticInfrastructureLogs.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_LogLevel
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/LogLevel.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property int BufferQuotaInMB Buffer quota in MB
|
59 |
+
* @property int ScheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
60 |
+
* @property string ScheduledTransferLogLevelFilter Scheduled transfer log level filter
|
61 |
+
*/
|
62 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationDiagnosticInfrastructureLogs
|
63 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
64 |
+
{
|
65 |
+
/**
|
66 |
+
* Constructor
|
67 |
+
*
|
68 |
+
* @param int $bufferQuotaInMB Buffer quota in MB
|
69 |
+
* @param int $scheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
70 |
+
* @param string $scheduledTransferLogLevelFilter Scheduled transfer log level filter
|
71 |
+
*/
|
72 |
+
public function __construct($bufferQuotaInMB = 0, $scheduledTransferPeriodInMinutes = 0, $scheduledTransferLogLevelFilter = Microsoft_WindowsAzure_Diagnostics_LogLevel::UNDEFINED)
|
73 |
+
{
|
74 |
+
$this->_data = array(
|
75 |
+
'bufferquotainmb' => $bufferQuotaInMB,
|
76 |
+
'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes,
|
77 |
+
'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter
|
78 |
+
);
|
79 |
+
}
|
80 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationDirectories.php
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_DirectoryConfigurationSubscription
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property int BufferQuotaInMB Buffer quota in MB
|
59 |
+
* @property int ScheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
60 |
+
* @property array Subscriptions Subscriptions
|
61 |
+
*/
|
62 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationDirectories
|
63 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
64 |
+
{
|
65 |
+
/**
|
66 |
+
* Constructor
|
67 |
+
*
|
68 |
+
* @param int $bufferQuotaInMB Buffer quota in MB
|
69 |
+
* @param int $scheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
70 |
+
*/
|
71 |
+
public function __construct($bufferQuotaInMB = 0, $scheduledTransferPeriodInMinutes = 0)
|
72 |
+
{
|
73 |
+
$this->_data = array(
|
74 |
+
'bufferquotainmb' => $bufferQuotaInMB,
|
75 |
+
'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes,
|
76 |
+
'subscriptions' => array()
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Add subscription
|
82 |
+
*
|
83 |
+
* @param string $path Path
|
84 |
+
* @param string $container Container
|
85 |
+
* @param int $directoryQuotaInMB Directory quota in MB
|
86 |
+
*/
|
87 |
+
public function addSubscription($path, $container, $directoryQuotaInMB = 1024)
|
88 |
+
{
|
89 |
+
$this->_data['subscriptions'][$path] = new Microsoft_WindowsAzure_Diagnostics_DirectoryConfigurationSubscription($path, $container, $directoryQuotaInMB);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Remove subscription
|
94 |
+
*
|
95 |
+
* @param string $path Path
|
96 |
+
*/
|
97 |
+
public function removeSubscription($path)
|
98 |
+
{
|
99 |
+
if (isset($this->_data['subscriptions'][$path])) {
|
100 |
+
unset($this->_data['subscriptions'][$path]);
|
101 |
+
}
|
102 |
+
}
|
103 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationInstance.php
ADDED
@@ -0,0 +1,234 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationDataSources
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationDataSources.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property Microsoft_WindowsAzure_Diagnostics_ConfigurationDataSources DataSources Data sources
|
59 |
+
*/
|
60 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance
|
61 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
62 |
+
{
|
63 |
+
/**
|
64 |
+
* Constructor
|
65 |
+
*/
|
66 |
+
public function __construct()
|
67 |
+
{
|
68 |
+
$this->_data = array(
|
69 |
+
'datasources' => new Microsoft_WindowsAzure_Diagnostics_ConfigurationDataSources()
|
70 |
+
);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Load configuration XML
|
75 |
+
*
|
76 |
+
* @param string $configurationXml Configuration XML
|
77 |
+
*/
|
78 |
+
public function loadXml($configurationXml)
|
79 |
+
{
|
80 |
+
// Convert to SimpleXMLElement
|
81 |
+
$configurationXml = simplexml_load_string($configurationXml);
|
82 |
+
|
83 |
+
// Assign general settings
|
84 |
+
$this->DataSources->OverallQuotaInMB = (int)$configurationXml->DataSources->OverallQuotaInMB;
|
85 |
+
|
86 |
+
// Assign Logs settings
|
87 |
+
$this->DataSources->Logs->BufferQuotaInMB = (int)$configurationXml->DataSources->Logs->BufferQuotaInMB;
|
88 |
+
$this->DataSources->Logs->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->Logs->ScheduledTransferPeriodInMinutes;
|
89 |
+
$this->DataSources->Logs->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->Logs->ScheduledTransferLogLevelFilter;
|
90 |
+
|
91 |
+
// Assign DiagnosticInfrastructureLogs settings
|
92 |
+
$this->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB = (int)$configurationXml->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB;
|
93 |
+
$this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes;
|
94 |
+
$this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter;
|
95 |
+
|
96 |
+
// Assign PerformanceCounters settings
|
97 |
+
$this->DataSources->PerformanceCounters->BufferQuotaInMB = (int)$configurationXml->DataSources->PerformanceCounters->BufferQuotaInMB;
|
98 |
+
$this->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes;
|
99 |
+
if ($configurationXml->DataSources->PerformanceCounters->Subscriptions
|
100 |
+
&& $configurationXml->DataSources->PerformanceCounters->Subscriptions->PerformanceCounterConfiguration) {
|
101 |
+
$subscriptions = $configurationXml->DataSources->PerformanceCounters->Subscriptions;
|
102 |
+
if (count($subscriptions->PerformanceCounterConfiguration) > 1) {
|
103 |
+
$subscriptions = $subscriptions->PerformanceCounterConfiguration;
|
104 |
+
} else {
|
105 |
+
$subscriptions = array($subscriptions->PerformanceCounterConfiguration);
|
106 |
+
}
|
107 |
+
foreach ($subscriptions as $subscription) {
|
108 |
+
$this->DataSources->PerformanceCounters->addSubscription((string)$subscription->CounterSpecifier, (int)$subscription->SampleRateInSeconds);
|
109 |
+
}
|
110 |
+
}
|
111 |
+
|
112 |
+
// Assign WindowsEventLog settings
|
113 |
+
$this->DataSources->WindowsEventLog->BufferQuotaInMB = (int)$configurationXml->DataSources->WindowsEventLog->BufferQuotaInMB;
|
114 |
+
$this->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes;
|
115 |
+
$this->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter = (string)$configurationXml->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter;
|
116 |
+
if ($configurationXml->DataSources->WindowsEventLog->Subscriptions
|
117 |
+
&& $configurationXml->DataSources->WindowsEventLog->Subscriptions->string) {
|
118 |
+
$subscriptions = $configurationXml->DataSources->WindowsEventLog->Subscriptions;
|
119 |
+
if (count($subscriptions->string) > 1) {
|
120 |
+
$subscriptions = $subscriptions->string;
|
121 |
+
} else {
|
122 |
+
$subscriptions = array($subscriptions->string);
|
123 |
+
}
|
124 |
+
foreach ($subscriptions as $subscription) {
|
125 |
+
$this->DataSources->WindowsEventLog->addSubscription((string)$subscription);
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
// Assign Directories settings
|
130 |
+
$this->DataSources->Directories->BufferQuotaInMB = (int)$configurationXml->DataSources->Directories->BufferQuotaInMB;
|
131 |
+
$this->DataSources->Directories->ScheduledTransferPeriodInMinutes = (int)$configurationXml->DataSources->Directories->ScheduledTransferPeriodInMinutes;
|
132 |
+
|
133 |
+
if ($configurationXml->DataSources->Directories->Subscriptions
|
134 |
+
&& $configurationXml->DataSources->Directories->Subscriptions->DirectoryConfiguration) {
|
135 |
+
$subscriptions = $configurationXml->DataSources->Directories->Subscriptions;
|
136 |
+
if (count($subscriptions->DirectoryConfiguration) > 1) {
|
137 |
+
$subscriptions = $subscriptions->DirectoryConfiguration;
|
138 |
+
} else {
|
139 |
+
$subscriptions = array($subscriptions->DirectoryConfiguration);
|
140 |
+
}
|
141 |
+
foreach ($subscriptions as $subscription) {
|
142 |
+
$this->DataSources->Directories->addSubscription((string)$subscription->Path, (string)$subscription->Container, (int)$subscription->DirectoryQuotaInMB);
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Create configuration XML
|
149 |
+
*
|
150 |
+
* @return string
|
151 |
+
*/
|
152 |
+
public function toXml()
|
153 |
+
{
|
154 |
+
// Return value
|
155 |
+
$returnValue = array();
|
156 |
+
|
157 |
+
// Build XML
|
158 |
+
$returnValue[] = '<?xml version="1.0"?>';
|
159 |
+
$returnValue[] = '<ConfigRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">';
|
160 |
+
|
161 |
+
// Add data sources
|
162 |
+
$returnValue[] = ' <DataSources>';
|
163 |
+
|
164 |
+
$returnValue[] = ' <OverallQuotaInMB>' . $this->DataSources->OverallQuotaInMB . '</OverallQuotaInMB>';
|
165 |
+
|
166 |
+
$returnValue[] = ' <Logs>';
|
167 |
+
$returnValue[] = ' <BufferQuotaInMB>' . $this->DataSources->Logs->BufferQuotaInMB . '</BufferQuotaInMB>';
|
168 |
+
$returnValue[] = ' <ScheduledTransferPeriodInMinutes>' . $this->DataSources->Logs->ScheduledTransferPeriodInMinutes . '</ScheduledTransferPeriodInMinutes>';
|
169 |
+
$returnValue[] = ' <ScheduledTransferLogLevelFilter>' . $this->DataSources->Logs->ScheduledTransferLogLevelFilter . '</ScheduledTransferLogLevelFilter>';
|
170 |
+
$returnValue[] = ' </Logs>';
|
171 |
+
|
172 |
+
$returnValue[] = ' <DiagnosticInfrastructureLogs>';
|
173 |
+
$returnValue[] = ' <BufferQuotaInMB>' . $this->DataSources->DiagnosticInfrastructureLogs->BufferQuotaInMB . '</BufferQuotaInMB>';
|
174 |
+
$returnValue[] = ' <ScheduledTransferPeriodInMinutes>' . $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferPeriodInMinutes . '</ScheduledTransferPeriodInMinutes>';
|
175 |
+
$returnValue[] = ' <ScheduledTransferLogLevelFilter>' . $this->DataSources->DiagnosticInfrastructureLogs->ScheduledTransferLogLevelFilter . '</ScheduledTransferLogLevelFilter>';
|
176 |
+
$returnValue[] = ' </DiagnosticInfrastructureLogs>';
|
177 |
+
|
178 |
+
$returnValue[] = ' <PerformanceCounters>';
|
179 |
+
$returnValue[] = ' <BufferQuotaInMB>' . $this->DataSources->PerformanceCounters->BufferQuotaInMB . '</BufferQuotaInMB>';
|
180 |
+
$returnValue[] = ' <ScheduledTransferPeriodInMinutes>' . $this->DataSources->PerformanceCounters->ScheduledTransferPeriodInMinutes . '</ScheduledTransferPeriodInMinutes>';
|
181 |
+
if (count($this->DataSources->PerformanceCounters->Subscriptions) == 0) {
|
182 |
+
$returnValue[] = ' <Subscriptions />';
|
183 |
+
} else {
|
184 |
+
$returnValue[] = ' <Subscriptions>';
|
185 |
+
foreach ($this->DataSources->PerformanceCounters->Subscriptions as $subscription) {
|
186 |
+
$returnValue[] = ' <PerformanceCounterConfiguration>';
|
187 |
+
$returnValue[] = ' <CounterSpecifier>' . $subscription->CounterSpecifier . '</CounterSpecifier>';
|
188 |
+
$returnValue[] = ' <SampleRateInSeconds>' . $subscription->SampleRateInSeconds . '</SampleRateInSeconds>';
|
189 |
+
$returnValue[] = ' </PerformanceCounterConfiguration>';
|
190 |
+
}
|
191 |
+
$returnValue[] = ' </Subscriptions>';
|
192 |
+
}
|
193 |
+
$returnValue[] = ' </PerformanceCounters>';
|
194 |
+
|
195 |
+
$returnValue[] = ' <WindowsEventLog>';
|
196 |
+
$returnValue[] = ' <BufferQuotaInMB>' . $this->DataSources->WindowsEventLog->BufferQuotaInMB . '</BufferQuotaInMB>';
|
197 |
+
$returnValue[] = ' <ScheduledTransferPeriodInMinutes>' . $this->DataSources->WindowsEventLog->ScheduledTransferPeriodInMinutes . '</ScheduledTransferPeriodInMinutes>';
|
198 |
+
if (count($this->DataSources->WindowsEventLog->Subscriptions) == 0) {
|
199 |
+
$returnValue[] = ' <Subscriptions />';
|
200 |
+
} else {
|
201 |
+
$returnValue[] = ' <Subscriptions>';
|
202 |
+
foreach ($this->DataSources->WindowsEventLog->Subscriptions as $subscription) {
|
203 |
+
$returnValue[] = ' <string>' . $subscription . '</string>';
|
204 |
+
}
|
205 |
+
$returnValue[] = ' </Subscriptions>';
|
206 |
+
}
|
207 |
+
$returnValue[] = ' <ScheduledTransferLogLevelFilter>' . $this->DataSources->WindowsEventLog->ScheduledTransferLogLevelFilter . '</ScheduledTransferLogLevelFilter>';
|
208 |
+
$returnValue[] = ' </WindowsEventLog>';
|
209 |
+
|
210 |
+
$returnValue[] = ' <Directories>';
|
211 |
+
$returnValue[] = ' <BufferQuotaInMB>' . $this->DataSources->Directories->BufferQuotaInMB . '</BufferQuotaInMB>';
|
212 |
+
$returnValue[] = ' <ScheduledTransferPeriodInMinutes>' . $this->DataSources->Directories->ScheduledTransferPeriodInMinutes . '</ScheduledTransferPeriodInMinutes>';
|
213 |
+
if (count($this->DataSources->Directories->Subscriptions) == 0) {
|
214 |
+
$returnValue[] = ' <Subscriptions />';
|
215 |
+
} else {
|
216 |
+
$returnValue[] = ' <Subscriptions>';
|
217 |
+
foreach ($this->DataSources->Directories->Subscriptions as $subscription) {
|
218 |
+
$returnValue[] = ' <DirectoryConfiguration>';
|
219 |
+
$returnValue[] = ' <Path>' . $subscription->Path . '</Path>';
|
220 |
+
$returnValue[] = ' <Container>' . $subscription->Container . '</Container>';
|
221 |
+
$returnValue[] = ' <DirectoryQuotaInMB>' . $subscription->DirectoryQuotaInMB . '</DirectoryQuotaInMB>';
|
222 |
+
$returnValue[] = ' </DirectoryConfiguration>';
|
223 |
+
}
|
224 |
+
$returnValue[] = ' </Subscriptions>';
|
225 |
+
}
|
226 |
+
$returnValue[] = ' </Directories>';
|
227 |
+
|
228 |
+
$returnValue[] = ' </DataSources>';
|
229 |
+
$returnValue[] = '</ConfigRequest>';
|
230 |
+
|
231 |
+
// Return
|
232 |
+
return implode("\r\n", $returnValue);
|
233 |
+
}
|
234 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationLogs.php
ADDED
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_LogLevel
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/LogLevel.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property int BufferQuotaInMB Buffer quota in MB
|
59 |
+
* @property int ScheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
60 |
+
* @property string ScheduledTransferLogLevelFilter Scheduled transfer log level filter
|
61 |
+
*/
|
62 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationLogs
|
63 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
64 |
+
{
|
65 |
+
/**
|
66 |
+
* Constructor
|
67 |
+
*
|
68 |
+
* @param int $bufferQuotaInMB Buffer quota in MB
|
69 |
+
* @param int $scheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
70 |
+
* @param string $scheduledTransferLogLevelFilter Scheduled transfer log level filter
|
71 |
+
*/
|
72 |
+
public function __construct($bufferQuotaInMB = 0, $scheduledTransferPeriodInMinutes = 0, $scheduledTransferLogLevelFilter = Microsoft_WindowsAzure_Diagnostics_LogLevel::UNDEFINED)
|
73 |
+
{
|
74 |
+
$this->_data = array(
|
75 |
+
'bufferquotainmb' => $bufferQuotaInMB,
|
76 |
+
'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes,
|
77 |
+
'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter
|
78 |
+
);
|
79 |
+
}
|
80 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @subpackage Diagnostics
|
45 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
46 |
+
* @license http://phpazure.codeplex.com/license
|
47 |
+
*/
|
48 |
+
abstract class Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
49 |
+
{
|
50 |
+
/**
|
51 |
+
* Data
|
52 |
+
*
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
+
protected $_data = null;
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Magic overload for setting properties
|
59 |
+
*
|
60 |
+
* @param string $name Name of the property
|
61 |
+
* @param string $value Value to set
|
62 |
+
*/
|
63 |
+
public function __set($name, $value) {
|
64 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
65 |
+
$this->_data[strtolower($name)] = $value;
|
66 |
+
return;
|
67 |
+
}
|
68 |
+
|
69 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception("Unknown property: " . $name);
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Magic overload for getting properties
|
74 |
+
*
|
75 |
+
* @param string $name Name of the property
|
76 |
+
*/
|
77 |
+
public function __get($name) {
|
78 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
79 |
+
return $this->_data[strtolower($name)];
|
80 |
+
}
|
81 |
+
|
82 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception("Unknown property: " . $name);
|
83 |
+
}
|
84 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationPerformanceCounters.php
ADDED
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_PerformanceCounterSubscription
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property int BufferQuotaInMB Buffer quota in MB
|
59 |
+
* @property int ScheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
60 |
+
* @property array Subscriptions Subscriptions
|
61 |
+
*/
|
62 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationPerformanceCounters
|
63 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
64 |
+
{
|
65 |
+
/**
|
66 |
+
* Constructor
|
67 |
+
*
|
68 |
+
* @param int $bufferQuotaInMB Buffer quota in MB
|
69 |
+
* @param int $scheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
70 |
+
*/
|
71 |
+
public function __construct($bufferQuotaInMB = 0, $scheduledTransferPeriodInMinutes = 0)
|
72 |
+
{
|
73 |
+
$this->_data = array(
|
74 |
+
'bufferquotainmb' => $bufferQuotaInMB,
|
75 |
+
'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes,
|
76 |
+
'subscriptions' => array()
|
77 |
+
);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Add subscription
|
82 |
+
*
|
83 |
+
* @param string $counterSpecifier Counter specifier
|
84 |
+
* @param int $sampleRateInSeconds Sample rate in seconds
|
85 |
+
*/
|
86 |
+
public function addSubscription($counterSpecifier, $sampleRateInSeconds = 1)
|
87 |
+
{
|
88 |
+
$this->_data['subscriptions'][$counterSpecifier] = new Microsoft_WindowsAzure_Diagnostics_PerformanceCounterSubscription($counterSpecifier, $sampleRateInSeconds);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Remove subscription
|
93 |
+
*
|
94 |
+
* @param string $counterSpecifier Counter specifier
|
95 |
+
*/
|
96 |
+
public function removeSubscription($counterSpecifier)
|
97 |
+
{
|
98 |
+
if (isset($this->_data['subscriptions'][$counterSpecifier])) {
|
99 |
+
unset($this->_data['subscriptions'][$counterSpecifier]);
|
100 |
+
}
|
101 |
+
}
|
102 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/ConfigurationWindowsEventLog.php
ADDED
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_LogLevel
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/LogLevel.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*
|
58 |
+
* @property int BufferQuotaInMB Buffer quota in MB
|
59 |
+
* @property int ScheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
60 |
+
* @property string ScheduledTransferLogLevelFilter Scheduled transfer log level filter
|
61 |
+
* @property array Subscriptions Subscriptions
|
62 |
+
*/
|
63 |
+
class Microsoft_WindowsAzure_Diagnostics_ConfigurationWindowsEventLog
|
64 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
65 |
+
{
|
66 |
+
/**
|
67 |
+
* Constructor
|
68 |
+
*
|
69 |
+
* @param int $bufferQuotaInMB Buffer quota in MB
|
70 |
+
* @param int $scheduledTransferPeriodInMinutes Scheduled transfer period in minutes
|
71 |
+
* @param string $scheduledTransferLogLevelFilter Scheduled transfer log level filter
|
72 |
+
*/
|
73 |
+
public function __construct($bufferQuotaInMB = 0, $scheduledTransferPeriodInMinutes = 0, $scheduledTransferLogLevelFilter = Microsoft_WindowsAzure_Diagnostics_LogLevel::UNDEFINED)
|
74 |
+
{
|
75 |
+
$this->_data = array(
|
76 |
+
'bufferquotainmb' => $bufferQuotaInMB,
|
77 |
+
'scheduledtransferperiodinminutes' => $scheduledTransferPeriodInMinutes,
|
78 |
+
'scheduledtransferloglevelfilter' => $scheduledTransferLogLevelFilter,
|
79 |
+
'subscriptions' => array()
|
80 |
+
);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Add subscription
|
85 |
+
*
|
86 |
+
* @param string $filter Event log filter
|
87 |
+
*/
|
88 |
+
public function addSubscription($filter)
|
89 |
+
{
|
90 |
+
$this->_data['subscriptions'][$filter] = $filter;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Remove subscription
|
95 |
+
*
|
96 |
+
* @param string $filter Event log filter
|
97 |
+
*/
|
98 |
+
public function removeSubscription($filter)
|
99 |
+
{
|
100 |
+
if (isset($this->_data['subscriptions'][$filter])) {
|
101 |
+
unset($this->_data['subscriptions'][$filter]);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/DirectoryConfigurationSubscription.php
ADDED
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Diagnostics
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string Path Path
|
54 |
+
* @property string Container Container
|
55 |
+
* @property int DirectoryQuotaInMB Directory quota in MB
|
56 |
+
*/
|
57 |
+
class Microsoft_WindowsAzure_Diagnostics_DirectoryConfigurationSubscription
|
58 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
59 |
+
{
|
60 |
+
/**
|
61 |
+
* Constructor
|
62 |
+
*
|
63 |
+
* @param string $path Path
|
64 |
+
* @param string $container Container
|
65 |
+
* @param int $directoryQuotaInMB Directory quota in MB
|
66 |
+
*/
|
67 |
+
public function __construct($path, $container, $directoryQuotaInMB = 1024)
|
68 |
+
{
|
69 |
+
$this->_data = array(
|
70 |
+
'path' => $path,
|
71 |
+
'container' => $container,
|
72 |
+
'directoryquotainmb' => $directoryQuotaInMB
|
73 |
+
);
|
74 |
+
}
|
75 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/Exception.php
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @subpackage Diagnostics
|
45 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
46 |
+
* @license http://phpazure.codeplex.com/license
|
47 |
+
*/
|
48 |
+
class Microsoft_WindowsAzure_Diagnostics_Exception
|
49 |
+
extends Microsoft_WindowsAzure_Exception
|
50 |
+
{
|
51 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/LogLevel.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @category Microsoft
|
39 |
+
* @package Microsoft_WindowsAzure
|
40 |
+
* @subpackage Diagnostics
|
41 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
42 |
+
* @license http://phpazure.codeplex.com/license
|
43 |
+
*/
|
44 |
+
class Microsoft_WindowsAzure_Diagnostics_LogLevel
|
45 |
+
{
|
46 |
+
const UNDEFINED = 'Undefined';
|
47 |
+
const CRITICAL = 'Critical';
|
48 |
+
const ERROR = 'Error';
|
49 |
+
const WARNING = 'Warning';
|
50 |
+
const INFORMATION = 'Information';
|
51 |
+
const VERBOSE = 'Verbose';
|
52 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/Manager.php
ADDED
@@ -0,0 +1,225 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Storage_Blob
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationInstance.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage Diagnostics
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*/
|
58 |
+
class Microsoft_WindowsAzure_Diagnostics_Manager
|
59 |
+
{
|
60 |
+
/**
|
61 |
+
* Blob storage client
|
62 |
+
*
|
63 |
+
* @var Microsoft_WindowsAzure_Storage_Blob
|
64 |
+
*/
|
65 |
+
protected $_blobStorageClient = null;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Control container name
|
69 |
+
*
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
protected $_controlContainer = '';
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Create a new instance of Microsoft_WindowsAzure_Diagnostics_Manager
|
76 |
+
*
|
77 |
+
* @param Microsoft_WindowsAzure_Storage_Blob $blobStorageClient Blob storage client
|
78 |
+
* @param string $controlContainer Control container name
|
79 |
+
*/
|
80 |
+
public function __construct(Microsoft_WindowsAzure_Storage_Blob $blobStorageClient = null, $controlContainer = 'wad-control-container')
|
81 |
+
{
|
82 |
+
$this->_blobStorageClient = $blobStorageClient;
|
83 |
+
$this->_controlContainer = $controlContainer;
|
84 |
+
|
85 |
+
$this->_ensureStorageInitialized();
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Ensure storage has been initialized
|
90 |
+
*/
|
91 |
+
protected function _ensureStorageInitialized()
|
92 |
+
{
|
93 |
+
if (!$this->_blobStorageClient->containerExists($this->_controlContainer)) {
|
94 |
+
$this->_blobStorageClient->createContainer($this->_controlContainer);
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get default configuration values
|
100 |
+
*
|
101 |
+
* @return Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance
|
102 |
+
*/
|
103 |
+
public function getDefaultConfiguration()
|
104 |
+
{
|
105 |
+
return new Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance();
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Checks if a configuration for a specific role instance exists.
|
110 |
+
*
|
111 |
+
* @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure.
|
112 |
+
* @return boolean
|
113 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
114 |
+
*/
|
115 |
+
public function configurationForRoleInstanceExists($roleInstance = null)
|
116 |
+
{
|
117 |
+
if (is_null($roleInstance)) {
|
118 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.');
|
119 |
+
}
|
120 |
+
|
121 |
+
return $this->_blobStorageClient->blobExists($this->_controlContainer, $roleInstance);
|
122 |
+
}
|
123 |
+
|
124 |
+
/**
|
125 |
+
* Checks if a configuration for current role instance exists. Only works on Development Fabric or Windows Azure Fabric.
|
126 |
+
*
|
127 |
+
* @return boolean
|
128 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
129 |
+
*/
|
130 |
+
public function configurationForCurrentRoleInstanceExists()
|
131 |
+
{
|
132 |
+
if (!isset($_SERVER['RdRoleId'])) {
|
133 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.');
|
134 |
+
}
|
135 |
+
|
136 |
+
return $this->_blobStorageClient->blobExists($this->_controlContainer, $this->_getCurrentRoleInstanceId());
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Get configuration for current role instance. Only works on Development Fabric or Windows Azure Fabric.
|
141 |
+
*
|
142 |
+
* @return Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance
|
143 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
144 |
+
*/
|
145 |
+
public function getConfigurationForCurrentRoleInstance()
|
146 |
+
{
|
147 |
+
if (!isset($_SERVER['RdRoleId'])) {
|
148 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.');
|
149 |
+
}
|
150 |
+
return $this->getConfigurationForRoleInstance($this->_getCurrentRoleInstanceId());
|
151 |
+
}
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Get the current role instance ID. Only works on Development Fabric or Windows Azure Fabric.
|
155 |
+
*
|
156 |
+
* @return string
|
157 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
158 |
+
*/
|
159 |
+
protected function _getCurrentRoleInstanceId()
|
160 |
+
{
|
161 |
+
if (!isset($_SERVER['RdRoleId'])) {
|
162 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.');
|
163 |
+
}
|
164 |
+
|
165 |
+
if (strpos($_SERVER['RdRoleId'], 'deployment(') === false) {
|
166 |
+
return $_SERVER['RdRoleId'];
|
167 |
+
} else {
|
168 |
+
$roleIdParts = explode('.', $_SERVER['RdRoleId']);
|
169 |
+
return $roleIdParts[0] . '/' . $roleIdParts[2] . '/' . $_SERVER['RdRoleId'];
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
/**
|
174 |
+
* Set configuration for current role instance. Only works on Development Fabric or Windows Azure Fabric.
|
175 |
+
*
|
176 |
+
* @param Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance $configuration Configuration to apply
|
177 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
178 |
+
*/
|
179 |
+
public function setConfigurationForCurrentRoleInstance(Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance $configuration)
|
180 |
+
{
|
181 |
+
if (!isset($_SERVER['RdRoleId'])) {
|
182 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Server variable \'RdRoleId\' is unknown. Please verify the application is running in Development Fabric or Windows Azure Fabric.');
|
183 |
+
}
|
184 |
+
|
185 |
+
$this->setConfigurationForRoleInstance($this->_getCurrentRoleInstanceId(), $configuration);
|
186 |
+
}
|
187 |
+
|
188 |
+
/**
|
189 |
+
* Get configuration for a specific role instance
|
190 |
+
*
|
191 |
+
* @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure.
|
192 |
+
* @return Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance
|
193 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
194 |
+
*/
|
195 |
+
public function getConfigurationForRoleInstance($roleInstance = null)
|
196 |
+
{
|
197 |
+
if (is_null($roleInstance)) {
|
198 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.');
|
199 |
+
}
|
200 |
+
|
201 |
+
if ($this->_blobStorageClient->blobExists($this->_controlContainer, $roleInstance)) {
|
202 |
+
$configurationInstance = new Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance();
|
203 |
+
$configurationInstance->loadXml( $this->_blobStorageClient->getBlobData($this->_controlContainer, $roleInstance) );
|
204 |
+
return $configurationInstance;
|
205 |
+
}
|
206 |
+
|
207 |
+
return new Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance();
|
208 |
+
}
|
209 |
+
|
210 |
+
/**
|
211 |
+
* Set configuration for a specific role instance
|
212 |
+
*
|
213 |
+
* @param string $roleInstance Role instance name, can be found in $_SERVER['RdRoleId'] when hosted on Windows Azure.
|
214 |
+
* @param Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance $configuration Configuration to apply
|
215 |
+
* @throws Microsoft_WindowsAzure_Diagnostics_Exception
|
216 |
+
*/
|
217 |
+
public function setConfigurationForRoleInstance($roleInstance = null, Microsoft_WindowsAzure_Diagnostics_ConfigurationInstance $configuration)
|
218 |
+
{
|
219 |
+
if (is_null($roleInstance)) {
|
220 |
+
throw new Microsoft_WindowsAzure_Diagnostics_Exception('Role instance should be specified. Try reading $_SERVER[\'RdRoleId\'] for this information if the application is hosted on Windows Azure Fabric or Development Fabric.');
|
221 |
+
}
|
222 |
+
|
223 |
+
$this->_blobStorageClient->putBlobData($this->_controlContainer, $roleInstance, $configuration->toXml(), array(), null, array('Content-Type' => 'text/xml'));
|
224 |
+
}
|
225 |
+
}
|
app/libs/Microsoft/WindowsAzure/Diagnostics/PerformanceCounterSubscription.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Diagnostics
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 45989 2010-05-03 12:19:10Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Diagnostics_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Diagnostics/ConfigurationObjectBaseAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Diagnostics
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string CounterSpecifier Counter specifier
|
54 |
+
* @property int SampleRateInSeconds Sample rate in seconds
|
55 |
+
*/
|
56 |
+
class Microsoft_WindowsAzure_Diagnostics_PerformanceCounterSubscription
|
57 |
+
extends Microsoft_WindowsAzure_Diagnostics_ConfigurationObjectBaseAbstract
|
58 |
+
{
|
59 |
+
/**
|
60 |
+
* Constructor
|
61 |
+
*
|
62 |
+
* @param string $counterSpecifier Counter specifier
|
63 |
+
* @param int $sampleRateInSeconds Sample rate in seconds
|
64 |
+
*/
|
65 |
+
public function __construct($counterSpecifier, $sampleRateInSeconds = 1)
|
66 |
+
{
|
67 |
+
$this->_data = array(
|
68 |
+
'counterspecifier' => $counterSpecifier,
|
69 |
+
'samplerateinseconds' => $sampleRateInSeconds
|
70 |
+
);
|
71 |
+
}
|
72 |
+
}
|
app/libs/Microsoft/WindowsAzure/Exception.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Exception
|
31 |
+
* @version $Id: Exception.php 45259 2010-04-16 12:13:55Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
45 |
+
* @license http://phpazure.codeplex.com/license
|
46 |
+
*/
|
47 |
+
class Microsoft_WindowsAzure_Exception extends Microsoft_Exception
|
48 |
+
{}
|
app/libs/Microsoft/WindowsAzure/RetryPolicy/Exception.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Exception
|
31 |
+
* @version $Id: Exception.php 45259 2010-04-16 12:13:55Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @subpackage RetryPolicy
|
45 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
46 |
+
* @license http://phpazure.codeplex.com/license
|
47 |
+
*/
|
48 |
+
class Microsoft_WindowsAzure_RetryPolicy_Exception extends Microsoft_WindowsAzure_Exception
|
49 |
+
{}
|
app/libs/Microsoft/WindowsAzure/RetryPolicy/NoRetry.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage RetryPolicy
|
31 |
+
* @version $Id: NoRetry.php 45259 2010-04-16 12:13:55Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @category Microsoft
|
43 |
+
* @package Microsoft_WindowsAzure
|
44 |
+
* @subpackage RetryPolicy
|
45 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
46 |
+
* @license http://phpazure.codeplex.com/license
|
47 |
+
*/
|
48 |
+
class Microsoft_WindowsAzure_RetryPolicy_NoRetry extends Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
49 |
+
{
|
50 |
+
/**
|
51 |
+
* Execute function under retry policy
|
52 |
+
*
|
53 |
+
* @param string|array $function Function to execute
|
54 |
+
* @param array $parameters Parameters for function call
|
55 |
+
* @return mixed
|
56 |
+
*/
|
57 |
+
public function execute($function, $parameters = array())
|
58 |
+
{
|
59 |
+
$returnValue = null;
|
60 |
+
|
61 |
+
try
|
62 |
+
{
|
63 |
+
$returnValue = call_user_func_array($function, $parameters);
|
64 |
+
return $returnValue;
|
65 |
+
}
|
66 |
+
catch (Exception $ex)
|
67 |
+
{
|
68 |
+
throw $ex;
|
69 |
+
}
|
70 |
+
}
|
71 |
+
}
|
app/libs/Microsoft/WindowsAzure/RetryPolicy/RetryN.php
ADDED
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage RetryPolicy
|
31 |
+
* @version $Id: RetryN.php 45259 2010-04-16 12:13:55Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_Exception
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/Exception.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage RetryPolicy
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*/
|
53 |
+
class Microsoft_WindowsAzure_RetryPolicy_RetryN extends Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
54 |
+
{
|
55 |
+
/**
|
56 |
+
* Number of retries
|
57 |
+
*
|
58 |
+
* @var int
|
59 |
+
*/
|
60 |
+
protected $_retryCount = 1;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Interval between retries (in milliseconds)
|
64 |
+
*
|
65 |
+
* @var int
|
66 |
+
*/
|
67 |
+
protected $_retryInterval = 0;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Constructor
|
71 |
+
*
|
72 |
+
* @param int $count Number of retries
|
73 |
+
* @param int $intervalBetweenRetries Interval between retries (in milliseconds)
|
74 |
+
*/
|
75 |
+
public function __construct($count = 1, $intervalBetweenRetries = 0)
|
76 |
+
{
|
77 |
+
$this->_retryCount = $count;
|
78 |
+
$this->_retryInterval = $intervalBetweenRetries;
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Execute function under retry policy
|
83 |
+
*
|
84 |
+
* @param string|array $function Function to execute
|
85 |
+
* @param array $parameters Parameters for function call
|
86 |
+
* @return mixed
|
87 |
+
*/
|
88 |
+
public function execute($function, $parameters = array())
|
89 |
+
{
|
90 |
+
$returnValue = null;
|
91 |
+
|
92 |
+
for ($retriesLeft = $this->_retryCount; $retriesLeft >= 0; --$retriesLeft) {
|
93 |
+
try {
|
94 |
+
$returnValue = call_user_func_array($function, $parameters);
|
95 |
+
return $returnValue;
|
96 |
+
} catch (Exception $ex) {
|
97 |
+
if ($retriesLeft == 1) {
|
98 |
+
throw new Microsoft_WindowsAzure_RetryPolicy_Exception("Exceeded retry count of " . $this->_retryCount . ". " . $ex->getMessage());
|
99 |
+
}
|
100 |
+
|
101 |
+
usleep($this->_retryInterval * 1000);
|
102 |
+
}
|
103 |
+
}
|
104 |
+
}
|
105 |
+
}
|
app/libs/Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage RetryPolicy
|
31 |
+
* @version $Id: RetryPolicy.php 28585 2009-09-07 12:12:56Z unknown $
|
32 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
33 |
+
* @license http://phpazure.codeplex.com/license
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_NoRetry
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/NoRetry.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryN
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryN.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @category Microsoft
|
53 |
+
* @package Microsoft_WindowsAzure
|
54 |
+
* @subpackage RetryPolicy
|
55 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
56 |
+
* @license http://phpazure.codeplex.com/license
|
57 |
+
*/
|
58 |
+
abstract class Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
59 |
+
{
|
60 |
+
/**
|
61 |
+
* Execute function under retry policy
|
62 |
+
*
|
63 |
+
* @param string|array $function Function to execute
|
64 |
+
* @param array $parameters Parameters for function call
|
65 |
+
* @return mixed
|
66 |
+
*/
|
67 |
+
public abstract function execute($function, $parameters = array());
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Create a Microsoft_WindowsAzure_RetryPolicy_NoRetry instance
|
71 |
+
*
|
72 |
+
* @return Microsoft_WindowsAzure_RetryPolicy_NoRetry
|
73 |
+
*/
|
74 |
+
public static function noRetry()
|
75 |
+
{
|
76 |
+
return new Microsoft_WindowsAzure_RetryPolicy_NoRetry();
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Create a Microsoft_WindowsAzure_RetryPolicy_RetryN instance
|
81 |
+
*
|
82 |
+
* @param int $count Number of retries
|
83 |
+
* @param int $intervalBetweenRetries Interval between retries (in milliseconds)
|
84 |
+
* @return Microsoft_WindowsAzure_RetryPolicy_RetryN
|
85 |
+
*/
|
86 |
+
public static function retryN($count = 1, $intervalBetweenRetries = 0)
|
87 |
+
{
|
88 |
+
return new Microsoft_WindowsAzure_RetryPolicy_RetryN($count, $intervalBetweenRetries);
|
89 |
+
}
|
90 |
+
}
|
app/libs/Microsoft/WindowsAzure/SessionHandler.php
ADDED
@@ -0,0 +1,230 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Session
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 21617 2009-06-12 10:46:31Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/** Microsoft_WindowsAzure_Storage_Table */
|
37 |
+
require_once 'Microsoft/WindowsAzure/Storage/Table.php';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* @see Microsoft_WindowsAzure_Exception
|
41 |
+
*/
|
42 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
43 |
+
|
44 |
+
/**
|
45 |
+
* @category Microsoft
|
46 |
+
* @package Microsoft_WindowsAzure
|
47 |
+
* @subpackage Session
|
48 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
49 |
+
* @license http://phpazure.codeplex.com/license
|
50 |
+
*/
|
51 |
+
class Microsoft_WindowsAzure_SessionHandler
|
52 |
+
{
|
53 |
+
/**
|
54 |
+
* Table storage
|
55 |
+
*
|
56 |
+
* @var Microsoft_WindowsAzure_Storage_Table
|
57 |
+
*/
|
58 |
+
protected $_tableStorage;
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Session table name
|
62 |
+
*
|
63 |
+
* @var string
|
64 |
+
*/
|
65 |
+
protected $_sessionTable;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Session table partition
|
69 |
+
*
|
70 |
+
* @var string
|
71 |
+
*/
|
72 |
+
protected $_sessionTablePartition;
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Creates a new Microsoft_WindowsAzure_SessionHandler instance
|
76 |
+
*
|
77 |
+
* @param Microsoft_WindowsAzure_Storage_Table $tableStorage Table storage
|
78 |
+
* @param string $sessionTable Session table name
|
79 |
+
* @param string $sessionTablePartition Session table partition
|
80 |
+
*/
|
81 |
+
public function __construct(Microsoft_WindowsAzure_Storage_Table $tableStorage, $sessionTable = 'phpsessions', $sessionTablePartition = 'sessions')
|
82 |
+
{
|
83 |
+
// Set properties
|
84 |
+
$this->_tableStorage = $tableStorage;
|
85 |
+
$this->_sessionTable = $sessionTable;
|
86 |
+
$this->_sessionTablePartition = $sessionTablePartition;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Registers the current session handler as PHP's session handler
|
91 |
+
*
|
92 |
+
* @return boolean
|
93 |
+
*/
|
94 |
+
public function register()
|
95 |
+
{
|
96 |
+
return session_set_save_handler(array($this, 'open'),
|
97 |
+
array($this, 'close'),
|
98 |
+
array($this, 'read'),
|
99 |
+
array($this, 'write'),
|
100 |
+
array($this, 'destroy'),
|
101 |
+
array($this, 'gc')
|
102 |
+
);
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Open the session store
|
107 |
+
*
|
108 |
+
* @return bool
|
109 |
+
*/
|
110 |
+
public function open()
|
111 |
+
{
|
112 |
+
// Make sure table exists
|
113 |
+
$tableExists = $this->_tableStorage->tableExists($this->_sessionTable);
|
114 |
+
if (!$tableExists) {
|
115 |
+
$this->_tableStorage->createTable($this->_sessionTable);
|
116 |
+
}
|
117 |
+
|
118 |
+
// Ok!
|
119 |
+
return true;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Close the session store
|
124 |
+
*
|
125 |
+
* @return bool
|
126 |
+
*/
|
127 |
+
public function close()
|
128 |
+
{
|
129 |
+
return true;
|
130 |
+
}
|
131 |
+
|
132 |
+
/**
|
133 |
+
* Read a specific session
|
134 |
+
*
|
135 |
+
* @param int $id Session Id
|
136 |
+
* @return string
|
137 |
+
*/
|
138 |
+
public function read($id)
|
139 |
+
{
|
140 |
+
try
|
141 |
+
{
|
142 |
+
$sessionRecord = $this->_tableStorage->retrieveEntityById(
|
143 |
+
$this->_sessionTable,
|
144 |
+
$this->_sessionTablePartition,
|
145 |
+
$id
|
146 |
+
);
|
147 |
+
return base64_decode($sessionRecord->serializedData);
|
148 |
+
}
|
149 |
+
catch (Microsoft_WindowsAzure_Exception $ex)
|
150 |
+
{
|
151 |
+
return '';
|
152 |
+
}
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Write a specific session
|
157 |
+
*
|
158 |
+
* @param int $id Session Id
|
159 |
+
* @param string $serializedData Serialized PHP object
|
160 |
+
*/
|
161 |
+
public function write($id, $serializedData)
|
162 |
+
{
|
163 |
+
$sessionRecord = new Microsoft_WindowsAzure_Storage_DynamicTableEntity($this->_sessionTablePartition, $id);
|
164 |
+
$sessionRecord->sessionExpires = time();
|
165 |
+
$sessionRecord->serializedData = base64_encode($serializedData);
|
166 |
+
|
167 |
+
$sessionRecord->setAzurePropertyType('sessionExpires', 'Edm.Int32');
|
168 |
+
|
169 |
+
try
|
170 |
+
{
|
171 |
+
$this->_tableStorage->updateEntity($this->_sessionTable, $sessionRecord);
|
172 |
+
}
|
173 |
+
catch (Microsoft_WindowsAzure_Exception $unknownRecord)
|
174 |
+
{
|
175 |
+
$this->_tableStorage->insertEntity($this->_sessionTable, $sessionRecord);
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Destroy a specific session
|
181 |
+
*
|
182 |
+
* @param int $id Session Id
|
183 |
+
* @return boolean
|
184 |
+
*/
|
185 |
+
public function destroy($id)
|
186 |
+
{
|
187 |
+
try
|
188 |
+
{
|
189 |
+
$sessionRecord = $this->_tableStorage->retrieveEntityById(
|
190 |
+
$this->_sessionTable,
|
191 |
+
$this->_sessionTablePartition,
|
192 |
+
$id
|
193 |
+
);
|
194 |
+
$this->_tableStorage->deleteEntity($this->_sessionTable, $sessionRecord);
|
195 |
+
|
196 |
+
return true;
|
197 |
+
}
|
198 |
+
catch (Microsoft_WindowsAzure_Exception $ex)
|
199 |
+
{
|
200 |
+
return false;
|
201 |
+
}
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* Garbage collector
|
206 |
+
*
|
207 |
+
* @param int $lifeTime Session maximal lifetime
|
208 |
+
* @see session.gc_divisor 100
|
209 |
+
* @see session.gc_maxlifetime 1440
|
210 |
+
* @see session.gc_probability 1
|
211 |
+
* @usage Execution rate 1/100 (session.gc_probability/session.gc_divisor)
|
212 |
+
* @return boolean
|
213 |
+
*/
|
214 |
+
public function gc($lifeTime)
|
215 |
+
{
|
216 |
+
try
|
217 |
+
{
|
218 |
+
$result = $this->_tableStorage->retrieveEntities($this->_sessionTable, 'PartitionKey eq \'' . $this->_sessionTablePartition . '\' and sessionExpires lt ' . (time() - $lifeTime));
|
219 |
+
foreach ($result as $sessionRecord)
|
220 |
+
{
|
221 |
+
$this->_tableStorage->deleteEntity($this->_sessionTable, $sessionRecord);
|
222 |
+
}
|
223 |
+
return true;
|
224 |
+
}
|
225 |
+
catch (Microsoft_WindowsAzure_exception $ex)
|
226 |
+
{
|
227 |
+
return false;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage.php
ADDED
@@ -0,0 +1,586 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 51671 2010-09-30 08:33:45Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedKey
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKey.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_WindowsAzure_Exception
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_Http_Client
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/Http/Client.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @see Microsoft_Http_Response
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/Http/Response.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @category Microsoft
|
68 |
+
* @package Microsoft_WindowsAzure
|
69 |
+
* @subpackage Storage
|
70 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
71 |
+
* @license http://phpazure.codeplex.com/license
|
72 |
+
*/
|
73 |
+
class Microsoft_WindowsAzure_Storage
|
74 |
+
{
|
75 |
+
/**
|
76 |
+
* Development storage URLS
|
77 |
+
*/
|
78 |
+
const URL_DEV_BLOB = "127.0.0.1:10000";
|
79 |
+
const URL_DEV_QUEUE = "127.0.0.1:10001";
|
80 |
+
const URL_DEV_TABLE = "127.0.0.1:10002";
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Live storage URLS
|
84 |
+
*/
|
85 |
+
const URL_CLOUD_BLOB = "blob.core.windows.net";
|
86 |
+
const URL_CLOUD_QUEUE = "queue.core.windows.net";
|
87 |
+
const URL_CLOUD_TABLE = "table.core.windows.net";
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Resource types
|
91 |
+
*/
|
92 |
+
const RESOURCE_UNKNOWN = "unknown";
|
93 |
+
const RESOURCE_CONTAINER = "c";
|
94 |
+
const RESOURCE_BLOB = "b";
|
95 |
+
const RESOURCE_TABLE = "t";
|
96 |
+
const RESOURCE_ENTITY = "e";
|
97 |
+
const RESOURCE_QUEUE = "q";
|
98 |
+
|
99 |
+
/**
|
100 |
+
* HTTP header prefixes
|
101 |
+
*/
|
102 |
+
const PREFIX_PROPERTIES = "x-ms-prop-";
|
103 |
+
const PREFIX_METADATA = "x-ms-meta-";
|
104 |
+
const PREFIX_STORAGE_HEADER = "x-ms-";
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Current API version
|
108 |
+
*
|
109 |
+
* @var string
|
110 |
+
*/
|
111 |
+
protected $_apiVersion = '2009-09-19';
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Storage host name
|
115 |
+
*
|
116 |
+
* @var string
|
117 |
+
*/
|
118 |
+
protected $_host = '';
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Account name for Windows Azure
|
122 |
+
*
|
123 |
+
* @var string
|
124 |
+
*/
|
125 |
+
protected $_accountName = '';
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Account key for Windows Azure
|
129 |
+
*
|
130 |
+
* @var string
|
131 |
+
*/
|
132 |
+
protected $_accountKey = '';
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Use path-style URI's
|
136 |
+
*
|
137 |
+
* @var boolean
|
138 |
+
*/
|
139 |
+
protected $_usePathStyleUri = false;
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
|
143 |
+
*
|
144 |
+
* @var Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
145 |
+
*/
|
146 |
+
protected $_credentials = null;
|
147 |
+
|
148 |
+
/**
|
149 |
+
* Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract instance
|
150 |
+
*
|
151 |
+
* @var Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
152 |
+
*/
|
153 |
+
protected $_retryPolicy = null;
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Microsoft_Http_Client channel used for communication with REST services
|
157 |
+
*
|
158 |
+
* @var Microsoft_Http_Client
|
159 |
+
*/
|
160 |
+
protected $_httpClientChannel = null;
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Use proxy?
|
164 |
+
*
|
165 |
+
* @var boolean
|
166 |
+
*/
|
167 |
+
protected $_useProxy = false;
|
168 |
+
|
169 |
+
/**
|
170 |
+
* Proxy url
|
171 |
+
*
|
172 |
+
* @var string
|
173 |
+
*/
|
174 |
+
protected $_proxyUrl = '';
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Proxy port
|
178 |
+
*
|
179 |
+
* @var int
|
180 |
+
*/
|
181 |
+
protected $_proxyPort = 80;
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Proxy credentials
|
185 |
+
*
|
186 |
+
* @var string
|
187 |
+
*/
|
188 |
+
protected $_proxyCredentials = '';
|
189 |
+
|
190 |
+
/**
|
191 |
+
* Creates a new Microsoft_WindowsAzure_Storage instance
|
192 |
+
*
|
193 |
+
* @param string $host Storage host name
|
194 |
+
* @param string $accountName Account name for Windows Azure
|
195 |
+
* @param string $accountKey Account key for Windows Azure
|
196 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
197 |
+
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
|
198 |
+
*/
|
199 |
+
public function __construct(
|
200 |
+
$host = self::URL_DEV_BLOB,
|
201 |
+
$accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT,
|
202 |
+
$accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY,
|
203 |
+
$usePathStyleUri = false,
|
204 |
+
Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null
|
205 |
+
) {
|
206 |
+
$this->_host = $host;
|
207 |
+
$this->_accountName = $accountName;
|
208 |
+
$this->_accountKey = $accountKey;
|
209 |
+
$this->_usePathStyleUri = $usePathStyleUri;
|
210 |
+
|
211 |
+
// Using local storage?
|
212 |
+
if (!$this->_usePathStyleUri
|
213 |
+
&& ($this->_host == self::URL_DEV_BLOB
|
214 |
+
|| $this->_host == self::URL_DEV_QUEUE
|
215 |
+
|| $this->_host == self::URL_DEV_TABLE)
|
216 |
+
) {
|
217 |
+
// Local storage
|
218 |
+
$this->_usePathStyleUri = true;
|
219 |
+
}
|
220 |
+
|
221 |
+
if (is_null($this->_credentials)) {
|
222 |
+
$this->_credentials = new Microsoft_WindowsAzure_Credentials_SharedKey(
|
223 |
+
$this->_accountName, $this->_accountKey, $this->_usePathStyleUri);
|
224 |
+
}
|
225 |
+
|
226 |
+
$this->_retryPolicy = $retryPolicy;
|
227 |
+
if (is_null($this->_retryPolicy)) {
|
228 |
+
$this->_retryPolicy = Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
|
229 |
+
}
|
230 |
+
|
231 |
+
// Setup default Microsoft_Http_Client channel
|
232 |
+
$options = array(
|
233 |
+
'adapter' => 'Microsoft_Http_Client_Adapter_Proxy'
|
234 |
+
);
|
235 |
+
if (function_exists('curl_init')) {
|
236 |
+
// Set cURL options if cURL is used afterwards
|
237 |
+
$options['curloptions'] = array(
|
238 |
+
CURLOPT_FOLLOWLOCATION => true,
|
239 |
+
CURLOPT_TIMEOUT => 120,
|
240 |
+
);
|
241 |
+
}
|
242 |
+
$this->_httpClientChannel = new Microsoft_Http_Client(null, $options);
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* Set the HTTP client channel to use
|
247 |
+
*
|
248 |
+
* @param Microsoft_Http_Client_Adapter_Interface|string $adapterInstance Adapter instance or adapter class name.
|
249 |
+
*/
|
250 |
+
public function setHttpClientChannel($adapterInstance = 'Microsoft_Http_Client_Adapter_Proxy')
|
251 |
+
{
|
252 |
+
$this->_httpClientChannel->setAdapter($adapterInstance);
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Retrieve HTTP client channel
|
257 |
+
*
|
258 |
+
* @return Microsoft_Http_Client_Adapter_Interface
|
259 |
+
*/
|
260 |
+
public function getHttpClientChannel()
|
261 |
+
{
|
262 |
+
return $this->_httpClientChannel;
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Set retry policy to use when making requests
|
267 |
+
*
|
268 |
+
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
|
269 |
+
*/
|
270 |
+
public function setRetryPolicy(Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
|
271 |
+
{
|
272 |
+
$this->_retryPolicy = $retryPolicy;
|
273 |
+
if (is_null($this->_retryPolicy)) {
|
274 |
+
$this->_retryPolicy = Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract::noRetry();
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Set proxy
|
280 |
+
*
|
281 |
+
* @param boolean $useProxy Use proxy?
|
282 |
+
* @param string $proxyUrl Proxy URL
|
283 |
+
* @param int $proxyPort Proxy port
|
284 |
+
* @param string $proxyCredentials Proxy credentials
|
285 |
+
*/
|
286 |
+
public function setProxy($useProxy = false, $proxyUrl = '', $proxyPort = 80, $proxyCredentials = '')
|
287 |
+
{
|
288 |
+
$this->_useProxy = $useProxy;
|
289 |
+
$this->_proxyUrl = $proxyUrl;
|
290 |
+
$this->_proxyPort = $proxyPort;
|
291 |
+
$this->_proxyCredentials = $proxyCredentials;
|
292 |
+
|
293 |
+
if ($this->_useProxy) {
|
294 |
+
$credentials = explode(':', $this->_proxyCredentials);
|
295 |
+
|
296 |
+
$this->_httpClientChannel->setConfig(array(
|
297 |
+
'proxy_host' => $this->_proxyUrl,
|
298 |
+
'proxy_port' => $this->_proxyPort,
|
299 |
+
'proxy_user' => $credentials[0],
|
300 |
+
'proxy_pass' => $credentials[1],
|
301 |
+
));
|
302 |
+
} else {
|
303 |
+
$this->_httpClientChannel->setConfig(array(
|
304 |
+
'proxy_host' => '',
|
305 |
+
'proxy_port' => 8080,
|
306 |
+
'proxy_user' => '',
|
307 |
+
'proxy_pass' => '',
|
308 |
+
));
|
309 |
+
}
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Returns the Windows Azure account name
|
314 |
+
*
|
315 |
+
* @return string
|
316 |
+
*/
|
317 |
+
public function getAccountName()
|
318 |
+
{
|
319 |
+
return $this->_accountName;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* Get base URL for creating requests
|
324 |
+
*
|
325 |
+
* @return string
|
326 |
+
*/
|
327 |
+
public function getBaseUrl()
|
328 |
+
{
|
329 |
+
if ($this->_usePathStyleUri) {
|
330 |
+
return 'http://' . $this->_host . '/' . $this->_accountName;
|
331 |
+
} else {
|
332 |
+
return 'http://' . $this->_accountName . '.' . $this->_host;
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
/**
|
337 |
+
* Set Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
|
338 |
+
*
|
339 |
+
* @param Microsoft_WindowsAzure_Credentials_CredentialsAbstract $credentials Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance to use for request signing.
|
340 |
+
*/
|
341 |
+
public function setCredentials(Microsoft_WindowsAzure_Credentials_CredentialsAbstract $credentials)
|
342 |
+
{
|
343 |
+
$this->_credentials = $credentials;
|
344 |
+
$this->_credentials->setAccountName($this->_accountName);
|
345 |
+
$this->_credentials->setAccountkey($this->_accountKey);
|
346 |
+
$this->_credentials->setUsePathStyleUri($this->_usePathStyleUri);
|
347 |
+
}
|
348 |
+
|
349 |
+
/**
|
350 |
+
* Get Microsoft_WindowsAzure_Credentials_CredentialsAbstract instance
|
351 |
+
*
|
352 |
+
* @return Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
353 |
+
*/
|
354 |
+
public function getCredentials()
|
355 |
+
{
|
356 |
+
return $this->_credentials;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Perform request using Microsoft_Http_Client channel
|
361 |
+
*
|
362 |
+
* @param string $path Path
|
363 |
+
* @param string $queryString Query string
|
364 |
+
* @param string $httpVerb HTTP verb the request will use
|
365 |
+
* @param array $headers x-ms headers to add
|
366 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
367 |
+
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
|
368 |
+
* @param string $resourceType Resource type
|
369 |
+
* @param string $requiredPermission Required permission
|
370 |
+
* @return Microsoft_Http_Response
|
371 |
+
*/
|
372 |
+
protected function _performRequest(
|
373 |
+
$path = '/',
|
374 |
+
$queryString = '',
|
375 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
376 |
+
$headers = array(),
|
377 |
+
$forTableStorage = false,
|
378 |
+
$rawData = null,
|
379 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
380 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
381 |
+
) {
|
382 |
+
// Clean path
|
383 |
+
if (strpos($path, '/') !== 0) {
|
384 |
+
$path = '/' . $path;
|
385 |
+
}
|
386 |
+
|
387 |
+
// Clean headers
|
388 |
+
if (is_null($headers)) {
|
389 |
+
$headers = array();
|
390 |
+
}
|
391 |
+
|
392 |
+
// Ensure cUrl will also work correctly:
|
393 |
+
// - disable Content-Type if required
|
394 |
+
// - disable Expect: 100 Continue
|
395 |
+
if (!isset($headers["Content-Type"])) {
|
396 |
+
$headers["Content-Type"] = '';
|
397 |
+
}
|
398 |
+
$headers["Expect"]= '';
|
399 |
+
|
400 |
+
// Add version header
|
401 |
+
$headers['x-ms-version'] = $this->_apiVersion;
|
402 |
+
|
403 |
+
// URL encoding
|
404 |
+
$path = self::urlencode($path);
|
405 |
+
$queryString = self::urlencode($queryString);
|
406 |
+
|
407 |
+
// Generate URL and sign request
|
408 |
+
$requestUrl = $this->_credentials
|
409 |
+
->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission);
|
410 |
+
$requestHeaders = $this->_credentials
|
411 |
+
->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission, $rawData);
|
412 |
+
|
413 |
+
// Prepare request
|
414 |
+
$this->_httpClientChannel->resetParameters(true);
|
415 |
+
$this->_httpClientChannel->setUri($requestUrl);
|
416 |
+
$this->_httpClientChannel->setHeaders($requestHeaders);
|
417 |
+
$this->_httpClientChannel->setRawData($rawData);
|
418 |
+
|
419 |
+
// Execute request
|
420 |
+
$response = $this->_retryPolicy->execute(
|
421 |
+
array($this->_httpClientChannel, 'request'),
|
422 |
+
array($httpVerb)
|
423 |
+
);
|
424 |
+
|
425 |
+
return $response;
|
426 |
+
}
|
427 |
+
|
428 |
+
/**
|
429 |
+
* Parse result from Microsoft_Http_Response
|
430 |
+
*
|
431 |
+
* @param Microsoft_Http_Response $response Response from HTTP call
|
432 |
+
* @return object
|
433 |
+
* @throws Microsoft_WindowsAzure_Exception
|
434 |
+
*/
|
435 |
+
protected function _parseResponse(Microsoft_Http_Response $response = null)
|
436 |
+
{
|
437 |
+
if (is_null($response)) {
|
438 |
+
throw new Microsoft_WindowsAzure_Exception('Response should not be null.');
|
439 |
+
}
|
440 |
+
|
441 |
+
$xml = @simplexml_load_string($response->getBody());
|
442 |
+
|
443 |
+
if ($xml !== false) {
|
444 |
+
// Fetch all namespaces
|
445 |
+
$namespaces = array_merge($xml->getNamespaces(true), $xml->getDocNamespaces(true));
|
446 |
+
|
447 |
+
// Register all namespace prefixes
|
448 |
+
foreach ($namespaces as $prefix => $ns) {
|
449 |
+
if ($prefix != '') {
|
450 |
+
$xml->registerXPathNamespace($prefix, $ns);
|
451 |
+
}
|
452 |
+
}
|
453 |
+
}
|
454 |
+
|
455 |
+
return $xml;
|
456 |
+
}
|
457 |
+
|
458 |
+
/**
|
459 |
+
* Generate metadata headers
|
460 |
+
*
|
461 |
+
* @param array $metadata
|
462 |
+
* @return HTTP headers containing metadata
|
463 |
+
*/
|
464 |
+
protected function _generateMetadataHeaders($metadata = array())
|
465 |
+
{
|
466 |
+
// Validate
|
467 |
+
if (!is_array($metadata)) {
|
468 |
+
return array();
|
469 |
+
}
|
470 |
+
|
471 |
+
// Return headers
|
472 |
+
$headers = array();
|
473 |
+
foreach ($metadata as $key => $value) {
|
474 |
+
if (strpos($value, "\r") !== false || strpos($value, "\n") !== false) {
|
475 |
+
throw new Microsoft_WindowsAzure_Exception('Metadata cannot contain newline characters.');
|
476 |
+
}
|
477 |
+
|
478 |
+
if (!self::isValidMetadataName($key)) {
|
479 |
+
throw new Microsoft_WindowsAzure_Exception('Metadata name does not adhere to metadata naming conventions. See http://msdn.microsoft.com/en-us/library/aa664670(VS.71).aspx for more information.');
|
480 |
+
}
|
481 |
+
|
482 |
+
$headers["x-ms-meta-" . strtolower($key)] = $value;
|
483 |
+
}
|
484 |
+
return $headers;
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Parse metadata headers
|
489 |
+
*
|
490 |
+
* @param array $headers HTTP headers containing metadata
|
491 |
+
* @return array
|
492 |
+
*/
|
493 |
+
protected function _parseMetadataHeaders($headers = array())
|
494 |
+
{
|
495 |
+
// Validate
|
496 |
+
if (!is_array($headers)) {
|
497 |
+
return array();
|
498 |
+
}
|
499 |
+
|
500 |
+
// Return metadata
|
501 |
+
$metadata = array();
|
502 |
+
foreach ($headers as $key => $value) {
|
503 |
+
if (substr(strtolower($key), 0, 10) == "x-ms-meta-") {
|
504 |
+
$metadata[str_replace("x-ms-meta-", '', strtolower($key))] = $value;
|
505 |
+
}
|
506 |
+
}
|
507 |
+
return $metadata;
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Parse metadata XML
|
512 |
+
*
|
513 |
+
* @param SimpleXMLElement $parentElement Element containing the Metadata element.
|
514 |
+
* @return array
|
515 |
+
*/
|
516 |
+
protected function _parseMetadataElement($element = null)
|
517 |
+
{
|
518 |
+
// Metadata present?
|
519 |
+
if (!is_null($element) && isset($element->Metadata) && !is_null($element->Metadata)) {
|
520 |
+
return get_object_vars($element->Metadata);
|
521 |
+
}
|
522 |
+
|
523 |
+
return array();
|
524 |
+
}
|
525 |
+
|
526 |
+
/**
|
527 |
+
* Generate ISO 8601 compliant date string in UTC time zone
|
528 |
+
*
|
529 |
+
* @param int $timestamp
|
530 |
+
* @return string
|
531 |
+
*/
|
532 |
+
public function isoDate($timestamp = null)
|
533 |
+
{
|
534 |
+
$tz = @date_default_timezone_get();
|
535 |
+
@date_default_timezone_set('UTC');
|
536 |
+
|
537 |
+
if (is_null($timestamp)) {
|
538 |
+
$timestamp = time();
|
539 |
+
}
|
540 |
+
|
541 |
+
$returnValue = str_replace('+00:00', '.0000000Z', @date('c', $timestamp));
|
542 |
+
@date_default_timezone_set($tz);
|
543 |
+
return $returnValue;
|
544 |
+
}
|
545 |
+
|
546 |
+
/**
|
547 |
+
* URL encode function
|
548 |
+
*
|
549 |
+
* @param string $value Value to encode
|
550 |
+
* @return string Encoded value
|
551 |
+
*/
|
552 |
+
public static function urlencode($value)
|
553 |
+
{
|
554 |
+
return str_replace(' ', '%20', $value);
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Is valid metadata name?
|
559 |
+
*
|
560 |
+
* @param string $metadataName Metadata name
|
561 |
+
* @return boolean
|
562 |
+
*/
|
563 |
+
public static function isValidMetadataName($metadataName = '')
|
564 |
+
{
|
565 |
+
if (preg_match("/^[a-zA-Z0-9_@][a-zA-Z0-9_]*$/", $metadataName) === 0) {
|
566 |
+
return false;
|
567 |
+
}
|
568 |
+
|
569 |
+
if ($metadataName == '') {
|
570 |
+
return false;
|
571 |
+
}
|
572 |
+
|
573 |
+
return true;
|
574 |
+
}
|
575 |
+
|
576 |
+
/**
|
577 |
+
* Builds a query string from an array of elements
|
578 |
+
*
|
579 |
+
* @param array Array of elements
|
580 |
+
* @return string Assembled query string
|
581 |
+
*/
|
582 |
+
public static function createQueryStringFromArray($queryString)
|
583 |
+
{
|
584 |
+
return count($queryString) > 0 ? '?' . implode('&', $queryString) : '';
|
585 |
+
}
|
586 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/Batch.php
ADDED
@@ -0,0 +1,261 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 21617 2009-06-12 10:46:31Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_BatchStorageAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/BatchStorageAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*/
|
53 |
+
class Microsoft_WindowsAzure_Storage_Batch
|
54 |
+
{
|
55 |
+
/**
|
56 |
+
* Storage client the batch is defined on
|
57 |
+
*
|
58 |
+
* @var Microsoft_WindowsAzure_Storage_BatchStorageAbstract
|
59 |
+
*/
|
60 |
+
protected $_storageClient = null;
|
61 |
+
|
62 |
+
/**
|
63 |
+
* For table storage?
|
64 |
+
*
|
65 |
+
* @var boolean
|
66 |
+
*/
|
67 |
+
protected $_forTableStorage = false;
|
68 |
+
|
69 |
+
/**
|
70 |
+
* Base URL
|
71 |
+
*
|
72 |
+
* @var string
|
73 |
+
*/
|
74 |
+
protected $_baseUrl;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Pending operations
|
78 |
+
*
|
79 |
+
* @var unknown_type
|
80 |
+
*/
|
81 |
+
protected $_operations = array();
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Does the batch contain a single select?
|
85 |
+
*
|
86 |
+
* @var boolean
|
87 |
+
*/
|
88 |
+
protected $_isSingleSelect = false;
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Creates a new Microsoft_WindowsAzure_Storage_Batch
|
92 |
+
*
|
93 |
+
* @param Microsoft_WindowsAzure_Storage_BatchStorageAbstract $storageClient Storage client the batch is defined on
|
94 |
+
*/
|
95 |
+
public function __construct(Microsoft_WindowsAzure_Storage_BatchStorageAbstract $storageClient = null, $baseUrl = '')
|
96 |
+
{
|
97 |
+
$this->_storageClient = $storageClient;
|
98 |
+
$this->_baseUrl = $baseUrl;
|
99 |
+
$this->_beginBatch();
|
100 |
+
}
|
101 |
+
|
102 |
+
/**
|
103 |
+
* Get base URL for creating requests
|
104 |
+
*
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function getBaseUrl()
|
108 |
+
{
|
109 |
+
return $this->_baseUrl;
|
110 |
+
}
|
111 |
+
|
112 |
+
/**
|
113 |
+
* Starts a new batch operation set
|
114 |
+
*
|
115 |
+
* @throws Microsoft_WindowsAzure_Exception
|
116 |
+
*/
|
117 |
+
protected function _beginBatch()
|
118 |
+
{
|
119 |
+
$this->_storageClient->setCurrentBatch($this);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Cleanup current batch
|
124 |
+
*/
|
125 |
+
protected function _clean()
|
126 |
+
{
|
127 |
+
unset($this->_operations);
|
128 |
+
$this->_storageClient->setCurrentBatch(null);
|
129 |
+
$this->_storageClient = null;
|
130 |
+
unset($this);
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Enlist operation in current batch
|
135 |
+
*
|
136 |
+
* @param string $path Path
|
137 |
+
* @param string $queryString Query string
|
138 |
+
* @param string $httpVerb HTTP verb the request will use
|
139 |
+
* @param array $headers x-ms headers to add
|
140 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
141 |
+
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
|
142 |
+
* @throws Microsoft_WindowsAzure_Exception
|
143 |
+
*/
|
144 |
+
public function enlistOperation($path = '/', $queryString = '', $httpVerb = Microsoft_Http_Client::GET, $headers = array(), $forTableStorage = false, $rawData = null)
|
145 |
+
{
|
146 |
+
// Set _forTableStorage
|
147 |
+
if ($forTableStorage) {
|
148 |
+
$this->_forTableStorage = true;
|
149 |
+
}
|
150 |
+
|
151 |
+
// Set _isSingleSelect
|
152 |
+
if ($httpVerb == Microsoft_Http_Client::GET) {
|
153 |
+
if (count($this->_operations) > 0) {
|
154 |
+
throw new Microsoft_WindowsAzure_Exception("Select operations can only be performed in an empty batch transaction.");
|
155 |
+
}
|
156 |
+
$this->_isSingleSelect = true;
|
157 |
+
}
|
158 |
+
|
159 |
+
// Clean path
|
160 |
+
if (strpos($path, '/') !== 0) {
|
161 |
+
$path = '/' . $path;
|
162 |
+
}
|
163 |
+
|
164 |
+
// Clean headers
|
165 |
+
if (is_null($headers)) {
|
166 |
+
$headers = array();
|
167 |
+
}
|
168 |
+
|
169 |
+
// URL encoding
|
170 |
+
$path = Microsoft_WindowsAzure_Storage::urlencode($path);
|
171 |
+
$queryString = Microsoft_WindowsAzure_Storage::urlencode($queryString);
|
172 |
+
|
173 |
+
// Generate URL
|
174 |
+
$requestUrl = $this->getBaseUrl() . $path . $queryString;
|
175 |
+
|
176 |
+
// Generate $rawData
|
177 |
+
if (is_null($rawData)) {
|
178 |
+
$rawData = '';
|
179 |
+
}
|
180 |
+
|
181 |
+
// Add headers
|
182 |
+
if ($httpVerb != Microsoft_Http_Client::GET) {
|
183 |
+
$headers['Content-ID'] = count($this->_operations) + 1;
|
184 |
+
if ($httpVerb != Microsoft_Http_Client::DELETE) {
|
185 |
+
$headers['Content-Type'] = 'application/atom+xml;type=entry';
|
186 |
+
}
|
187 |
+
$headers['Content-Length'] = strlen($rawData);
|
188 |
+
}
|
189 |
+
|
190 |
+
// Generate $operation
|
191 |
+
$operation = '';
|
192 |
+
$operation .= $httpVerb . ' ' . $requestUrl . ' HTTP/1.1' . "\n";
|
193 |
+
foreach ($headers as $key => $value)
|
194 |
+
{
|
195 |
+
$operation .= $key . ': ' . $value . "\n";
|
196 |
+
}
|
197 |
+
$operation .= "\n";
|
198 |
+
|
199 |
+
// Add data
|
200 |
+
$operation .= $rawData;
|
201 |
+
|
202 |
+
// Store operation
|
203 |
+
$this->_operations[] = $operation;
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Commit current batch
|
208 |
+
*
|
209 |
+
* @return Microsoft_Http_Response
|
210 |
+
* @throws Microsoft_WindowsAzure_Exception
|
211 |
+
*/
|
212 |
+
public function commit()
|
213 |
+
{
|
214 |
+
// Perform batch
|
215 |
+
$response = $this->_storageClient->performBatch($this->_operations, $this->_forTableStorage, $this->_isSingleSelect);
|
216 |
+
|
217 |
+
// Dispose
|
218 |
+
$this->_clean();
|
219 |
+
|
220 |
+
// Parse response
|
221 |
+
$errors = null;
|
222 |
+
preg_match_all('/<message (.*)>(.*)<\/message>/', $response->getBody(), $errors);
|
223 |
+
|
224 |
+
// Error?
|
225 |
+
if (count($errors[2]) > 0) {
|
226 |
+
throw new Microsoft_WindowsAzure_Exception('An error has occured while committing a batch: ' . $errors[2][0]);
|
227 |
+
}
|
228 |
+
|
229 |
+
// Return
|
230 |
+
return $response;
|
231 |
+
}
|
232 |
+
|
233 |
+
/**
|
234 |
+
* Rollback current batch
|
235 |
+
*/
|
236 |
+
public function rollback()
|
237 |
+
{
|
238 |
+
// Dispose
|
239 |
+
$this->_clean();
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Get operation count
|
244 |
+
*
|
245 |
+
* @return integer
|
246 |
+
*/
|
247 |
+
public function getOperationCount()
|
248 |
+
{
|
249 |
+
return count($this->_operations);
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* Is single select?
|
254 |
+
*
|
255 |
+
* @return boolean
|
256 |
+
*/
|
257 |
+
public function isSingleSelect()
|
258 |
+
{
|
259 |
+
return $this->_isSingleSelect;
|
260 |
+
}
|
261 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/BatchStorageAbstract.php
ADDED
@@ -0,0 +1,210 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Storage.php 21617 2009-06-12 10:46:31Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Storage
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Exception
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_WindowsAzure_Storage_Batch
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/WindowsAzure/Storage/Batch.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_Http_Client
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/Http/Client.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @see Microsoft_Http_Response
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/Http/Response.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @category Microsoft
|
68 |
+
* @package Microsoft_WindowsAzure
|
69 |
+
* @subpackage Storage
|
70 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
71 |
+
* @license http://phpazure.codeplex.com/license
|
72 |
+
*/
|
73 |
+
abstract class Microsoft_WindowsAzure_Storage_BatchStorageAbstract
|
74 |
+
extends Microsoft_WindowsAzure_Storage
|
75 |
+
{
|
76 |
+
/**
|
77 |
+
* Current batch
|
78 |
+
*
|
79 |
+
* @var Microsoft_WindowsAzure_Storage_Batch
|
80 |
+
*/
|
81 |
+
protected $_currentBatch = null;
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Set current batch
|
85 |
+
*
|
86 |
+
* @param Microsoft_WindowsAzure_Storage_Batch $batch Current batch
|
87 |
+
* @throws Microsoft_WindowsAzure_Exception
|
88 |
+
*/
|
89 |
+
public function setCurrentBatch(Microsoft_WindowsAzure_Storage_Batch $batch = null)
|
90 |
+
{
|
91 |
+
if (!is_null($batch) && $this->isInBatch()) {
|
92 |
+
throw new Microsoft_WindowsAzure_Exception('Only one batch can be active at a time.');
|
93 |
+
}
|
94 |
+
$this->_currentBatch = $batch;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Get current batch
|
99 |
+
*
|
100 |
+
* @return Microsoft_WindowsAzure_Storage_Batch
|
101 |
+
*/
|
102 |
+
public function getCurrentBatch()
|
103 |
+
{
|
104 |
+
return $this->_currentBatch;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Is there a current batch?
|
109 |
+
*
|
110 |
+
* @return boolean
|
111 |
+
*/
|
112 |
+
public function isInBatch()
|
113 |
+
{
|
114 |
+
return !is_null($this->_currentBatch);
|
115 |
+
}
|
116 |
+
|
117 |
+
/**
|
118 |
+
* Starts a new batch operation set
|
119 |
+
*
|
120 |
+
* @return Microsoft_WindowsAzure_Storage_Batch
|
121 |
+
* @throws Microsoft_WindowsAzure_Exception
|
122 |
+
*/
|
123 |
+
public function startBatch()
|
124 |
+
{
|
125 |
+
return new Microsoft_WindowsAzure_Storage_Batch($this, $this->getBaseUrl());
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Perform batch using Microsoft_Http_Client channel, combining all batch operations into one request
|
130 |
+
*
|
131 |
+
* @param array $operations Operations in batch
|
132 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
133 |
+
* @param boolean $isSingleSelect Is the request a single select statement?
|
134 |
+
* @param string $resourceType Resource type
|
135 |
+
* @param string $requiredPermission Required permission
|
136 |
+
* @return Microsoft_Http_Response
|
137 |
+
*/
|
138 |
+
public function performBatch($operations = array(), $forTableStorage = false, $isSingleSelect = false, $resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN, $requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ)
|
139 |
+
{
|
140 |
+
// Generate boundaries
|
141 |
+
$batchBoundary = 'batch_' . md5(time() . microtime());
|
142 |
+
$changesetBoundary = 'changeset_' . md5(time() . microtime());
|
143 |
+
|
144 |
+
// Set headers
|
145 |
+
$headers = array();
|
146 |
+
|
147 |
+
// Add version header
|
148 |
+
$headers['x-ms-version'] = $this->_apiVersion;
|
149 |
+
|
150 |
+
// Add dataservice headers
|
151 |
+
$headers['DataServiceVersion'] = '1.0;NetFx';
|
152 |
+
$headers['MaxDataServiceVersion'] = '1.0;NetFx';
|
153 |
+
|
154 |
+
// Add content-type header
|
155 |
+
$headers['Content-Type'] = 'multipart/mixed; boundary=' . $batchBoundary;
|
156 |
+
|
157 |
+
// Set path and query string
|
158 |
+
$path = '/$batch';
|
159 |
+
$queryString = '';
|
160 |
+
|
161 |
+
// Set verb
|
162 |
+
$httpVerb = Microsoft_Http_Client::POST;
|
163 |
+
|
164 |
+
// Generate raw data
|
165 |
+
$rawData = '';
|
166 |
+
|
167 |
+
// Single select?
|
168 |
+
if ($isSingleSelect) {
|
169 |
+
$operation = $operations[0];
|
170 |
+
$rawData .= '--' . $batchBoundary . "\n";
|
171 |
+
$rawData .= 'Content-Type: application/http' . "\n";
|
172 |
+
$rawData .= 'Content-Transfer-Encoding: binary' . "\n\n";
|
173 |
+
$rawData .= $operation;
|
174 |
+
$rawData .= '--' . $batchBoundary . '--';
|
175 |
+
} else {
|
176 |
+
$rawData .= '--' . $batchBoundary . "\n";
|
177 |
+
$rawData .= 'Content-Type: multipart/mixed; boundary=' . $changesetBoundary . "\n\n";
|
178 |
+
|
179 |
+
// Add operations
|
180 |
+
foreach ($operations as $operation)
|
181 |
+
{
|
182 |
+
$rawData .= '--' . $changesetBoundary . "\n";
|
183 |
+
$rawData .= 'Content-Type: application/http' . "\n";
|
184 |
+
$rawData .= 'Content-Transfer-Encoding: binary' . "\n\n";
|
185 |
+
$rawData .= $operation;
|
186 |
+
}
|
187 |
+
$rawData .= '--' . $changesetBoundary . '--' . "\n";
|
188 |
+
|
189 |
+
$rawData .= '--' . $batchBoundary . '--';
|
190 |
+
}
|
191 |
+
|
192 |
+
// Generate URL and sign request
|
193 |
+
$requestUrl = $this->_credentials->signRequestUrl($this->getBaseUrl() . $path . $queryString, $resourceType, $requiredPermission);
|
194 |
+
$requestHeaders = $this->_credentials->signRequestHeaders($httpVerb, $path, $queryString, $headers, $forTableStorage, $resourceType, $requiredPermission);
|
195 |
+
|
196 |
+
// Prepare request
|
197 |
+
$this->_httpClientChannel->resetParameters(true);
|
198 |
+
$this->_httpClientChannel->setUri($requestUrl);
|
199 |
+
$this->_httpClientChannel->setHeaders($requestHeaders);
|
200 |
+
$this->_httpClientChannel->setRawData($rawData);
|
201 |
+
|
202 |
+
// Execute request
|
203 |
+
$response = $this->_retryPolicy->execute(
|
204 |
+
array($this->_httpClientChannel, 'request'),
|
205 |
+
array($httpVerb)
|
206 |
+
);
|
207 |
+
|
208 |
+
return $response;
|
209 |
+
}
|
210 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/Blob.php
ADDED
@@ -0,0 +1,2029 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://todo name_todo
|
33 |
+
* @version $Id: Blob.php 53747 2010-11-18 19:34:25Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract_SharedKey
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKey.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedAccessSignature
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedAccessSignature.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_Http_Client
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/Http/Client.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_Http_Response
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/Http/Response.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @see Microsoft_WindowsAzure_Storage
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @see Microsoft_WindowsAzure_Storage_BlobContainer
|
68 |
+
*/
|
69 |
+
require_once 'Microsoft/WindowsAzure/Storage/BlobContainer.php';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @see Microsoft_WindowsAzure_Storage_BlobInstance
|
73 |
+
*/
|
74 |
+
require_once 'Microsoft/WindowsAzure/Storage/BlobInstance.php';
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @see Microsoft_WindowsAzure_Storage_PageRegionInstance
|
78 |
+
*/
|
79 |
+
require_once 'Microsoft/WindowsAzure/Storage/PageRegionInstance.php';
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @see Microsoft_WindowsAzure_Storage_LeaseInstance
|
83 |
+
*/
|
84 |
+
require_once 'Microsoft/WindowsAzure/Storage/LeaseInstance.php';
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @see Microsoft_WindowsAzure_Storage_SignedIdentifier
|
88 |
+
*/
|
89 |
+
require_once 'Microsoft/WindowsAzure/Storage/SignedIdentifier.php';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @see Microsoft_WindowsAzure_Exception
|
93 |
+
*/
|
94 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
95 |
+
|
96 |
+
|
97 |
+
/**
|
98 |
+
* @category Microsoft
|
99 |
+
* @package Microsoft_WindowsAzure
|
100 |
+
* @subpackage Storage
|
101 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
102 |
+
* @license http://phpazure.codeplex.com/license
|
103 |
+
*/
|
104 |
+
class Microsoft_WindowsAzure_Storage_Blob extends Microsoft_WindowsAzure_Storage
|
105 |
+
{
|
106 |
+
/**
|
107 |
+
* ACL - Private access
|
108 |
+
*/
|
109 |
+
const ACL_PRIVATE = null;
|
110 |
+
|
111 |
+
/**
|
112 |
+
* ACL - Public access (read all blobs)
|
113 |
+
*
|
114 |
+
* @deprecated Use ACL_PUBLIC_CONTAINER or ACL_PUBLIC_BLOB instead.
|
115 |
+
*/
|
116 |
+
const ACL_PUBLIC = 'container';
|
117 |
+
|
118 |
+
/**
|
119 |
+
* ACL - Blob Public access (read all blobs)
|
120 |
+
*/
|
121 |
+
const ACL_PUBLIC_BLOB = 'blob';
|
122 |
+
|
123 |
+
/**
|
124 |
+
* ACL - Container Public access (enumerate and read all blobs)
|
125 |
+
*/
|
126 |
+
const ACL_PUBLIC_CONTAINER = 'container';
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Blob lease constants
|
130 |
+
*/
|
131 |
+
const LEASE_ACQUIRE = 'acquire';
|
132 |
+
const LEASE_RENEW = 'renew';
|
133 |
+
const LEASE_RELEASE = 'release';
|
134 |
+
const LEASE_BREAK = 'break';
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Maximal blob size (in bytes)
|
138 |
+
*/
|
139 |
+
const MAX_BLOB_SIZE = 67108864;
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Maximal blob transfer size (in bytes)
|
143 |
+
*/
|
144 |
+
const MAX_BLOB_TRANSFER_SIZE = 4194304;
|
145 |
+
|
146 |
+
/**
|
147 |
+
* Blob types
|
148 |
+
*/
|
149 |
+
const BLOBTYPE_BLOCK = 'BlockBlob';
|
150 |
+
const BLOBTYPE_PAGE = 'PageBlob';
|
151 |
+
|
152 |
+
/**
|
153 |
+
* Put page write options
|
154 |
+
*/
|
155 |
+
const PAGE_WRITE_UPDATE = 'update';
|
156 |
+
const PAGE_WRITE_CLEAR = 'clear';
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Stream wrapper clients
|
160 |
+
*
|
161 |
+
* @var array
|
162 |
+
*/
|
163 |
+
protected static $_wrapperClients = array();
|
164 |
+
|
165 |
+
/**
|
166 |
+
* SharedAccessSignature credentials
|
167 |
+
*
|
168 |
+
* @var Microsoft_WindowsAzure_Credentials_SharedAccessSignature
|
169 |
+
*/
|
170 |
+
private $_sharedAccessSignatureCredentials = null;
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Creates a new Microsoft_WindowsAzure_Storage_Blob instance
|
174 |
+
*
|
175 |
+
* @param string $host Storage host name
|
176 |
+
* @param string $accountName Account name for Windows Azure
|
177 |
+
* @param string $accountKey Account key for Windows Azure
|
178 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
179 |
+
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
|
180 |
+
*/
|
181 |
+
public function __construct($host = Microsoft_WindowsAzure_Storage::URL_DEV_BLOB, $accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
|
182 |
+
{
|
183 |
+
parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
|
184 |
+
|
185 |
+
// API version
|
186 |
+
$this->_apiVersion = '2009-09-19';
|
187 |
+
|
188 |
+
// SharedAccessSignature credentials
|
189 |
+
$this->_sharedAccessSignatureCredentials = new Microsoft_WindowsAzure_Credentials_SharedAccessSignature($accountName, $accountKey, $usePathStyleUri);
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Check if a blob exists
|
194 |
+
*
|
195 |
+
* @param string $containerName Container name
|
196 |
+
* @param string $blobName Blob name
|
197 |
+
* @param string $snapshotId Snapshot identifier
|
198 |
+
* @return boolean
|
199 |
+
*/
|
200 |
+
public function blobExists($containerName = '', $blobName = '', $snapshotId = null)
|
201 |
+
{
|
202 |
+
if ($containerName === '') {
|
203 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
204 |
+
}
|
205 |
+
if (!self::isValidContainerName($containerName)) {
|
206 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
207 |
+
}
|
208 |
+
if ($blobName === '') {
|
209 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
210 |
+
}
|
211 |
+
|
212 |
+
// Get blob instance
|
213 |
+
try {
|
214 |
+
$this->getBlobInstance($containerName, $blobName, $snapshotId);
|
215 |
+
} catch (Microsoft_WindowsAzure_Exception $e) {
|
216 |
+
return false;
|
217 |
+
}
|
218 |
+
|
219 |
+
return true;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Check if a container exists
|
224 |
+
*
|
225 |
+
* @param string $containerName Container name
|
226 |
+
* @return boolean
|
227 |
+
*/
|
228 |
+
public function containerExists($containerName = '')
|
229 |
+
{
|
230 |
+
if ($containerName === '') {
|
231 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
232 |
+
}
|
233 |
+
if (!self::isValidContainerName($containerName)) {
|
234 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
235 |
+
}
|
236 |
+
|
237 |
+
// List containers
|
238 |
+
$containers = $this->listContainers($containerName, 1);
|
239 |
+
foreach ($containers as $container) {
|
240 |
+
if ($container->Name == $containerName) {
|
241 |
+
return true;
|
242 |
+
}
|
243 |
+
}
|
244 |
+
|
245 |
+
return false;
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Create container
|
250 |
+
*
|
251 |
+
* @param string $containerName Container name
|
252 |
+
* @param array $metadata Key/value pairs of meta data
|
253 |
+
* @return object Container properties
|
254 |
+
* @throws Microsoft_WindowsAzure_Exception
|
255 |
+
*/
|
256 |
+
public function createContainer($containerName = '', $metadata = array())
|
257 |
+
{
|
258 |
+
if ($containerName === '') {
|
259 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
260 |
+
}
|
261 |
+
if (!self::isValidContainerName($containerName)) {
|
262 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
263 |
+
}
|
264 |
+
if (!is_array($metadata)) {
|
265 |
+
throw new Microsoft_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
|
266 |
+
}
|
267 |
+
|
268 |
+
// Create metadata headers
|
269 |
+
$headers = array();
|
270 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
271 |
+
|
272 |
+
// Perform request
|
273 |
+
$response = $this->_performRequest($containerName, '?restype=container', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
274 |
+
if ($response->isSuccessful()) {
|
275 |
+
return new Microsoft_WindowsAzure_Storage_BlobContainer(
|
276 |
+
$containerName,
|
277 |
+
$response->getHeader('Etag'),
|
278 |
+
$response->getHeader('Last-modified'),
|
279 |
+
$metadata
|
280 |
+
);
|
281 |
+
} else {
|
282 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
283 |
+
}
|
284 |
+
}
|
285 |
+
|
286 |
+
/**
|
287 |
+
* Create container if it does not exist
|
288 |
+
*
|
289 |
+
* @param string $containerName Container name
|
290 |
+
* @param array $metadata Key/value pairs of meta data
|
291 |
+
* @throws Microsoft_WindowsAzure_Exception
|
292 |
+
*/
|
293 |
+
public function createContainerIfNotExists($containerName = '', $metadata = array())
|
294 |
+
{
|
295 |
+
if (!$this->containerExists($containerName)) {
|
296 |
+
$this->createContainer($containerName, $metadata);
|
297 |
+
}
|
298 |
+
}
|
299 |
+
|
300 |
+
/**
|
301 |
+
* Get container ACL
|
302 |
+
*
|
303 |
+
* @param string $containerName Container name
|
304 |
+
* @param bool $signedIdentifiers Display only private/blob/container or display signed identifiers?
|
305 |
+
* @return string Acl, to be compared with Microsoft_WindowsAzure_Storage_Blob::ACL_*
|
306 |
+
* @throws Microsoft_WindowsAzure_Exception
|
307 |
+
*/
|
308 |
+
public function getContainerAcl($containerName = '', $signedIdentifiers = false)
|
309 |
+
{
|
310 |
+
if ($containerName === '') {
|
311 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
312 |
+
}
|
313 |
+
if (!self::isValidContainerName($containerName)) {
|
314 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
315 |
+
}
|
316 |
+
|
317 |
+
// Perform request
|
318 |
+
$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Microsoft_Http_Client::GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
|
319 |
+
if ($response->isSuccessful()) {
|
320 |
+
if ($signedIdentifiers == false) {
|
321 |
+
// Only private/blob/container
|
322 |
+
$accessType = $response->getHeader(Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access');
|
323 |
+
if (strtolower($accessType) == 'true') {
|
324 |
+
$accessType = self::ACL_PUBLIC_CONTAINER;
|
325 |
+
}
|
326 |
+
return $accessType;
|
327 |
+
} else {
|
328 |
+
// Parse result
|
329 |
+
$result = $this->_parseResponse($response);
|
330 |
+
if (!$result) {
|
331 |
+
return array();
|
332 |
+
}
|
333 |
+
|
334 |
+
$entries = null;
|
335 |
+
if ($result->SignedIdentifier) {
|
336 |
+
if (count($result->SignedIdentifier) > 1) {
|
337 |
+
$entries = $result->SignedIdentifier;
|
338 |
+
} else {
|
339 |
+
$entries = array($result->SignedIdentifier);
|
340 |
+
}
|
341 |
+
}
|
342 |
+
|
343 |
+
// Return value
|
344 |
+
$returnValue = array();
|
345 |
+
foreach ($entries as $entry) {
|
346 |
+
$returnValue[] = new Microsoft_WindowsAzure_Storage_SignedIdentifier(
|
347 |
+
$entry->Id,
|
348 |
+
$entry->AccessPolicy ? $entry->AccessPolicy->Start ? $entry->AccessPolicy->Start : '' : '',
|
349 |
+
$entry->AccessPolicy ? $entry->AccessPolicy->Expiry ? $entry->AccessPolicy->Expiry : '' : '',
|
350 |
+
$entry->AccessPolicy ? $entry->AccessPolicy->Permission ? $entry->AccessPolicy->Permission : '' : ''
|
351 |
+
);
|
352 |
+
}
|
353 |
+
|
354 |
+
// Return
|
355 |
+
return $returnValue;
|
356 |
+
}
|
357 |
+
} else {
|
358 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
359 |
+
}
|
360 |
+
}
|
361 |
+
|
362 |
+
/**
|
363 |
+
* Set container ACL
|
364 |
+
*
|
365 |
+
* @param string $containerName Container name
|
366 |
+
* @param bool $acl Microsoft_WindowsAzure_Storage_Blob::ACL_*
|
367 |
+
* @param array $signedIdentifiers Signed identifiers
|
368 |
+
* @throws Microsoft_WindowsAzure_Exception
|
369 |
+
*/
|
370 |
+
public function setContainerAcl($containerName = '', $acl = self::ACL_PRIVATE, $signedIdentifiers = array())
|
371 |
+
{
|
372 |
+
if ($containerName === '') {
|
373 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
374 |
+
}
|
375 |
+
if (!self::isValidContainerName($containerName)) {
|
376 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
377 |
+
}
|
378 |
+
|
379 |
+
// Headers
|
380 |
+
$headers = array();
|
381 |
+
|
382 |
+
// Acl specified?
|
383 |
+
if ($acl != self::ACL_PRIVATE && !is_null($acl) && $acl != '') {
|
384 |
+
$headers[Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-public-access'] = $acl;
|
385 |
+
}
|
386 |
+
|
387 |
+
// Policies
|
388 |
+
$policies = null;
|
389 |
+
if (is_array($signedIdentifiers) && count($signedIdentifiers) > 0) {
|
390 |
+
$policies = '';
|
391 |
+
$policies .= '<?xml version="1.0" encoding="utf-8"?>' . "\r\n";
|
392 |
+
$policies .= '<SignedIdentifiers>' . "\r\n";
|
393 |
+
foreach ($signedIdentifiers as $signedIdentifier) {
|
394 |
+
$policies .= ' <SignedIdentifier>' . "\r\n";
|
395 |
+
$policies .= ' <Id>' . $signedIdentifier->Id . '</Id>' . "\r\n";
|
396 |
+
$policies .= ' <AccessPolicy>' . "\r\n";
|
397 |
+
if ($signedIdentifier->Start != '')
|
398 |
+
$policies .= ' <Start>' . $signedIdentifier->Start . '</Start>' . "\r\n";
|
399 |
+
if ($signedIdentifier->Expiry != '')
|
400 |
+
$policies .= ' <Expiry>' . $signedIdentifier->Expiry . '</Expiry>' . "\r\n";
|
401 |
+
if ($signedIdentifier->Permissions != '')
|
402 |
+
$policies .= ' <Permission>' . $signedIdentifier->Permissions . '</Permission>' . "\r\n";
|
403 |
+
$policies .= ' </AccessPolicy>' . "\r\n";
|
404 |
+
$policies .= ' </SignedIdentifier>' . "\r\n";
|
405 |
+
}
|
406 |
+
$policies .= '</SignedIdentifiers>' . "\r\n";
|
407 |
+
}
|
408 |
+
|
409 |
+
// Perform request
|
410 |
+
$response = $this->_performRequest($containerName, '?restype=container&comp=acl', Microsoft_Http_Client::PUT, $headers, false, $policies, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
411 |
+
if (!$response->isSuccessful()) {
|
412 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
413 |
+
}
|
414 |
+
}
|
415 |
+
|
416 |
+
/**
|
417 |
+
* Get container
|
418 |
+
*
|
419 |
+
* @param string $containerName Container name
|
420 |
+
* @return Microsoft_WindowsAzure_Storage_BlobContainer
|
421 |
+
* @throws Microsoft_WindowsAzure_Exception
|
422 |
+
*/
|
423 |
+
public function getContainer($containerName = '')
|
424 |
+
{
|
425 |
+
if ($containerName === '') {
|
426 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
427 |
+
}
|
428 |
+
if (!self::isValidContainerName($containerName)) {
|
429 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
430 |
+
}
|
431 |
+
|
432 |
+
// Perform request
|
433 |
+
$response = $this->_performRequest($containerName, '?restype=container', Microsoft_Http_Client::GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
|
434 |
+
if ($response->isSuccessful()) {
|
435 |
+
// Parse metadata
|
436 |
+
$metadata = $this->_parseMetadataHeaders($response->getHeaders());
|
437 |
+
|
438 |
+
// Return container
|
439 |
+
return new Microsoft_WindowsAzure_Storage_BlobContainer(
|
440 |
+
$containerName,
|
441 |
+
$response->getHeader('Etag'),
|
442 |
+
$response->getHeader('Last-modified'),
|
443 |
+
$metadata
|
444 |
+
);
|
445 |
+
} else {
|
446 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
447 |
+
}
|
448 |
+
}
|
449 |
+
|
450 |
+
/**
|
451 |
+
* Get container metadata
|
452 |
+
*
|
453 |
+
* @param string $containerName Container name
|
454 |
+
* @return array Key/value pairs of meta data
|
455 |
+
* @throws Microsoft_WindowsAzure_Exception
|
456 |
+
*/
|
457 |
+
public function getContainerMetadata($containerName = '')
|
458 |
+
{
|
459 |
+
if ($containerName === '') {
|
460 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
461 |
+
}
|
462 |
+
if (!self::isValidContainerName($containerName)) {
|
463 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
464 |
+
}
|
465 |
+
|
466 |
+
return $this->getContainer($containerName)->Metadata;
|
467 |
+
}
|
468 |
+
|
469 |
+
/**
|
470 |
+
* Set container metadata
|
471 |
+
*
|
472 |
+
* Calling the Set Container Metadata operation overwrites all existing metadata that is associated with the container. It's not possible to modify an individual name/value pair.
|
473 |
+
*
|
474 |
+
* @param string $containerName Container name
|
475 |
+
* @param array $metadata Key/value pairs of meta data
|
476 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
477 |
+
* @throws Microsoft_WindowsAzure_Exception
|
478 |
+
*/
|
479 |
+
public function setContainerMetadata($containerName = '', $metadata = array(), $additionalHeaders = array())
|
480 |
+
{
|
481 |
+
if ($containerName === '') {
|
482 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
483 |
+
}
|
484 |
+
if (!self::isValidContainerName($containerName)) {
|
485 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
486 |
+
}
|
487 |
+
if (!is_array($metadata)) {
|
488 |
+
throw new Microsoft_WindowsAzure_Exception('Meta data should be an array of key and value pairs.');
|
489 |
+
}
|
490 |
+
if (count($metadata) == 0) {
|
491 |
+
return;
|
492 |
+
}
|
493 |
+
|
494 |
+
// Create metadata headers
|
495 |
+
$headers = array();
|
496 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
497 |
+
|
498 |
+
// Additional headers?
|
499 |
+
foreach ($additionalHeaders as $key => $value) {
|
500 |
+
$headers[$key] = $value;
|
501 |
+
}
|
502 |
+
|
503 |
+
// Perform request
|
504 |
+
$response = $this->_performRequest($containerName, '?restype=container&comp=metadata', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
505 |
+
if (!$response->isSuccessful()) {
|
506 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
507 |
+
}
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Delete container
|
512 |
+
*
|
513 |
+
* @param string $containerName Container name
|
514 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
515 |
+
* @throws Microsoft_WindowsAzure_Exception
|
516 |
+
*/
|
517 |
+
public function deleteContainer($containerName = '', $additionalHeaders = array())
|
518 |
+
{
|
519 |
+
if ($containerName === '') {
|
520 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
521 |
+
}
|
522 |
+
if (!self::isValidContainerName($containerName)) {
|
523 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
524 |
+
}
|
525 |
+
|
526 |
+
// Additional headers?
|
527 |
+
$headers = array();
|
528 |
+
foreach ($additionalHeaders as $key => $value) {
|
529 |
+
$headers[$key] = $value;
|
530 |
+
}
|
531 |
+
|
532 |
+
// Perform request
|
533 |
+
$response = $this->_performRequest($containerName, '?restype=container', Microsoft_Http_Client::DELETE, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
534 |
+
if (!$response->isSuccessful()) {
|
535 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
536 |
+
}
|
537 |
+
}
|
538 |
+
|
539 |
+
/**
|
540 |
+
* List containers
|
541 |
+
*
|
542 |
+
* @param string $prefix Optional. Filters the results to return only containers whose name begins with the specified prefix.
|
543 |
+
* @param int $maxResults Optional. Specifies the maximum number of containers to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
|
544 |
+
* @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
|
545 |
+
* @param string $include Optional. Include this parameter to specify that the container's metadata be returned as part of the response body. (allowed values: '', 'metadata')
|
546 |
+
* @param int $currentResultCount Current result count (internal use)
|
547 |
+
* @return array
|
548 |
+
* @throws Microsoft_WindowsAzure_Exception
|
549 |
+
*/
|
550 |
+
public function listContainers($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
|
551 |
+
{
|
552 |
+
// Build query string
|
553 |
+
$queryString = array('comp=list');
|
554 |
+
if (!is_null($prefix)) {
|
555 |
+
$queryString[] = 'prefix=' . $prefix;
|
556 |
+
}
|
557 |
+
if (!is_null($maxResults)) {
|
558 |
+
$queryString[] = 'maxresults=' . $maxResults;
|
559 |
+
}
|
560 |
+
if (!is_null($marker)) {
|
561 |
+
$queryString[] = 'marker=' . $marker;
|
562 |
+
}
|
563 |
+
if (!is_null($include)) {
|
564 |
+
$queryString[] = 'include=' . $include;
|
565 |
+
}
|
566 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
567 |
+
|
568 |
+
// Perform request
|
569 |
+
$response = $this->_performRequest('', $queryString, Microsoft_Http_Client::GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_CONTAINER, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
|
570 |
+
if ($response->isSuccessful()) {
|
571 |
+
$xmlContainers = $this->_parseResponse($response)->Containers->Container;
|
572 |
+
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
|
573 |
+
|
574 |
+
$containers = array();
|
575 |
+
if (!is_null($xmlContainers)) {
|
576 |
+
for ($i = 0; $i < count($xmlContainers); $i++) {
|
577 |
+
$containers[] = new Microsoft_WindowsAzure_Storage_BlobContainer(
|
578 |
+
(string)$xmlContainers[$i]->Name,
|
579 |
+
(string)$xmlContainers[$i]->Etag,
|
580 |
+
(string)$xmlContainers[$i]->LastModified,
|
581 |
+
$this->_parseMetadataElement($xmlContainers[$i])
|
582 |
+
);
|
583 |
+
}
|
584 |
+
}
|
585 |
+
$currentResultCount = $currentResultCount + count($containers);
|
586 |
+
if (!is_null($maxResults) && $currentResultCount < $maxResults) {
|
587 |
+
if (!is_null($xmlMarker) && $xmlMarker != '') {
|
588 |
+
$containers = array_merge($containers, $this->listContainers($prefix, $maxResults, $xmlMarker, $include, $currentResultCount));
|
589 |
+
}
|
590 |
+
}
|
591 |
+
if (!is_null($maxResults) && count($containers) > $maxResults) {
|
592 |
+
$containers = array_slice($containers, 0, $maxResults);
|
593 |
+
}
|
594 |
+
|
595 |
+
return $containers;
|
596 |
+
} else {
|
597 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
598 |
+
}
|
599 |
+
}
|
600 |
+
|
601 |
+
/**
|
602 |
+
* Put blob
|
603 |
+
*
|
604 |
+
* @param string $containerName Container name
|
605 |
+
* @param string $blobName Blob name
|
606 |
+
* @param string $localFileName Local file name to be uploaded
|
607 |
+
* @param array $metadata Key/value pairs of meta data
|
608 |
+
* @param string $leaseId Lease identifier
|
609 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
610 |
+
* @return object Partial blob properties
|
611 |
+
* @throws Microsoft_WindowsAzure_Exception
|
612 |
+
*/
|
613 |
+
public function putBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
614 |
+
{
|
615 |
+
if ($containerName === '') {
|
616 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
617 |
+
}
|
618 |
+
if (!self::isValidContainerName($containerName)) {
|
619 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
620 |
+
}
|
621 |
+
if ($blobName === '') {
|
622 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
623 |
+
}
|
624 |
+
if ($localFileName === '') {
|
625 |
+
throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
|
626 |
+
}
|
627 |
+
if (!file_exists($localFileName)) {
|
628 |
+
throw new Microsoft_WindowsAzure_Exception('Local file not found.');
|
629 |
+
}
|
630 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
631 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
632 |
+
}
|
633 |
+
|
634 |
+
// Check file size
|
635 |
+
if (filesize($localFileName) >= self::MAX_BLOB_SIZE) {
|
636 |
+
return $this->putLargeBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders);
|
637 |
+
}
|
638 |
+
|
639 |
+
// Put the data to Windows Azure Storage
|
640 |
+
return $this->putBlobData($containerName, $blobName, file_get_contents($localFileName), $metadata, $leaseId, $additionalHeaders);
|
641 |
+
}
|
642 |
+
|
643 |
+
/**
|
644 |
+
* Put blob data
|
645 |
+
*
|
646 |
+
* @param string $containerName Container name
|
647 |
+
* @param string $blobName Blob name
|
648 |
+
* @param mixed $data Data to store
|
649 |
+
* @param array $metadata Key/value pairs of meta data
|
650 |
+
* @param string $leaseId Lease identifier
|
651 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
652 |
+
* @return object Partial blob properties
|
653 |
+
* @throws Microsoft_WindowsAzure_Exception
|
654 |
+
*/
|
655 |
+
public function putBlobData($containerName = '', $blobName = '', $data = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
656 |
+
{
|
657 |
+
if ($containerName === '') {
|
658 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
659 |
+
}
|
660 |
+
if (!self::isValidContainerName($containerName)) {
|
661 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
662 |
+
}
|
663 |
+
if ($blobName === '') {
|
664 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
665 |
+
}
|
666 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
667 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
668 |
+
}
|
669 |
+
|
670 |
+
// Create metadata headers
|
671 |
+
$headers = array();
|
672 |
+
if (!is_null($leaseId)) {
|
673 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
674 |
+
}
|
675 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
676 |
+
|
677 |
+
// Additional headers?
|
678 |
+
foreach ($additionalHeaders as $key => $value) {
|
679 |
+
$headers[$key] = $value;
|
680 |
+
}
|
681 |
+
|
682 |
+
// Specify blob type
|
683 |
+
$headers[Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_BLOCK;
|
684 |
+
|
685 |
+
// Resource name
|
686 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
687 |
+
|
688 |
+
// Perform request
|
689 |
+
$response = $this->_performRequest($resourceName, '', Microsoft_Http_Client::PUT, $headers, false, $data, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
690 |
+
if ($response->isSuccessful()) {
|
691 |
+
return new Microsoft_WindowsAzure_Storage_BlobInstance(
|
692 |
+
$containerName,
|
693 |
+
$blobName,
|
694 |
+
null,
|
695 |
+
$response->getHeader('Etag'),
|
696 |
+
$response->getHeader('Last-modified'),
|
697 |
+
$this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
|
698 |
+
strlen($data),
|
699 |
+
'',
|
700 |
+
'',
|
701 |
+
'',
|
702 |
+
false,
|
703 |
+
$metadata
|
704 |
+
);
|
705 |
+
} else {
|
706 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
707 |
+
}
|
708 |
+
}
|
709 |
+
|
710 |
+
/**
|
711 |
+
* Put large blob (> 64 MB)
|
712 |
+
*
|
713 |
+
* @param string $containerName Container name
|
714 |
+
* @param string $blobName Blob name
|
715 |
+
* @param string $localFileName Local file name to be uploaded
|
716 |
+
* @param array $metadata Key/value pairs of meta data
|
717 |
+
* @param string $leaseId Lease identifier
|
718 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
719 |
+
* @return object Partial blob properties
|
720 |
+
* @throws Microsoft_WindowsAzure_Exception
|
721 |
+
*/
|
722 |
+
public function putLargeBlob($containerName = '', $blobName = '', $localFileName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
723 |
+
{
|
724 |
+
if ($containerName === '') {
|
725 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
726 |
+
}
|
727 |
+
if (!self::isValidContainerName($containerName)) {
|
728 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
729 |
+
}
|
730 |
+
if ($blobName === '') {
|
731 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
732 |
+
}
|
733 |
+
if ($localFileName === '') {
|
734 |
+
throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
|
735 |
+
}
|
736 |
+
if (!file_exists($localFileName)) {
|
737 |
+
throw new Microsoft_WindowsAzure_Exception('Local file not found.');
|
738 |
+
}
|
739 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
740 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
741 |
+
}
|
742 |
+
|
743 |
+
// Check file size
|
744 |
+
if (filesize($localFileName) < self::MAX_BLOB_SIZE) {
|
745 |
+
return $this->putBlob($containerName, $blobName, $localFileName, $metadata, $leaseId, $additionalHeaders);
|
746 |
+
}
|
747 |
+
|
748 |
+
// Determine number of parts
|
749 |
+
$numberOfParts = ceil( filesize($localFileName) / self::MAX_BLOB_TRANSFER_SIZE );
|
750 |
+
|
751 |
+
// Generate block id's
|
752 |
+
$blockIdentifiers = array();
|
753 |
+
for ($i = 0; $i < $numberOfParts; $i++) {
|
754 |
+
$blockIdentifiers[] = $this->_generateBlockId($i);
|
755 |
+
}
|
756 |
+
|
757 |
+
// Open file
|
758 |
+
$fp = fopen($localFileName, 'r');
|
759 |
+
if ($fp === false) {
|
760 |
+
throw new Microsoft_WindowsAzure_Exception('Could not open local file.');
|
761 |
+
}
|
762 |
+
|
763 |
+
// Upload parts
|
764 |
+
for ($i = 0; $i < $numberOfParts; $i++) {
|
765 |
+
// Seek position in file
|
766 |
+
fseek($fp, $i * self::MAX_BLOB_TRANSFER_SIZE);
|
767 |
+
|
768 |
+
// Read contents
|
769 |
+
$fileContents = fread($fp, self::MAX_BLOB_TRANSFER_SIZE);
|
770 |
+
|
771 |
+
// Put block
|
772 |
+
$this->putBlock($containerName, $blobName, $blockIdentifiers[$i], $fileContents, $leaseId);
|
773 |
+
|
774 |
+
// Dispose file contents
|
775 |
+
$fileContents = null;
|
776 |
+
unset($fileContents);
|
777 |
+
}
|
778 |
+
|
779 |
+
// Close file
|
780 |
+
fclose($fp);
|
781 |
+
|
782 |
+
// Put block list
|
783 |
+
$this->putBlockList($containerName, $blobName, $blockIdentifiers, $metadata, $leaseId, $additionalHeaders);
|
784 |
+
|
785 |
+
// Return information of the blob
|
786 |
+
return $this->getBlobInstance($containerName, $blobName, null, $leaseId);
|
787 |
+
}
|
788 |
+
|
789 |
+
/**
|
790 |
+
* Put large blob block
|
791 |
+
*
|
792 |
+
* @param string $containerName Container name
|
793 |
+
* @param string $blobName Blob name
|
794 |
+
* @param string $identifier Block ID
|
795 |
+
* @param array $contents Contents of the block
|
796 |
+
* @param string $leaseId Lease identifier
|
797 |
+
* @throws Microsoft_WindowsAzure_Exception
|
798 |
+
*/
|
799 |
+
public function putBlock($containerName = '', $blobName = '', $identifier = '', $contents = '', $leaseId = null)
|
800 |
+
{
|
801 |
+
if ($containerName === '') {
|
802 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
803 |
+
}
|
804 |
+
if (!self::isValidContainerName($containerName)) {
|
805 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
806 |
+
}
|
807 |
+
if ($identifier === '') {
|
808 |
+
throw new Microsoft_WindowsAzure_Exception('Block identifier is not specified.');
|
809 |
+
}
|
810 |
+
if (strlen($contents) > self::MAX_BLOB_TRANSFER_SIZE) {
|
811 |
+
throw new Microsoft_WindowsAzure_Exception('Block size is too big.');
|
812 |
+
}
|
813 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
814 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
815 |
+
}
|
816 |
+
|
817 |
+
// Headers
|
818 |
+
$headers = array();
|
819 |
+
if (!is_null($leaseId)) {
|
820 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
821 |
+
}
|
822 |
+
|
823 |
+
// Resource name
|
824 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
825 |
+
|
826 |
+
// Upload
|
827 |
+
$response = $this->_performRequest($resourceName, '?comp=block&blockid=' . base64_encode($identifier), Microsoft_Http_Client::PUT, $headers, false, $contents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
828 |
+
if (!$response->isSuccessful()) {
|
829 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
830 |
+
}
|
831 |
+
}
|
832 |
+
|
833 |
+
/**
|
834 |
+
* Put block list
|
835 |
+
*
|
836 |
+
* @param string $containerName Container name
|
837 |
+
* @param string $blobName Blob name
|
838 |
+
* @param array $blockList Array of block identifiers
|
839 |
+
* @param array $metadata Key/value pairs of meta data
|
840 |
+
* @param string $leaseId Lease identifier
|
841 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
842 |
+
* @throws Microsoft_WindowsAzure_Exception
|
843 |
+
*/
|
844 |
+
public function putBlockList($containerName = '', $blobName = '', $blockList = array(), $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
845 |
+
{
|
846 |
+
if ($containerName === '') {
|
847 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
848 |
+
}
|
849 |
+
if (!self::isValidContainerName($containerName)) {
|
850 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
851 |
+
}
|
852 |
+
if ($blobName === '') {
|
853 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
854 |
+
}
|
855 |
+
if (count($blockList) == 0) {
|
856 |
+
throw new Microsoft_WindowsAzure_Exception('Block list does not contain any elements.');
|
857 |
+
}
|
858 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
859 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
860 |
+
}
|
861 |
+
|
862 |
+
// Generate block list
|
863 |
+
$blocks = '';
|
864 |
+
foreach ($blockList as $block) {
|
865 |
+
$blocks .= ' <Latest>' . base64_encode($block) . '</Latest>' . "\n";
|
866 |
+
}
|
867 |
+
|
868 |
+
// Generate block list request
|
869 |
+
$fileContents = utf8_encode(implode("\n", array(
|
870 |
+
'<?xml version="1.0" encoding="utf-8"?>',
|
871 |
+
'<BlockList>',
|
872 |
+
$blocks,
|
873 |
+
'</BlockList>'
|
874 |
+
)));
|
875 |
+
|
876 |
+
// Create metadata headers
|
877 |
+
$headers = array();
|
878 |
+
if (!is_null($leaseId)) {
|
879 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
880 |
+
}
|
881 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
882 |
+
|
883 |
+
// Additional headers?
|
884 |
+
foreach ($additionalHeaders as $key => $value) {
|
885 |
+
$headers[$key] = $value;
|
886 |
+
}
|
887 |
+
|
888 |
+
// Resource name
|
889 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
890 |
+
|
891 |
+
// Perform request
|
892 |
+
$response = $this->_performRequest($resourceName, '?comp=blocklist', Microsoft_Http_Client::PUT, $headers, false, $fileContents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
893 |
+
if (!$response->isSuccessful()) {
|
894 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
895 |
+
}
|
896 |
+
}
|
897 |
+
|
898 |
+
/**
|
899 |
+
* Get block list
|
900 |
+
*
|
901 |
+
* @param string $containerName Container name
|
902 |
+
* @param string $blobName Blob name
|
903 |
+
* @param string $snapshotId Snapshot identifier
|
904 |
+
* @param string $leaseId Lease identifier
|
905 |
+
* @param integer $type Type of block list to retrieve. 0 = all, 1 = committed, 2 = uncommitted
|
906 |
+
* @return array
|
907 |
+
* @throws Microsoft_WindowsAzure_Exception
|
908 |
+
*/
|
909 |
+
public function getBlockList($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $type = 0)
|
910 |
+
{
|
911 |
+
if ($containerName === '') {
|
912 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
913 |
+
}
|
914 |
+
if (!self::isValidContainerName($containerName)) {
|
915 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
916 |
+
}
|
917 |
+
if ($blobName === '') {
|
918 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
919 |
+
}
|
920 |
+
if ($type < 0 || $type > 2) {
|
921 |
+
throw new Microsoft_WindowsAzure_Exception('Invalid type of block list to retrieve.');
|
922 |
+
}
|
923 |
+
|
924 |
+
// Set $blockListType
|
925 |
+
$blockListType = 'all';
|
926 |
+
if ($type == 1) {
|
927 |
+
$blockListType = 'committed';
|
928 |
+
}
|
929 |
+
if ($type == 2) {
|
930 |
+
$blockListType = 'uncommitted';
|
931 |
+
}
|
932 |
+
|
933 |
+
// Headers
|
934 |
+
$headers = array();
|
935 |
+
if (!is_null($leaseId)) {
|
936 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
937 |
+
}
|
938 |
+
|
939 |
+
// Build query string
|
940 |
+
$queryString = array('comp=blocklist', 'blocklisttype=' . $blockListType);
|
941 |
+
if (!is_null($snapshotId)) {
|
942 |
+
$queryString[] = 'snapshot=' . $snapshotId;
|
943 |
+
}
|
944 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
945 |
+
|
946 |
+
// Resource name
|
947 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
948 |
+
|
949 |
+
// Perform request
|
950 |
+
$response = $this->_performRequest($resourceName, $queryString, Microsoft_Http_Client::GET, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
|
951 |
+
if ($response->isSuccessful()) {
|
952 |
+
// Parse response
|
953 |
+
$blockList = $this->_parseResponse($response);
|
954 |
+
|
955 |
+
// Create return value
|
956 |
+
$returnValue = array();
|
957 |
+
if ($blockList->CommittedBlocks) {
|
958 |
+
foreach ($blockList->CommittedBlocks->Block as $block) {
|
959 |
+
$returnValue['CommittedBlocks'][] = (object)array(
|
960 |
+
'Name' => (string)$block->Name,
|
961 |
+
'Size' => (string)$block->Size
|
962 |
+
);
|
963 |
+
}
|
964 |
+
}
|
965 |
+
if ($blockList->UncommittedBlocks) {
|
966 |
+
foreach ($blockList->UncommittedBlocks->Block as $block) {
|
967 |
+
$returnValue['UncommittedBlocks'][] = (object)array(
|
968 |
+
'Name' => (string)$block->Name,
|
969 |
+
'Size' => (string)$block->Size
|
970 |
+
);
|
971 |
+
}
|
972 |
+
}
|
973 |
+
|
974 |
+
return $returnValue;
|
975 |
+
} else {
|
976 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
977 |
+
}
|
978 |
+
}
|
979 |
+
|
980 |
+
/**
|
981 |
+
* Create page blob
|
982 |
+
*
|
983 |
+
* @param string $containerName Container name
|
984 |
+
* @param string $blobName Blob name
|
985 |
+
* @param int $size Size of the page blob in bytes
|
986 |
+
* @param array $metadata Key/value pairs of meta data
|
987 |
+
* @param string $leaseId Lease identifier
|
988 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
989 |
+
* @return object Partial blob properties
|
990 |
+
* @throws Microsoft_WindowsAzure_Exception
|
991 |
+
*/
|
992 |
+
public function createPageBlob($containerName = '', $blobName = '', $size = 0, $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
993 |
+
{
|
994 |
+
if ($containerName === '') {
|
995 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
996 |
+
}
|
997 |
+
if (!self::isValidContainerName($containerName)) {
|
998 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
999 |
+
}
|
1000 |
+
if ($blobName === '') {
|
1001 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1002 |
+
}
|
1003 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1004 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1005 |
+
}
|
1006 |
+
if ($size <= 0) {
|
1007 |
+
throw new Microsoft_WindowsAzure_Exception('Page blob size must be specified.');
|
1008 |
+
}
|
1009 |
+
|
1010 |
+
// Create metadata headers
|
1011 |
+
$headers = array();
|
1012 |
+
if (!is_null($leaseId)) {
|
1013 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1014 |
+
}
|
1015 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
1016 |
+
|
1017 |
+
// Additional headers?
|
1018 |
+
foreach ($additionalHeaders as $key => $value) {
|
1019 |
+
$headers[$key] = $value;
|
1020 |
+
}
|
1021 |
+
|
1022 |
+
// Specify blob type & blob length
|
1023 |
+
$headers[Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-type'] = self::BLOBTYPE_PAGE;
|
1024 |
+
$headers[Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'blob-content-length'] = $size;
|
1025 |
+
$headers['Content-Length'] = 0;
|
1026 |
+
|
1027 |
+
// Resource name
|
1028 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1029 |
+
|
1030 |
+
// Perform request
|
1031 |
+
$response = $this->_performRequest($resourceName, '', Microsoft_Http_Client::PUT, $headers, false, '', Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1032 |
+
if ($response->isSuccessful()) {
|
1033 |
+
return new Microsoft_WindowsAzure_Storage_BlobInstance(
|
1034 |
+
$containerName,
|
1035 |
+
$blobName,
|
1036 |
+
null,
|
1037 |
+
$response->getHeader('Etag'),
|
1038 |
+
$response->getHeader('Last-modified'),
|
1039 |
+
$this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
|
1040 |
+
$size,
|
1041 |
+
'',
|
1042 |
+
'',
|
1043 |
+
'',
|
1044 |
+
false,
|
1045 |
+
$metadata
|
1046 |
+
);
|
1047 |
+
} else {
|
1048 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1049 |
+
}
|
1050 |
+
}
|
1051 |
+
|
1052 |
+
/**
|
1053 |
+
* Put page in page blob
|
1054 |
+
*
|
1055 |
+
* @param string $containerName Container name
|
1056 |
+
* @param string $blobName Blob name
|
1057 |
+
* @param int $startByteOffset Start byte offset
|
1058 |
+
* @param int $endByteOffset End byte offset
|
1059 |
+
* @param mixed $contents Page contents
|
1060 |
+
* @param string $writeMethod Write method (Microsoft_WindowsAzure_Storage_Blob::PAGE_WRITE_*)
|
1061 |
+
* @param string $leaseId Lease identifier
|
1062 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1063 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1064 |
+
*/
|
1065 |
+
public function putPage($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $contents = '', $writeMethod = self::PAGE_WRITE_UPDATE, $leaseId = null, $additionalHeaders = array())
|
1066 |
+
{
|
1067 |
+
if ($containerName === '') {
|
1068 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1069 |
+
}
|
1070 |
+
if (!self::isValidContainerName($containerName)) {
|
1071 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1072 |
+
}
|
1073 |
+
if ($blobName === '') {
|
1074 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1075 |
+
}
|
1076 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1077 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1078 |
+
}
|
1079 |
+
if ($startByteOffset % 512 != 0) {
|
1080 |
+
throw new Microsoft_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
|
1081 |
+
}
|
1082 |
+
if (($endByteOffset + 1) % 512 != 0) {
|
1083 |
+
throw new Microsoft_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
|
1084 |
+
}
|
1085 |
+
|
1086 |
+
// Determine size
|
1087 |
+
$size = strlen($contents);
|
1088 |
+
if ($size >= self::MAX_BLOB_TRANSFER_SIZE) {
|
1089 |
+
throw new Microsoft_WindowsAzure_Exception('Page blob size must not be larger than ' + self::MAX_BLOB_TRANSFER_SIZE . ' bytes.');
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
// Create metadata headers
|
1093 |
+
$headers = array();
|
1094 |
+
if (!is_null($leaseId)) {
|
1095 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// Additional headers?
|
1099 |
+
foreach ($additionalHeaders as $key => $value) {
|
1100 |
+
$headers[$key] = $value;
|
1101 |
+
}
|
1102 |
+
|
1103 |
+
// Specify range
|
1104 |
+
$headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset;
|
1105 |
+
|
1106 |
+
// Write method
|
1107 |
+
$headers[Microsoft_WindowsAzure_Storage::PREFIX_STORAGE_HEADER . 'page-write'] = $writeMethod;
|
1108 |
+
|
1109 |
+
// Resource name
|
1110 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1111 |
+
|
1112 |
+
// Perform request
|
1113 |
+
$response = $this->_performRequest($resourceName, '?comp=page', Microsoft_Http_Client::PUT, $headers, false, $contents, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1114 |
+
if (!$response->isSuccessful()) {
|
1115 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1116 |
+
}
|
1117 |
+
}
|
1118 |
+
|
1119 |
+
/**
|
1120 |
+
* Put page in page blob
|
1121 |
+
*
|
1122 |
+
* @param string $containerName Container name
|
1123 |
+
* @param string $blobName Blob name
|
1124 |
+
* @param int $startByteOffset Start byte offset
|
1125 |
+
* @param int $endByteOffset End byte offset
|
1126 |
+
* @param string $leaseId Lease identifier
|
1127 |
+
* @return array Array of page ranges
|
1128 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1129 |
+
*/
|
1130 |
+
public function getPageRegions($containerName = '', $blobName = '', $startByteOffset = 0, $endByteOffset = 0, $leaseId = null)
|
1131 |
+
{
|
1132 |
+
if ($containerName === '') {
|
1133 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1134 |
+
}
|
1135 |
+
if (!self::isValidContainerName($containerName)) {
|
1136 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1137 |
+
}
|
1138 |
+
if ($blobName === '') {
|
1139 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1140 |
+
}
|
1141 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1142 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1143 |
+
}
|
1144 |
+
if ($startByteOffset % 512 != 0) {
|
1145 |
+
throw new Microsoft_WindowsAzure_Exception('Start byte offset must be a modulus of 512.');
|
1146 |
+
}
|
1147 |
+
if ($endByteOffset > 0 && ($endByteOffset + 1) % 512 != 0) {
|
1148 |
+
throw new Microsoft_WindowsAzure_Exception('End byte offset must be a modulus of 512 minus 1.');
|
1149 |
+
}
|
1150 |
+
|
1151 |
+
// Create metadata headers
|
1152 |
+
$headers = array();
|
1153 |
+
if (!is_null($leaseId)) {
|
1154 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1155 |
+
}
|
1156 |
+
|
1157 |
+
// Specify range?
|
1158 |
+
if ($endByteOffset > 0) {
|
1159 |
+
$headers['Range'] = 'bytes=' . $startByteOffset . '-' . $endByteOffset;
|
1160 |
+
}
|
1161 |
+
|
1162 |
+
// Resource name
|
1163 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1164 |
+
|
1165 |
+
// Perform request
|
1166 |
+
$response = $this->_performRequest($resourceName, '?comp=pagelist', Microsoft_Http_Client::GET, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1167 |
+
if ($response->isSuccessful()) {
|
1168 |
+
$result = $this->_parseResponse($response);
|
1169 |
+
$xmlRanges = null;
|
1170 |
+
if (count($result->PageRange) > 1) {
|
1171 |
+
$xmlRanges = $result->PageRange;
|
1172 |
+
} else {
|
1173 |
+
$xmlRanges = array($result->PageRange);
|
1174 |
+
}
|
1175 |
+
|
1176 |
+
$ranges = array();
|
1177 |
+
for ($i = 0; $i < count($xmlRanges); $i++) {
|
1178 |
+
$ranges[] = new Microsoft_WindowsAzure_Storage_PageRegionInstance(
|
1179 |
+
(int)$xmlRanges[$i]->Start,
|
1180 |
+
(int)$xmlRanges[$i]->End
|
1181 |
+
);
|
1182 |
+
}
|
1183 |
+
|
1184 |
+
return $ranges;
|
1185 |
+
} else {
|
1186 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1187 |
+
}
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
/**
|
1191 |
+
* Copy blob
|
1192 |
+
*
|
1193 |
+
* @param string $sourceContainerName Source container name
|
1194 |
+
* @param string $sourceBlobName Source blob name
|
1195 |
+
* @param string $destinationContainerName Destination container name
|
1196 |
+
* @param string $destinationBlobName Destination blob name
|
1197 |
+
* @param array $metadata Key/value pairs of meta data
|
1198 |
+
* @param string $sourceSnapshotId Source snapshot identifier
|
1199 |
+
* @param string $destinationLeaseId Destination lease identifier
|
1200 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd894037.aspx for more information.
|
1201 |
+
* @return object Partial blob properties
|
1202 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1203 |
+
*/
|
1204 |
+
public function copyBlob($sourceContainerName = '', $sourceBlobName = '', $destinationContainerName = '', $destinationBlobName = '', $metadata = array(), $sourceSnapshotId = null, $destinationLeaseId = null, $additionalHeaders = array())
|
1205 |
+
{
|
1206 |
+
if ($sourceContainerName === '') {
|
1207 |
+
throw new Microsoft_WindowsAzure_Exception('Source container name is not specified.');
|
1208 |
+
}
|
1209 |
+
if (!self::isValidContainerName($sourceContainerName)) {
|
1210 |
+
throw new Microsoft_WindowsAzure_Exception('Source container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1211 |
+
}
|
1212 |
+
if ($sourceBlobName === '') {
|
1213 |
+
throw new Microsoft_WindowsAzure_Exception('Source blob name is not specified.');
|
1214 |
+
}
|
1215 |
+
if ($destinationContainerName === '') {
|
1216 |
+
throw new Microsoft_WindowsAzure_Exception('Destination container name is not specified.');
|
1217 |
+
}
|
1218 |
+
if (!self::isValidContainerName($destinationContainerName)) {
|
1219 |
+
throw new Microsoft_WindowsAzure_Exception('Destination container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1220 |
+
}
|
1221 |
+
if ($destinationBlobName === '') {
|
1222 |
+
throw new Microsoft_WindowsAzure_Exception('Destination blob name is not specified.');
|
1223 |
+
}
|
1224 |
+
if ($sourceContainerName === '$root' && strpos($sourceBlobName, '/') !== false) {
|
1225 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1226 |
+
}
|
1227 |
+
if ($destinationContainerName === '$root' && strpos($destinationBlobName, '/') !== false) {
|
1228 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1229 |
+
}
|
1230 |
+
|
1231 |
+
// Create metadata headers
|
1232 |
+
$headers = array();
|
1233 |
+
if (!is_null($destinationLeaseId)) {
|
1234 |
+
$headers['x-ms-lease-id'] = $destinationLeaseId;
|
1235 |
+
}
|
1236 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
1237 |
+
|
1238 |
+
// Additional headers?
|
1239 |
+
foreach ($additionalHeaders as $key => $value) {
|
1240 |
+
$headers[$key] = $value;
|
1241 |
+
}
|
1242 |
+
|
1243 |
+
// Resource names
|
1244 |
+
$sourceResourceName = self::createResourceName($sourceContainerName, $sourceBlobName);
|
1245 |
+
if (!is_null($sourceSnapshotId)) {
|
1246 |
+
$sourceResourceName .= '?snapshot=' . $sourceSnapshotId;
|
1247 |
+
}
|
1248 |
+
$destinationResourceName = self::createResourceName($destinationContainerName, $destinationBlobName);
|
1249 |
+
|
1250 |
+
// Set source blob
|
1251 |
+
$headers["x-ms-copy-source"] = '/' . $this->_accountName . '/' . $sourceResourceName;
|
1252 |
+
|
1253 |
+
// Perform request
|
1254 |
+
$response = $this->_performRequest($destinationResourceName, '', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1255 |
+
if ($response->isSuccessful()) {
|
1256 |
+
return new Microsoft_WindowsAzure_Storage_BlobInstance(
|
1257 |
+
$destinationContainerName,
|
1258 |
+
$destinationBlobName,
|
1259 |
+
null,
|
1260 |
+
$response->getHeader('Etag'),
|
1261 |
+
$response->getHeader('Last-modified'),
|
1262 |
+
$this->getBaseUrl() . '/' . $destinationContainerName . '/' . $destinationBlobName,
|
1263 |
+
0,
|
1264 |
+
'',
|
1265 |
+
'',
|
1266 |
+
'',
|
1267 |
+
false,
|
1268 |
+
$metadata
|
1269 |
+
);
|
1270 |
+
} else {
|
1271 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1272 |
+
}
|
1273 |
+
}
|
1274 |
+
|
1275 |
+
/**
|
1276 |
+
* Get blob
|
1277 |
+
*
|
1278 |
+
* @param string $containerName Container name
|
1279 |
+
* @param string $blobName Blob name
|
1280 |
+
* @param string $localFileName Local file name to store downloaded blob
|
1281 |
+
* @param string $snapshotId Snapshot identifier
|
1282 |
+
* @param string $leaseId Lease identifier
|
1283 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1284 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1285 |
+
*/
|
1286 |
+
public function getBlob($containerName = '', $blobName = '', $localFileName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
|
1287 |
+
{
|
1288 |
+
if ($containerName === '') {
|
1289 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1290 |
+
}
|
1291 |
+
if (!self::isValidContainerName($containerName)) {
|
1292 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1293 |
+
}
|
1294 |
+
if ($blobName === '') {
|
1295 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1296 |
+
}
|
1297 |
+
if ($localFileName === '') {
|
1298 |
+
throw new Microsoft_WindowsAzure_Exception('Local file name is not specified.');
|
1299 |
+
}
|
1300 |
+
|
1301 |
+
// Fetch data
|
1302 |
+
file_put_contents($localFileName, $this->getBlobData($containerName, $blobName, $snapshotId, $leaseId, $additionalHeaders));
|
1303 |
+
}
|
1304 |
+
|
1305 |
+
/**
|
1306 |
+
* Get blob data
|
1307 |
+
*
|
1308 |
+
* @param string $containerName Container name
|
1309 |
+
* @param string $blobName Blob name
|
1310 |
+
* @param string $snapshotId Snapshot identifier
|
1311 |
+
* @param string $leaseId Lease identifier
|
1312 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1313 |
+
* @return mixed Blob contents
|
1314 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1315 |
+
*/
|
1316 |
+
public function getBlobData($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
|
1317 |
+
{
|
1318 |
+
if ($containerName === '') {
|
1319 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1320 |
+
}
|
1321 |
+
if (!self::isValidContainerName($containerName)) {
|
1322 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1323 |
+
}
|
1324 |
+
if ($blobName === '') {
|
1325 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1326 |
+
}
|
1327 |
+
|
1328 |
+
// Build query string
|
1329 |
+
$queryString = array();
|
1330 |
+
if (!is_null($snapshotId)) {
|
1331 |
+
$queryString[] = 'snapshot=' . $snapshotId;
|
1332 |
+
}
|
1333 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
1334 |
+
|
1335 |
+
// Additional headers?
|
1336 |
+
$headers = array();
|
1337 |
+
if (!is_null($leaseId)) {
|
1338 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1339 |
+
}
|
1340 |
+
foreach ($additionalHeaders as $key => $value) {
|
1341 |
+
$headers[$key] = $value;
|
1342 |
+
}
|
1343 |
+
|
1344 |
+
// Resource name
|
1345 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1346 |
+
|
1347 |
+
// Perform request
|
1348 |
+
$response = $this->_performRequest($resourceName, $queryString, Microsoft_Http_Client::GET, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
|
1349 |
+
if ($response->isSuccessful()) {
|
1350 |
+
return $response->getBody();
|
1351 |
+
} else {
|
1352 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1353 |
+
}
|
1354 |
+
}
|
1355 |
+
|
1356 |
+
/**
|
1357 |
+
* Get blob instance
|
1358 |
+
*
|
1359 |
+
* @param string $containerName Container name
|
1360 |
+
* @param string $blobName Blob name
|
1361 |
+
* @param string $snapshotId Snapshot identifier
|
1362 |
+
* @param string $leaseId Lease identifier
|
1363 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1364 |
+
* @return Microsoft_WindowsAzure_Storage_BlobInstance
|
1365 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1366 |
+
*/
|
1367 |
+
public function getBlobInstance($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
|
1368 |
+
{
|
1369 |
+
if ($containerName === '') {
|
1370 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1371 |
+
}
|
1372 |
+
if (!self::isValidContainerName($containerName)) {
|
1373 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1374 |
+
}
|
1375 |
+
if ($blobName === '') {
|
1376 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1377 |
+
}
|
1378 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1379 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1380 |
+
}
|
1381 |
+
|
1382 |
+
// Build query string
|
1383 |
+
$queryString = array();
|
1384 |
+
if (!is_null($snapshotId)) {
|
1385 |
+
$queryString[] = 'snapshot=' . $snapshotId;
|
1386 |
+
}
|
1387 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
1388 |
+
|
1389 |
+
// Additional headers?
|
1390 |
+
$headers = array();
|
1391 |
+
if (!is_null($leaseId)) {
|
1392 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1393 |
+
}
|
1394 |
+
foreach ($additionalHeaders as $key => $value) {
|
1395 |
+
$headers[$key] = $value;
|
1396 |
+
}
|
1397 |
+
|
1398 |
+
// Resource name
|
1399 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1400 |
+
|
1401 |
+
// Perform request
|
1402 |
+
$response = $this->_performRequest($resourceName, $queryString, Microsoft_Http_Client::HEAD, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ);
|
1403 |
+
if ($response->isSuccessful()) {
|
1404 |
+
// Parse metadata
|
1405 |
+
$metadata = $this->_parseMetadataHeaders($response->getHeaders());
|
1406 |
+
|
1407 |
+
// Return blob
|
1408 |
+
return new Microsoft_WindowsAzure_Storage_BlobInstance(
|
1409 |
+
$containerName,
|
1410 |
+
$blobName,
|
1411 |
+
$snapshotId,
|
1412 |
+
$response->getHeader('Etag'),
|
1413 |
+
$response->getHeader('Last-modified'),
|
1414 |
+
$this->getBaseUrl() . '/' . $containerName . '/' . $blobName,
|
1415 |
+
$response->getHeader('Content-Length'),
|
1416 |
+
$response->getHeader('Content-Type'),
|
1417 |
+
$response->getHeader('Content-Encoding'),
|
1418 |
+
$response->getHeader('Content-Language'),
|
1419 |
+
$response->getHeader('Cache-Control'),
|
1420 |
+
$response->getHeader('x-ms-blob-type'),
|
1421 |
+
$response->getHeader('x-ms-lease-status'),
|
1422 |
+
false,
|
1423 |
+
$metadata
|
1424 |
+
);
|
1425 |
+
} else {
|
1426 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1427 |
+
}
|
1428 |
+
}
|
1429 |
+
|
1430 |
+
/**
|
1431 |
+
* Get blob metadata
|
1432 |
+
*
|
1433 |
+
* @param string $containerName Container name
|
1434 |
+
* @param string $blobName Blob name
|
1435 |
+
* @param string $snapshotId Snapshot identifier
|
1436 |
+
* @param string $leaseId Lease identifier
|
1437 |
+
* @return array Key/value pairs of meta data
|
1438 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1439 |
+
*/
|
1440 |
+
public function getBlobMetadata($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
|
1441 |
+
{
|
1442 |
+
if ($containerName === '') {
|
1443 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1444 |
+
}
|
1445 |
+
if (!self::isValidContainerName($containerName)) {
|
1446 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1447 |
+
}
|
1448 |
+
if ($blobName === '') {
|
1449 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1450 |
+
}
|
1451 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1452 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1453 |
+
}
|
1454 |
+
|
1455 |
+
return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId)->Metadata;
|
1456 |
+
}
|
1457 |
+
|
1458 |
+
/**
|
1459 |
+
* Set blob metadata
|
1460 |
+
*
|
1461 |
+
* Calling the Set Blob Metadata operation overwrites all existing metadata that is associated with the blob. It's not possible to modify an individual name/value pair.
|
1462 |
+
*
|
1463 |
+
* @param string $containerName Container name
|
1464 |
+
* @param string $blobName Blob name
|
1465 |
+
* @param array $metadata Key/value pairs of meta data
|
1466 |
+
* @param string $leaseId Lease identifier
|
1467 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1468 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1469 |
+
*/
|
1470 |
+
public function setBlobMetadata($containerName = '', $blobName = '', $metadata = array(), $leaseId = null, $additionalHeaders = array())
|
1471 |
+
{
|
1472 |
+
if ($containerName === '') {
|
1473 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1474 |
+
}
|
1475 |
+
if (!self::isValidContainerName($containerName)) {
|
1476 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1477 |
+
}
|
1478 |
+
if ($blobName === '') {
|
1479 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1480 |
+
}
|
1481 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1482 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1483 |
+
}
|
1484 |
+
if (count($metadata) == 0) {
|
1485 |
+
return;
|
1486 |
+
}
|
1487 |
+
|
1488 |
+
// Create metadata headers
|
1489 |
+
$headers = array();
|
1490 |
+
if (!is_null($leaseId)) {
|
1491 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1492 |
+
}
|
1493 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
1494 |
+
|
1495 |
+
// Additional headers?
|
1496 |
+
foreach ($additionalHeaders as $key => $value) {
|
1497 |
+
$headers[$key] = $value;
|
1498 |
+
}
|
1499 |
+
|
1500 |
+
// Perform request
|
1501 |
+
$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=metadata', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1502 |
+
if (!$response->isSuccessful()) {
|
1503 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1504 |
+
}
|
1505 |
+
}
|
1506 |
+
|
1507 |
+
/**
|
1508 |
+
* Set blob properties
|
1509 |
+
*
|
1510 |
+
* All available properties are listed at http://msdn.microsoft.com/en-us/library/ee691966.aspx and should be provided in the $additionalHeaders parameter.
|
1511 |
+
*
|
1512 |
+
* @param string $containerName Container name
|
1513 |
+
* @param string $blobName Blob name
|
1514 |
+
* @param string $leaseId Lease identifier
|
1515 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1516 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1517 |
+
*/
|
1518 |
+
public function setBlobProperties($containerName = '', $blobName = '', $leaseId = null, $additionalHeaders = array())
|
1519 |
+
{
|
1520 |
+
if ($containerName === '') {
|
1521 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1522 |
+
}
|
1523 |
+
if (!self::isValidContainerName($containerName)) {
|
1524 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1525 |
+
}
|
1526 |
+
if ($blobName === '') {
|
1527 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1528 |
+
}
|
1529 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1530 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1531 |
+
}
|
1532 |
+
if (count($additionalHeaders) == 0) {
|
1533 |
+
throw new Microsoft_WindowsAzure_Exception('No additional headers are specified.');
|
1534 |
+
}
|
1535 |
+
|
1536 |
+
// Create headers
|
1537 |
+
$headers = array();
|
1538 |
+
|
1539 |
+
// Lease set?
|
1540 |
+
if (!is_null($leaseId)) {
|
1541 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1542 |
+
}
|
1543 |
+
|
1544 |
+
// Additional headers?
|
1545 |
+
foreach ($additionalHeaders as $key => $value) {
|
1546 |
+
$headers[$key] = $value;
|
1547 |
+
}
|
1548 |
+
|
1549 |
+
// Perform request
|
1550 |
+
$response = $this->_performRequest($containerName . '/' . $blobName, '?comp=properties', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1551 |
+
if (!$response->isSuccessful()) {
|
1552 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1553 |
+
}
|
1554 |
+
}
|
1555 |
+
|
1556 |
+
/**
|
1557 |
+
* Get blob properties
|
1558 |
+
*
|
1559 |
+
* @param string $containerName Container name
|
1560 |
+
* @param string $blobName Blob name
|
1561 |
+
* @param string $snapshotId Snapshot identifier
|
1562 |
+
* @param string $leaseId Lease identifier
|
1563 |
+
* @return Microsoft_WindowsAzure_Storage_BlobInstance
|
1564 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1565 |
+
*/
|
1566 |
+
public function getBlobProperties($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null)
|
1567 |
+
{
|
1568 |
+
if ($containerName === '') {
|
1569 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1570 |
+
}
|
1571 |
+
if (!self::isValidContainerName($containerName)) {
|
1572 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1573 |
+
}
|
1574 |
+
if ($blobName === '') {
|
1575 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1576 |
+
}
|
1577 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1578 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1579 |
+
}
|
1580 |
+
|
1581 |
+
return $this->getBlobInstance($containerName, $blobName, $snapshotId, $leaseId);
|
1582 |
+
}
|
1583 |
+
|
1584 |
+
/**
|
1585 |
+
* Delete blob
|
1586 |
+
*
|
1587 |
+
* @param string $containerName Container name
|
1588 |
+
* @param string $blobName Blob name
|
1589 |
+
* @param string $snapshotId Snapshot identifier
|
1590 |
+
* @param string $leaseId Lease identifier
|
1591 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1592 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1593 |
+
*/
|
1594 |
+
public function deleteBlob($containerName = '', $blobName = '', $snapshotId = null, $leaseId = null, $additionalHeaders = array())
|
1595 |
+
{
|
1596 |
+
if ($containerName === '') {
|
1597 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1598 |
+
}
|
1599 |
+
if (!self::isValidContainerName($containerName)) {
|
1600 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1601 |
+
}
|
1602 |
+
if ($blobName === '') {
|
1603 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1604 |
+
}
|
1605 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1606 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1607 |
+
}
|
1608 |
+
|
1609 |
+
// Build query string
|
1610 |
+
$queryString = array();
|
1611 |
+
if (!is_null($snapshotId)) {
|
1612 |
+
$queryString[] = 'snapshot=' . $snapshotId;
|
1613 |
+
}
|
1614 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
1615 |
+
|
1616 |
+
// Additional headers?
|
1617 |
+
$headers = array();
|
1618 |
+
if (!is_null($leaseId)) {
|
1619 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1620 |
+
}
|
1621 |
+
foreach ($additionalHeaders as $key => $value) {
|
1622 |
+
$headers[$key] = $value;
|
1623 |
+
}
|
1624 |
+
|
1625 |
+
// Resource name
|
1626 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1627 |
+
|
1628 |
+
// Perform request
|
1629 |
+
$response = $this->_performRequest($resourceName, $queryString, Microsoft_Http_Client::DELETE, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1630 |
+
if (!$response->isSuccessful()) {
|
1631 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1632 |
+
}
|
1633 |
+
}
|
1634 |
+
|
1635 |
+
/**
|
1636 |
+
* Snapshot blob
|
1637 |
+
*
|
1638 |
+
* @param string $containerName Container name
|
1639 |
+
* @param string $blobName Blob name
|
1640 |
+
* @param array $metadata Key/value pairs of meta data
|
1641 |
+
* @param array $additionalHeaders Additional headers. See http://msdn.microsoft.com/en-us/library/dd179371.aspx for more information.
|
1642 |
+
* @return string Date/Time value representing the snapshot identifier.
|
1643 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1644 |
+
*/
|
1645 |
+
public function snapshotBlob($containerName = '', $blobName = '', $metadata = array(), $additionalHeaders = array())
|
1646 |
+
{
|
1647 |
+
if ($containerName === '') {
|
1648 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1649 |
+
}
|
1650 |
+
if (!self::isValidContainerName($containerName)) {
|
1651 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1652 |
+
}
|
1653 |
+
if ($blobName === '') {
|
1654 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1655 |
+
}
|
1656 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1657 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1658 |
+
}
|
1659 |
+
|
1660 |
+
// Additional headers?
|
1661 |
+
$headers = array();
|
1662 |
+
foreach ($additionalHeaders as $key => $value) {
|
1663 |
+
$headers[$key] = $value;
|
1664 |
+
}
|
1665 |
+
|
1666 |
+
// Resource name
|
1667 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1668 |
+
|
1669 |
+
// Perform request
|
1670 |
+
$response = $this->_performRequest($resourceName, '?comp=snapshot', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1671 |
+
if ($response->isSuccessful()) {
|
1672 |
+
return $response->getHeader('x-ms-snapshot');
|
1673 |
+
} else {
|
1674 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1675 |
+
}
|
1676 |
+
}
|
1677 |
+
|
1678 |
+
/**
|
1679 |
+
* Lease blob - See (http://msdn.microsoft.com/en-us/library/ee691972.aspx)
|
1680 |
+
*
|
1681 |
+
* @param string $containerName Container name
|
1682 |
+
* @param string $blobName Blob name
|
1683 |
+
* @param string $leaseAction Lease action (Microsoft_WindowsAzure_Storage_Blob::LEASE_*)
|
1684 |
+
* @param string $leaseId Lease identifier, required to renew the lease or to release the lease.
|
1685 |
+
* @return Microsoft_WindowsAzure_Storage_LeaseInstance Lease instance
|
1686 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1687 |
+
*/
|
1688 |
+
public function leaseBlob($containerName = '', $blobName = '', $leaseAction = self::LEASE_ACQUIRE, $leaseId = null)
|
1689 |
+
{
|
1690 |
+
if ($containerName === '') {
|
1691 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1692 |
+
}
|
1693 |
+
if (!self::isValidContainerName($containerName)) {
|
1694 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1695 |
+
}
|
1696 |
+
if ($blobName === '') {
|
1697 |
+
throw new Microsoft_WindowsAzure_Exception('Blob name is not specified.');
|
1698 |
+
}
|
1699 |
+
if ($containerName === '$root' && strpos($blobName, '/') !== false) {
|
1700 |
+
throw new Microsoft_WindowsAzure_Exception('Blobs stored in the root container can not have a name containing a forward slash (/).');
|
1701 |
+
}
|
1702 |
+
|
1703 |
+
// Additional headers?
|
1704 |
+
$headers = array();
|
1705 |
+
$headers['x-ms-lease-action'] = strtolower($leaseAction);
|
1706 |
+
if (!is_null($leaseId)) {
|
1707 |
+
$headers['x-ms-lease-id'] = $leaseId;
|
1708 |
+
}
|
1709 |
+
|
1710 |
+
// Resource name
|
1711 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1712 |
+
|
1713 |
+
// Perform request
|
1714 |
+
$response = $this->_performRequest($resourceName, '?comp=lease', Microsoft_Http_Client::PUT, $headers, false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_WRITE);
|
1715 |
+
if ($response->isSuccessful()) {
|
1716 |
+
return new Microsoft_WindowsAzure_Storage_LeaseInstance(
|
1717 |
+
$containerName,
|
1718 |
+
$blobName,
|
1719 |
+
$response->getHeader('x-ms-lease-id'),
|
1720 |
+
$response->getHeader('x-ms-lease-time'));
|
1721 |
+
} else {
|
1722 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1723 |
+
}
|
1724 |
+
}
|
1725 |
+
|
1726 |
+
/**
|
1727 |
+
* List blobs
|
1728 |
+
*
|
1729 |
+
* @param string $containerName Container name
|
1730 |
+
* @param string $prefix Optional. Filters the results to return only blobs whose name begins with the specified prefix.
|
1731 |
+
* @param string $delimiter Optional. Delimiter, i.e. '/', for specifying folder hierarchy
|
1732 |
+
* @param int $maxResults Optional. Specifies the maximum number of blobs to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
|
1733 |
+
* @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
|
1734 |
+
* @param string $include Optional. Specifies that the response should include one or more of the following subsets: '', 'metadata', 'snapshots', 'uncommittedblobs'). Multiple values can be added separated with a comma (,)
|
1735 |
+
* @param int $currentResultCount Current result count (internal use)
|
1736 |
+
* @return array
|
1737 |
+
* @throws Microsoft_WindowsAzure_Exception
|
1738 |
+
*/
|
1739 |
+
public function listBlobs($containerName = '', $prefix = '', $delimiter = '', $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
|
1740 |
+
{
|
1741 |
+
if ($containerName === '') {
|
1742 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1743 |
+
}
|
1744 |
+
if (!self::isValidContainerName($containerName)) {
|
1745 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1746 |
+
}
|
1747 |
+
|
1748 |
+
// Build query string
|
1749 |
+
$queryString = array('restype=container', 'comp=list');
|
1750 |
+
if (!is_null($prefix)) {
|
1751 |
+
$queryString[] = 'prefix=' . $prefix;
|
1752 |
+
}
|
1753 |
+
if ($delimiter !== '') {
|
1754 |
+
$queryString[] = 'delimiter=' . $delimiter;
|
1755 |
+
}
|
1756 |
+
if (!is_null($maxResults)) {
|
1757 |
+
$queryString[] = 'maxresults=' . $maxResults;
|
1758 |
+
}
|
1759 |
+
if (!is_null($marker)) {
|
1760 |
+
$queryString[] = 'marker=' . $marker;
|
1761 |
+
}
|
1762 |
+
if (!is_null($include)) {
|
1763 |
+
$queryString[] = 'include=' . $include;
|
1764 |
+
}
|
1765 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
1766 |
+
|
1767 |
+
// Perform request
|
1768 |
+
$response = $this->_performRequest($containerName, $queryString, Microsoft_Http_Client::GET, array(), false, null, Microsoft_WindowsAzure_Storage::RESOURCE_BLOB, Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_LIST);
|
1769 |
+
if ($response->isSuccessful()) {
|
1770 |
+
// Return value
|
1771 |
+
$blobs = array();
|
1772 |
+
|
1773 |
+
// Blobs
|
1774 |
+
$xmlBlobs = $this->_parseResponse($response)->Blobs->Blob;
|
1775 |
+
if (!is_null($xmlBlobs)) {
|
1776 |
+
for ($i = 0; $i < count($xmlBlobs); $i++) {
|
1777 |
+
$properties = (array)$xmlBlobs[$i]->Properties;
|
1778 |
+
|
1779 |
+
$blobs[] = new Microsoft_WindowsAzure_Storage_BlobInstance(
|
1780 |
+
$containerName,
|
1781 |
+
(string)$xmlBlobs[$i]->Name,
|
1782 |
+
(string)$xmlBlobs[$i]->Snapshot,
|
1783 |
+
(string)$properties['Etag'],
|
1784 |
+
(string)$properties['Last-Modified'],
|
1785 |
+
(string)$xmlBlobs[$i]->Url,
|
1786 |
+
(string)$properties['Content-Length'],
|
1787 |
+
(string)$properties['Content-Type'],
|
1788 |
+
(string)$properties['Content-Encoding'],
|
1789 |
+
(string)$properties['Content-Language'],
|
1790 |
+
(string)$properties['Cache-Control'],
|
1791 |
+
(string)$properties['BlobType'],
|
1792 |
+
(string)$properties['LeaseStatus'],
|
1793 |
+
false,
|
1794 |
+
$this->_parseMetadataElement($xmlBlobs[$i])
|
1795 |
+
);
|
1796 |
+
}
|
1797 |
+
}
|
1798 |
+
|
1799 |
+
// Blob prefixes (folders)
|
1800 |
+
$xmlBlobs = $this->_parseResponse($response)->Blobs->BlobPrefix;
|
1801 |
+
|
1802 |
+
if (!is_null($xmlBlobs)) {
|
1803 |
+
for ($i = 0; $i < count($xmlBlobs); $i++) {
|
1804 |
+
$blobs[] = new Microsoft_WindowsAzure_Storage_BlobInstance(
|
1805 |
+
$containerName,
|
1806 |
+
(string)$xmlBlobs[$i]->Name,
|
1807 |
+
null,
|
1808 |
+
'',
|
1809 |
+
'',
|
1810 |
+
'',
|
1811 |
+
0,
|
1812 |
+
'',
|
1813 |
+
'',
|
1814 |
+
'',
|
1815 |
+
'',
|
1816 |
+
'',
|
1817 |
+
'',
|
1818 |
+
true,
|
1819 |
+
$this->_parseMetadataElement($xmlBlobs[$i])
|
1820 |
+
);
|
1821 |
+
}
|
1822 |
+
}
|
1823 |
+
|
1824 |
+
// More blobs?
|
1825 |
+
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
|
1826 |
+
$currentResultCount = $currentResultCount + count($blobs);
|
1827 |
+
if (!is_null($maxResults) && $currentResultCount < $maxResults) {
|
1828 |
+
if (!is_null($xmlMarker) && $xmlMarker != '') {
|
1829 |
+
$blobs = array_merge($blobs, $this->listBlobs($containerName, $prefix, $delimiter, $maxResults, $marker, $include, $currentResultCount));
|
1830 |
+
}
|
1831 |
+
}
|
1832 |
+
if (!is_null($maxResults) && count($blobs) > $maxResults) {
|
1833 |
+
$blobs = array_slice($blobs, 0, $maxResults);
|
1834 |
+
}
|
1835 |
+
|
1836 |
+
return $blobs;
|
1837 |
+
} else {
|
1838 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
1839 |
+
}
|
1840 |
+
}
|
1841 |
+
|
1842 |
+
/**
|
1843 |
+
* Generate shared access URL
|
1844 |
+
*
|
1845 |
+
* @param string $containerName Container name
|
1846 |
+
* @param string $blobName Blob name
|
1847 |
+
* @param string $resource Signed resource - container (c) - blob (b)
|
1848 |
+
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
|
1849 |
+
* @param string $start The time at which the Shared Access Signature becomes valid.
|
1850 |
+
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
|
1851 |
+
* @param string $identifier Signed identifier
|
1852 |
+
* @return string
|
1853 |
+
*/
|
1854 |
+
public function generateSharedAccessUrl($containerName = '', $blobName = '', $resource = 'b', $permissions = 'r', $start = '', $expiry = '', $identifier = '')
|
1855 |
+
{
|
1856 |
+
if ($containerName === '') {
|
1857 |
+
throw new Microsoft_WindowsAzure_Exception('Container name is not specified.');
|
1858 |
+
}
|
1859 |
+
if (!self::isValidContainerName($containerName)) {
|
1860 |
+
throw new Microsoft_WindowsAzure_Exception('Container name does not adhere to container naming conventions. See http://msdn.microsoft.com/en-us/library/dd135715.aspx for more information.');
|
1861 |
+
}
|
1862 |
+
|
1863 |
+
// Resource name
|
1864 |
+
$resourceName = self::createResourceName($containerName , $blobName);
|
1865 |
+
|
1866 |
+
// Generate URL
|
1867 |
+
return $this->getBaseUrl() . '/' . $resourceName . '?' .
|
1868 |
+
$this->_sharedAccessSignatureCredentials->createSignedQueryString(
|
1869 |
+
$resourceName,
|
1870 |
+
'',
|
1871 |
+
$resource,
|
1872 |
+
$permissions,
|
1873 |
+
$start,
|
1874 |
+
$expiry,
|
1875 |
+
$identifier);
|
1876 |
+
}
|
1877 |
+
|
1878 |
+
/**
|
1879 |
+
* Register this object as stream wrapper client
|
1880 |
+
*
|
1881 |
+
* @param string $name Protocol name
|
1882 |
+
* @return Microsoft_WindowsAzure_Storage_Blob
|
1883 |
+
*/
|
1884 |
+
public function registerAsClient($name)
|
1885 |
+
{
|
1886 |
+
self::$_wrapperClients[$name] = $this;
|
1887 |
+
return $this;
|
1888 |
+
}
|
1889 |
+
|
1890 |
+
/**
|
1891 |
+
* Unregister this object as stream wrapper client
|
1892 |
+
*
|
1893 |
+
* @param string $name Protocol name
|
1894 |
+
* @return Microsoft_WindowsAzure_Storage_Blob
|
1895 |
+
*/
|
1896 |
+
public function unregisterAsClient($name)
|
1897 |
+
{
|
1898 |
+
unset(self::$_wrapperClients[$name]);
|
1899 |
+
return $this;
|
1900 |
+
}
|
1901 |
+
|
1902 |
+
/**
|
1903 |
+
* Get wrapper client for stream type
|
1904 |
+
*
|
1905 |
+
* @param string $name Protocol name
|
1906 |
+
* @return Microsoft_WindowsAzure_Storage_Blob
|
1907 |
+
*/
|
1908 |
+
public static function getWrapperClient($name)
|
1909 |
+
{
|
1910 |
+
return self::$_wrapperClients[$name];
|
1911 |
+
}
|
1912 |
+
|
1913 |
+
/**
|
1914 |
+
* Register this object as stream wrapper
|
1915 |
+
*
|
1916 |
+
* @param string $name Protocol name
|
1917 |
+
*/
|
1918 |
+
public function registerStreamWrapper($name = 'azure')
|
1919 |
+
{
|
1920 |
+
/**
|
1921 |
+
* @see Microsoft_WindowsAzure_Storage_Blob_Stream
|
1922 |
+
*/
|
1923 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob/Stream.php';
|
1924 |
+
|
1925 |
+
stream_register_wrapper($name, 'Microsoft_WindowsAzure_Storage_Blob_Stream');
|
1926 |
+
$this->registerAsClient($name);
|
1927 |
+
}
|
1928 |
+
|
1929 |
+
/**
|
1930 |
+
* Unregister this object as stream wrapper
|
1931 |
+
*
|
1932 |
+
* @param string $name Protocol name
|
1933 |
+
* @return Microsoft_WindowsAzure_Storage_Blob
|
1934 |
+
*/
|
1935 |
+
public function unregisterStreamWrapper($name = 'azure')
|
1936 |
+
{
|
1937 |
+
stream_wrapper_unregister($name);
|
1938 |
+
$this->unregisterAsClient($name);
|
1939 |
+
}
|
1940 |
+
|
1941 |
+
/**
|
1942 |
+
* Create resource name
|
1943 |
+
*
|
1944 |
+
* @param string $containerName Container name
|
1945 |
+
* @param string $blobName Blob name
|
1946 |
+
* @return string
|
1947 |
+
*/
|
1948 |
+
public static function createResourceName($containerName = '', $blobName = '')
|
1949 |
+
{
|
1950 |
+
// Resource name
|
1951 |
+
$resourceName = $containerName . '/' . $blobName;
|
1952 |
+
if ($containerName === '' || $containerName === '$root') {
|
1953 |
+
$resourceName = $blobName;
|
1954 |
+
}
|
1955 |
+
if ($blobName === '') {
|
1956 |
+
$resourceName = $containerName;
|
1957 |
+
}
|
1958 |
+
|
1959 |
+
return $resourceName;
|
1960 |
+
}
|
1961 |
+
|
1962 |
+
/**
|
1963 |
+
* Is valid container name?
|
1964 |
+
*
|
1965 |
+
* @param string $containerName Container name
|
1966 |
+
* @return boolean
|
1967 |
+
*/
|
1968 |
+
public static function isValidContainerName($containerName = '')
|
1969 |
+
{
|
1970 |
+
if ($containerName == '$root') {
|
1971 |
+
return true;
|
1972 |
+
}
|
1973 |
+
|
1974 |
+
if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $containerName) === 0) {
|
1975 |
+
return false;
|
1976 |
+
}
|
1977 |
+
|
1978 |
+
if (strpos($containerName, '--') !== false) {
|
1979 |
+
return false;
|
1980 |
+
}
|
1981 |
+
|
1982 |
+
if (strtolower($containerName) != $containerName) {
|
1983 |
+
return false;
|
1984 |
+
}
|
1985 |
+
|
1986 |
+
if (strlen($containerName) < 3 || strlen($containerName) > 63) {
|
1987 |
+
return false;
|
1988 |
+
}
|
1989 |
+
|
1990 |
+
if (substr($containerName, -1) == '-') {
|
1991 |
+
return false;
|
1992 |
+
}
|
1993 |
+
|
1994 |
+
return true;
|
1995 |
+
}
|
1996 |
+
|
1997 |
+
/**
|
1998 |
+
* Get error message from Microsoft_Http_Response
|
1999 |
+
*
|
2000 |
+
* @param Microsoft_Http_Response $response Repsonse
|
2001 |
+
* @param string $alternativeError Alternative error message
|
2002 |
+
* @return string
|
2003 |
+
*/
|
2004 |
+
protected function _getErrorMessage(Microsoft_Http_Response $response, $alternativeError = 'Unknown error.')
|
2005 |
+
{
|
2006 |
+
$response = $this->_parseResponse($response);
|
2007 |
+
if ($response && $response->Message) {
|
2008 |
+
return (string)$response->Message;
|
2009 |
+
} else {
|
2010 |
+
return $alternativeError;
|
2011 |
+
}
|
2012 |
+
}
|
2013 |
+
|
2014 |
+
/**
|
2015 |
+
* Generate block id
|
2016 |
+
*
|
2017 |
+
* @param int $part Block number
|
2018 |
+
* @return string Windows Azure Blob Storage block number
|
2019 |
+
*/
|
2020 |
+
protected function _generateBlockId($part = 0)
|
2021 |
+
{
|
2022 |
+
$returnValue = $part;
|
2023 |
+
while (strlen($returnValue) < 64) {
|
2024 |
+
$returnValue = '0' . $returnValue;
|
2025 |
+
}
|
2026 |
+
|
2027 |
+
return $returnValue;
|
2028 |
+
}
|
2029 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/Blob/Stream.php
ADDED
@@ -0,0 +1,578 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure_Storage
|
30 |
+
* @subpackage Blob
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://todo name_todo
|
33 |
+
* @version $Id: Blob.php 24511 2009-07-28 09:17:56Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Storage_Blob
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Exception
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
45 |
+
|
46 |
+
|
47 |
+
/**
|
48 |
+
* @category Microsoft
|
49 |
+
* @package Microsoft_WindowsAzure_Storage
|
50 |
+
* @subpackage Blob
|
51 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
52 |
+
* @license http://phpazure.codeplex.com/license
|
53 |
+
*/
|
54 |
+
class Microsoft_WindowsAzure_Storage_Blob_Stream
|
55 |
+
{
|
56 |
+
/**
|
57 |
+
* Current file name
|
58 |
+
*
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
private $_fileName = null;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Temporary file name
|
65 |
+
*
|
66 |
+
* @var string
|
67 |
+
*/
|
68 |
+
private $_temporaryFileName = null;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Temporary file handle
|
72 |
+
*
|
73 |
+
* @var resource
|
74 |
+
*/
|
75 |
+
private $_temporaryFileHandle = null;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Blob storage client
|
79 |
+
*
|
80 |
+
* @var Microsoft_WindowsAzure_Storage_Blob
|
81 |
+
*/
|
82 |
+
private $_storageClient = null;
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Write mode?
|
86 |
+
*
|
87 |
+
* @var boolean
|
88 |
+
*/
|
89 |
+
private $_writeMode = false;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* List of blobs
|
93 |
+
*
|
94 |
+
* @var array
|
95 |
+
*/
|
96 |
+
private $_blobs = null;
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Retrieve storage client for this stream type
|
100 |
+
*
|
101 |
+
* @param string $path
|
102 |
+
* @return Microsoft_WindowsAzure_Storage_Blob
|
103 |
+
*/
|
104 |
+
protected function _getStorageClient($path = '')
|
105 |
+
{
|
106 |
+
if (is_null($this->_storageClient)) {
|
107 |
+
$url = explode(':', $path);
|
108 |
+
if (!$url) {
|
109 |
+
throw new Microsoft_WindowsAzure_Exception('Could not parse path "' . $path . '".');
|
110 |
+
}
|
111 |
+
|
112 |
+
$this->_storageClient = Microsoft_WindowsAzure_Storage_Blob::getWrapperClient($url[0]);
|
113 |
+
if (!$this->_storageClient) {
|
114 |
+
throw new Microsoft_WindowsAzure_Exception('No storage client registered for stream type "' . $url[0] . '://".');
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
return $this->_storageClient;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Extract container name
|
123 |
+
*
|
124 |
+
* @param string $path
|
125 |
+
* @return string
|
126 |
+
*/
|
127 |
+
protected function _getContainerName($path)
|
128 |
+
{
|
129 |
+
$url = parse_url($path);
|
130 |
+
if ($url['host']) {
|
131 |
+
return $url['host'];
|
132 |
+
}
|
133 |
+
|
134 |
+
return '';
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Extract file name
|
139 |
+
*
|
140 |
+
* @param string $path
|
141 |
+
* @return string
|
142 |
+
*/
|
143 |
+
protected function _getFileName($path)
|
144 |
+
{
|
145 |
+
$url = parse_url($path);
|
146 |
+
if ($url['host']) {
|
147 |
+
$fileName = isset($url['path']) ? $url['path'] : $url['host'];
|
148 |
+
if (strpos($fileName, '/') === 0) {
|
149 |
+
$fileName = substr($fileName, 1);
|
150 |
+
}
|
151 |
+
return $fileName;
|
152 |
+
}
|
153 |
+
|
154 |
+
return '';
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Open the stream
|
159 |
+
*
|
160 |
+
* @param string $path
|
161 |
+
* @param string $mode
|
162 |
+
* @param integer $options
|
163 |
+
* @param string $opened_path
|
164 |
+
* @return boolean
|
165 |
+
*/
|
166 |
+
public function stream_open($path, $mode, $options, $opened_path)
|
167 |
+
{
|
168 |
+
$this->_fileName = $path;
|
169 |
+
$this->_temporaryFileName = tempnam(sys_get_temp_dir(), 'azure');
|
170 |
+
|
171 |
+
// Check the file can be opened
|
172 |
+
$fh = @fopen($this->_temporaryFileName, $mode);
|
173 |
+
if ($fh === false) {
|
174 |
+
return false;
|
175 |
+
}
|
176 |
+
fclose($fh);
|
177 |
+
|
178 |
+
// Write mode?
|
179 |
+
if (strpbrk($mode, 'wax+')) {
|
180 |
+
$this->_writeMode = true;
|
181 |
+
} else {
|
182 |
+
$this->_writeMode = false;
|
183 |
+
}
|
184 |
+
|
185 |
+
// If read/append, fetch the file
|
186 |
+
if (!$this->_writeMode || strpbrk($mode, 'ra+')) {
|
187 |
+
$this->_getStorageClient($this->_fileName)->getBlob(
|
188 |
+
$this->_getContainerName($this->_fileName),
|
189 |
+
$this->_getFileName($this->_fileName),
|
190 |
+
$this->_temporaryFileName
|
191 |
+
);
|
192 |
+
}
|
193 |
+
|
194 |
+
// Open temporary file handle
|
195 |
+
$this->_temporaryFileHandle = fopen($this->_temporaryFileName, $mode);
|
196 |
+
|
197 |
+
// Ok!
|
198 |
+
return true;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Close the stream
|
203 |
+
*
|
204 |
+
* @return void
|
205 |
+
*/
|
206 |
+
public function stream_close()
|
207 |
+
{
|
208 |
+
@fclose($this->_temporaryFileHandle);
|
209 |
+
|
210 |
+
// Upload the file?
|
211 |
+
if ($this->_writeMode) {
|
212 |
+
// Make sure the container exists
|
213 |
+
$containerExists = $this->_getStorageClient($this->_fileName)->containerExists(
|
214 |
+
$this->_getContainerName($this->_fileName)
|
215 |
+
);
|
216 |
+
if (!$containerExists) {
|
217 |
+
$this->_getStorageClient($this->_fileName)->createContainer(
|
218 |
+
$this->_getContainerName($this->_fileName)
|
219 |
+
);
|
220 |
+
}
|
221 |
+
|
222 |
+
// Upload the file
|
223 |
+
try {
|
224 |
+
$this->_getStorageClient($this->_fileName)->putBlob(
|
225 |
+
$this->_getContainerName($this->_fileName),
|
226 |
+
$this->_getFileName($this->_fileName),
|
227 |
+
$this->_temporaryFileName
|
228 |
+
);
|
229 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
230 |
+
@unlink($this->_temporaryFileName);
|
231 |
+
unset($this->_storageClient);
|
232 |
+
|
233 |
+
throw $ex;
|
234 |
+
}
|
235 |
+
}
|
236 |
+
|
237 |
+
@unlink($this->_temporaryFileName);
|
238 |
+
unset($this->_storageClient);
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Read from the stream
|
243 |
+
*
|
244 |
+
* @param integer $count
|
245 |
+
* @return string
|
246 |
+
*/
|
247 |
+
public function stream_read($count)
|
248 |
+
{
|
249 |
+
if (!$this->_temporaryFileHandle) {
|
250 |
+
return false;
|
251 |
+
}
|
252 |
+
|
253 |
+
return fread($this->_temporaryFileHandle, $count);
|
254 |
+
}
|
255 |
+
|
256 |
+
/**
|
257 |
+
* Write to the stream
|
258 |
+
*
|
259 |
+
* @param string $data
|
260 |
+
* @return integer
|
261 |
+
*/
|
262 |
+
public function stream_write($data)
|
263 |
+
{
|
264 |
+
if (!$this->_temporaryFileHandle) {
|
265 |
+
return 0;
|
266 |
+
}
|
267 |
+
|
268 |
+
$len = strlen($data);
|
269 |
+
fwrite($this->_temporaryFileHandle, $data, $len);
|
270 |
+
return $len;
|
271 |
+
}
|
272 |
+
|
273 |
+
/**
|
274 |
+
* End of the stream?
|
275 |
+
*
|
276 |
+
* @return boolean
|
277 |
+
*/
|
278 |
+
public function stream_eof()
|
279 |
+
{
|
280 |
+
if (!$this->_temporaryFileHandle) {
|
281 |
+
return true;
|
282 |
+
}
|
283 |
+
|
284 |
+
return feof($this->_temporaryFileHandle);
|
285 |
+
}
|
286 |
+
|
287 |
+
/**
|
288 |
+
* What is the current read/write position of the stream?
|
289 |
+
*
|
290 |
+
* @return integer
|
291 |
+
*/
|
292 |
+
public function stream_tell()
|
293 |
+
{
|
294 |
+
return ftell($this->_temporaryFileHandle);
|
295 |
+
}
|
296 |
+
|
297 |
+
/**
|
298 |
+
* Update the read/write position of the stream
|
299 |
+
*
|
300 |
+
* @param integer $offset
|
301 |
+
* @param integer $whence
|
302 |
+
* @return boolean
|
303 |
+
*/
|
304 |
+
public function stream_seek($offset, $whence)
|
305 |
+
{
|
306 |
+
if (!$this->_temporaryFileHandle) {
|
307 |
+
return false;
|
308 |
+
}
|
309 |
+
|
310 |
+
return (fseek($this->_temporaryFileHandle, $offset, $whence) === 0);
|
311 |
+
}
|
312 |
+
|
313 |
+
/**
|
314 |
+
* Flush current cached stream data to storage
|
315 |
+
*
|
316 |
+
* @return boolean
|
317 |
+
*/
|
318 |
+
public function stream_flush()
|
319 |
+
{
|
320 |
+
$result = fflush($this->_temporaryFileHandle);
|
321 |
+
|
322 |
+
// Upload the file?
|
323 |
+
if ($this->_writeMode) {
|
324 |
+
// Make sure the container exists
|
325 |
+
$containerExists = $this->_getStorageClient($this->_fileName)->containerExists(
|
326 |
+
$this->_getContainerName($this->_fileName)
|
327 |
+
);
|
328 |
+
if (!$containerExists) {
|
329 |
+
$this->_getStorageClient($this->_fileName)->createContainer(
|
330 |
+
$this->_getContainerName($this->_fileName)
|
331 |
+
);
|
332 |
+
}
|
333 |
+
|
334 |
+
// Upload the file
|
335 |
+
try {
|
336 |
+
$this->_getStorageClient($this->_fileName)->putBlob(
|
337 |
+
$this->_getContainerName($this->_fileName),
|
338 |
+
$this->_getFileName($this->_fileName),
|
339 |
+
$this->_temporaryFileName
|
340 |
+
);
|
341 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
342 |
+
@unlink($this->_temporaryFileName);
|
343 |
+
unset($this->_storageClient);
|
344 |
+
|
345 |
+
throw $ex;
|
346 |
+
}
|
347 |
+
}
|
348 |
+
|
349 |
+
return $result;
|
350 |
+
}
|
351 |
+
|
352 |
+
/**
|
353 |
+
* Returns data array of stream variables
|
354 |
+
*
|
355 |
+
* @return array
|
356 |
+
*/
|
357 |
+
public function stream_stat()
|
358 |
+
{
|
359 |
+
if (!$this->_temporaryFileHandle) {
|
360 |
+
return false;
|
361 |
+
}
|
362 |
+
|
363 |
+
$stat = array();
|
364 |
+
$stat['dev'] = 0;
|
365 |
+
$stat['ino'] = 0;
|
366 |
+
$stat['mode'] = 0;
|
367 |
+
$stat['nlink'] = 0;
|
368 |
+
$stat['uid'] = 0;
|
369 |
+
$stat['gid'] = 0;
|
370 |
+
$stat['rdev'] = 0;
|
371 |
+
$stat['size'] = 0;
|
372 |
+
$stat['atime'] = 0;
|
373 |
+
$stat['mtime'] = 0;
|
374 |
+
$stat['ctime'] = 0;
|
375 |
+
$stat['blksize'] = 0;
|
376 |
+
$stat['blocks'] = 0;
|
377 |
+
|
378 |
+
$info = null;
|
379 |
+
try {
|
380 |
+
$info = $this->_getStorageClient($this->_fileName)->getBlobInstance(
|
381 |
+
$this->_getContainerName($this->_fileName),
|
382 |
+
$this->_getFileName($this->_fileName)
|
383 |
+
);
|
384 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
385 |
+
// Unexisting file...
|
386 |
+
}
|
387 |
+
if (!is_null($info)) {
|
388 |
+
$stat['size'] = $info->Size;
|
389 |
+
$stat['atime'] = time();
|
390 |
+
}
|
391 |
+
|
392 |
+
return $stat;
|
393 |
+
}
|
394 |
+
|
395 |
+
/**
|
396 |
+
* Attempt to delete the item
|
397 |
+
*
|
398 |
+
* @param string $path
|
399 |
+
* @return boolean
|
400 |
+
*/
|
401 |
+
public function unlink($path)
|
402 |
+
{
|
403 |
+
$this->_getStorageClient($path)->deleteBlob(
|
404 |
+
$this->_getContainerName($path),
|
405 |
+
$this->_getFileName($path)
|
406 |
+
);
|
407 |
+
}
|
408 |
+
|
409 |
+
/**
|
410 |
+
* Attempt to rename the item
|
411 |
+
*
|
412 |
+
* @param string $path_from
|
413 |
+
* @param string $path_to
|
414 |
+
* @return boolean False
|
415 |
+
*/
|
416 |
+
public function rename($path_from, $path_to)
|
417 |
+
{
|
418 |
+
if ($this->_getContainerName($path_from) != $this->_getContainerName($path_to)) {
|
419 |
+
throw new Microsoft_WindowsAzure_Exception('Container name can not be changed.');
|
420 |
+
}
|
421 |
+
|
422 |
+
if ($this->_getFileName($path_from) == $this->_getContainerName($path_to)) {
|
423 |
+
return true;
|
424 |
+
}
|
425 |
+
|
426 |
+
$this->_getStorageClient($path_from)->copyBlob(
|
427 |
+
$this->_getContainerName($path_from),
|
428 |
+
$this->_getFileName($path_from),
|
429 |
+
$this->_getContainerName($path_to),
|
430 |
+
$this->_getFileName($path_to)
|
431 |
+
);
|
432 |
+
$this->_getStorageClient($path_from)->deleteBlob(
|
433 |
+
$this->_getContainerName($path_from),
|
434 |
+
$this->_getFileName($path_from)
|
435 |
+
);
|
436 |
+
return true;
|
437 |
+
}
|
438 |
+
|
439 |
+
/**
|
440 |
+
* Return array of URL variables
|
441 |
+
*
|
442 |
+
* @param string $path
|
443 |
+
* @param integer $flags
|
444 |
+
* @return array
|
445 |
+
*/
|
446 |
+
public function url_stat($path, $flags)
|
447 |
+
{
|
448 |
+
$stat = array();
|
449 |
+
$stat['dev'] = 0;
|
450 |
+
$stat['ino'] = 0;
|
451 |
+
$stat['mode'] = 0;
|
452 |
+
$stat['nlink'] = 0;
|
453 |
+
$stat['uid'] = 0;
|
454 |
+
$stat['gid'] = 0;
|
455 |
+
$stat['rdev'] = 0;
|
456 |
+
$stat['size'] = 0;
|
457 |
+
$stat['atime'] = 0;
|
458 |
+
$stat['mtime'] = 0;
|
459 |
+
$stat['ctime'] = 0;
|
460 |
+
$stat['blksize'] = 0;
|
461 |
+
$stat['blocks'] = 0;
|
462 |
+
|
463 |
+
$info = null;
|
464 |
+
try {
|
465 |
+
$info = $this->_getStorageClient($path)->getBlobInstance(
|
466 |
+
$this->_getContainerName($path),
|
467 |
+
$this->_getFileName($path)
|
468 |
+
);
|
469 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
470 |
+
// Unexisting file...
|
471 |
+
}
|
472 |
+
if (!is_null($info)) {
|
473 |
+
$stat['size'] = $info->Size;
|
474 |
+
$stat['atime'] = time();
|
475 |
+
}
|
476 |
+
|
477 |
+
return $stat;
|
478 |
+
}
|
479 |
+
|
480 |
+
/**
|
481 |
+
* Create a new directory
|
482 |
+
*
|
483 |
+
* @param string $path
|
484 |
+
* @param integer $mode
|
485 |
+
* @param integer $options
|
486 |
+
* @return boolean
|
487 |
+
*/
|
488 |
+
public function mkdir($path, $mode, $options)
|
489 |
+
{
|
490 |
+
if ($this->_getContainerName($path) == $this->_getFileName($path)) {
|
491 |
+
// Create container
|
492 |
+
try {
|
493 |
+
$this->_getStorageClient($path)->createContainer(
|
494 |
+
$this->_getContainerName($path)
|
495 |
+
);
|
496 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
497 |
+
return false;
|
498 |
+
}
|
499 |
+
} else {
|
500 |
+
throw new Microsoft_WindowsAzure_Exception('mkdir() with multiple levels is not supported on Windows Azure Blob Storage.');
|
501 |
+
}
|
502 |
+
}
|
503 |
+
|
504 |
+
/**
|
505 |
+
* Remove a directory
|
506 |
+
*
|
507 |
+
* @param string $path
|
508 |
+
* @param integer $options
|
509 |
+
* @return boolean
|
510 |
+
*/
|
511 |
+
public function rmdir($path, $options)
|
512 |
+
{
|
513 |
+
if ($this->_getContainerName($path) == $this->_getFileName($path)) {
|
514 |
+
// Delete container
|
515 |
+
try {
|
516 |
+
$this->_getStorageClient($path)->deleteContainer(
|
517 |
+
$this->_getContainerName($path)
|
518 |
+
);
|
519 |
+
} catch (Microsoft_WindowsAzure_Exception $ex) {
|
520 |
+
return false;
|
521 |
+
}
|
522 |
+
} else {
|
523 |
+
throw new Microsoft_WindowsAzure_Exception('rmdir() with multiple levels is not supported on Windows Azure Blob Storage.');
|
524 |
+
}
|
525 |
+
}
|
526 |
+
|
527 |
+
/**
|
528 |
+
* Attempt to open a directory
|
529 |
+
*
|
530 |
+
* @param string $path
|
531 |
+
* @param integer $options
|
532 |
+
* @return boolean
|
533 |
+
*/
|
534 |
+
public function dir_opendir($path, $options)
|
535 |
+
{
|
536 |
+
$this->_blobs = $this->_getStorageClient($path)->listBlobs(
|
537 |
+
$this->_getContainerName($path)
|
538 |
+
);
|
539 |
+
return is_array($this->_blobs);
|
540 |
+
}
|
541 |
+
|
542 |
+
/**
|
543 |
+
* Return the next filename in the directory
|
544 |
+
*
|
545 |
+
* @return string
|
546 |
+
*/
|
547 |
+
public function dir_readdir()
|
548 |
+
{
|
549 |
+
$object = current($this->_blobs);
|
550 |
+
if ($object !== false) {
|
551 |
+
next($this->_blobs);
|
552 |
+
return $object->Name;
|
553 |
+
}
|
554 |
+
return false;
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Reset the directory pointer
|
559 |
+
*
|
560 |
+
* @return boolean True
|
561 |
+
*/
|
562 |
+
public function dir_rewinddir()
|
563 |
+
{
|
564 |
+
reset($this->_blobs);
|
565 |
+
return true;
|
566 |
+
}
|
567 |
+
|
568 |
+
/**
|
569 |
+
* Close a directory
|
570 |
+
*
|
571 |
+
* @return boolean True
|
572 |
+
*/
|
573 |
+
public function dir_closedir()
|
574 |
+
{
|
575 |
+
$this->_blobs = null;
|
576 |
+
return true;
|
577 |
+
}
|
578 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/BlobContainer.php
ADDED
@@ -0,0 +1,112 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobContainer.php 45989 2010-05-03 12:19:11Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Name Name of the container
|
54 |
+
* @property string $Etag Etag of the container
|
55 |
+
* @property string $LastModified Last modified date of the container
|
56 |
+
* @property array $Metadata Key/value pairs of meta data
|
57 |
+
*/
|
58 |
+
class Microsoft_WindowsAzure_Storage_BlobContainer
|
59 |
+
{
|
60 |
+
/**
|
61 |
+
* Data
|
62 |
+
*
|
63 |
+
* @var array
|
64 |
+
*/
|
65 |
+
protected $_data = null;
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Constructor
|
69 |
+
*
|
70 |
+
* @param string $name Name
|
71 |
+
* @param string $etag Etag
|
72 |
+
* @param string $lastModified Last modified date
|
73 |
+
* @param array $metadata Key/value pairs of meta data
|
74 |
+
*/
|
75 |
+
public function __construct($name, $etag, $lastModified, $metadata = array())
|
76 |
+
{
|
77 |
+
$this->_data = array(
|
78 |
+
'name' => $name,
|
79 |
+
'etag' => $etag,
|
80 |
+
'lastmodified' => $lastModified,
|
81 |
+
'metadata' => $metadata
|
82 |
+
);
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Magic overload for setting properties
|
87 |
+
*
|
88 |
+
* @param string $name Name of the property
|
89 |
+
* @param string $value Value to set
|
90 |
+
*/
|
91 |
+
public function __set($name, $value) {
|
92 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
93 |
+
$this->_data[strtolower($name)] = $value;
|
94 |
+
return;
|
95 |
+
}
|
96 |
+
|
97 |
+
throw new Exception("Unknown property: " . $name);
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Magic overload for getting properties
|
102 |
+
*
|
103 |
+
* @param string $name Name of the property
|
104 |
+
*/
|
105 |
+
public function __get($name) {
|
106 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
107 |
+
return $this->_data[strtolower($name)];
|
108 |
+
}
|
109 |
+
|
110 |
+
throw new Exception("Unknown property: " . $name);
|
111 |
+
}
|
112 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/BlobInstance.php
ADDED
@@ -0,0 +1,145 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 53615 2010-11-16 20:45:11Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Container The name of the blob container in which the blob is stored.
|
54 |
+
* @property string $Name The name of the blob.
|
55 |
+
* @property string $SnapshotId The blob snapshot ID if it is a snapshot blob (= a backup copy of a blob).
|
56 |
+
* @property string $Etag The entity tag, used for versioning and concurrency.
|
57 |
+
* @property string $LastModified Timestamp when the blob was last modified.
|
58 |
+
* @property string $Url The full URL where the blob can be downloaded.
|
59 |
+
* @property int $Size The blob size in bytes.
|
60 |
+
* @property string $ContentType The blob content type header.
|
61 |
+
* @property string $ContentEncoding The blob content encoding header.
|
62 |
+
* @property string $ContentLanguage The blob content language header.
|
63 |
+
* @property string $CacheControl The blob cache control header.
|
64 |
+
* @property string $BlobType The blob type (block blob / page blob).
|
65 |
+
* @property string $LeaseStatus The blob lease status.
|
66 |
+
* @property boolean $IsPrefix Is it a blob or a directory prefix?
|
67 |
+
* @property array $Metadata Key/value pairs of meta data
|
68 |
+
*/
|
69 |
+
class Microsoft_WindowsAzure_Storage_BlobInstance
|
70 |
+
{
|
71 |
+
/**
|
72 |
+
* Data
|
73 |
+
*
|
74 |
+
* @var array
|
75 |
+
*/
|
76 |
+
protected $_data = null;
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Constructor
|
80 |
+
*
|
81 |
+
* @param string $containerName Container name
|
82 |
+
* @param string $name Name
|
83 |
+
* @param string $snapshotId Snapshot id
|
84 |
+
* @param string $etag Etag
|
85 |
+
* @param string $lastModified Last modified date
|
86 |
+
* @param string $url Url
|
87 |
+
* @param int $size Size
|
88 |
+
* @param string $contentType Content Type
|
89 |
+
* @param string $contentEncoding Content Encoding
|
90 |
+
* @param string $contentLanguage Content Language
|
91 |
+
* @param string $cacheControl Cache control
|
92 |
+
* @param string $blobType Blob type
|
93 |
+
* @param string $leaseStatus Lease status
|
94 |
+
* @param boolean $isPrefix Is Prefix?
|
95 |
+
* @param array $metadata Key/value pairs of meta data
|
96 |
+
*/
|
97 |
+
public function __construct($containerName, $name, $snapshotId, $etag, $lastModified, $url = '', $size = 0, $contentType = '', $contentEncoding = '', $contentLanguage = '', $cacheControl = '', $blobType = '', $leaseStatus = '', $isPrefix = false, $metadata = array())
|
98 |
+
{
|
99 |
+
$this->_data = array(
|
100 |
+
'container' => $containerName,
|
101 |
+
'name' => $name,
|
102 |
+
'snapshotid' => $snapshotId,
|
103 |
+
'etag' => $etag,
|
104 |
+
'lastmodified' => $lastModified,
|
105 |
+
'url' => $url,
|
106 |
+
'size' => $size,
|
107 |
+
'contenttype' => $contentType,
|
108 |
+
'contentencoding' => $contentEncoding,
|
109 |
+
'contentlanguage' => $contentLanguage,
|
110 |
+
'cachecontrol' => $cacheControl,
|
111 |
+
'blobtype' => $blobType,
|
112 |
+
'leasestatus' => $leaseStatus,
|
113 |
+
'isprefix' => $isPrefix,
|
114 |
+
'metadata' => $metadata
|
115 |
+
);
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Magic overload for setting properties
|
120 |
+
*
|
121 |
+
* @param string $name Name of the property
|
122 |
+
* @param string $value Value to set
|
123 |
+
*/
|
124 |
+
public function __set($name, $value) {
|
125 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
126 |
+
$this->_data[strtolower($name)] = $value;
|
127 |
+
return;
|
128 |
+
}
|
129 |
+
|
130 |
+
throw new Exception("Unknown property: " . $name);
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Magic overload for getting properties
|
135 |
+
*
|
136 |
+
* @param string $name Name of the property
|
137 |
+
*/
|
138 |
+
public function __get($name) {
|
139 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
140 |
+
return $this->_data[strtolower($name)];
|
141 |
+
}
|
142 |
+
|
143 |
+
throw new Exception("Unknown property: " . $name);
|
144 |
+
}
|
145 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/DynamicTableEntity.php
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
|
37 |
+
/**
|
38 |
+
* @see Microsoft_WindowsAzure_Exception
|
39 |
+
*/
|
40 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @see Microsoft_WindowsAzure_Storage_TableEntity
|
44 |
+
*/
|
45 |
+
require_once 'Microsoft/WindowsAzure/Storage/TableEntity.php';
|
46 |
+
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @category Microsoft
|
50 |
+
* @package Microsoft_WindowsAzure
|
51 |
+
* @subpackage Storage
|
52 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
53 |
+
* @license http://phpazure.codeplex.com/license
|
54 |
+
*/
|
55 |
+
class Microsoft_WindowsAzure_Storage_DynamicTableEntity extends Microsoft_WindowsAzure_Storage_TableEntity
|
56 |
+
{
|
57 |
+
/**
|
58 |
+
* Dynamic properties
|
59 |
+
*
|
60 |
+
* @var array
|
61 |
+
*/
|
62 |
+
protected $_dynamicProperties = array();
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Magic overload for setting properties
|
66 |
+
*
|
67 |
+
* @param string $name Name of the property
|
68 |
+
* @param string $value Value to set
|
69 |
+
*/
|
70 |
+
public function __set($name, $value) {
|
71 |
+
$this->setAzureProperty($name, $value, null);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Magic overload for getting properties
|
76 |
+
*
|
77 |
+
* @param string $name Name of the property
|
78 |
+
*/
|
79 |
+
public function __get($name) {
|
80 |
+
return $this->getAzureProperty($name);
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Set an Azure property
|
85 |
+
*
|
86 |
+
* @param string $name Property name
|
87 |
+
* @param mixed $value Property value
|
88 |
+
* @param string $type Property type (Edm.xxxx)
|
89 |
+
* @return Microsoft_WindowsAzure_Storage_DynamicTableEntity
|
90 |
+
*/
|
91 |
+
public function setAzureProperty($name, $value = '', $type = null)
|
92 |
+
{
|
93 |
+
if (strtolower($name) == 'partitionkey') {
|
94 |
+
$this->setPartitionKey($value);
|
95 |
+
} else if (strtolower($name) == 'rowkey') {
|
96 |
+
$this->setRowKey($value);
|
97 |
+
} else if (strtolower($name) == 'etag') {
|
98 |
+
$this->setEtag($value);
|
99 |
+
} else {
|
100 |
+
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
|
101 |
+
// Determine type?
|
102 |
+
if (is_null($type)) {
|
103 |
+
$type = 'Edm.String';
|
104 |
+
if (is_int($value)) {
|
105 |
+
$type = 'Edm.Int32';
|
106 |
+
} else if (is_float($value)) {
|
107 |
+
$type = 'Edm.Double';
|
108 |
+
} else if (is_bool($value)) {
|
109 |
+
$type = 'Edm.Boolean';
|
110 |
+
}
|
111 |
+
}
|
112 |
+
|
113 |
+
// Set dynamic property
|
114 |
+
$this->_dynamicProperties[strtolower($name)] = (object)array(
|
115 |
+
'Name' => $name,
|
116 |
+
'Type' => $type,
|
117 |
+
'Value' => $value,
|
118 |
+
);
|
119 |
+
}
|
120 |
+
|
121 |
+
$this->_dynamicProperties[strtolower($name)]->Value = $value;
|
122 |
+
}
|
123 |
+
return $this;
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Set an Azure property type
|
128 |
+
*
|
129 |
+
* @param string $name Property name
|
130 |
+
* @param string $type Property type (Edm.xxxx)
|
131 |
+
* @return Microsoft_WindowsAzure_Storage_DynamicTableEntity
|
132 |
+
*/
|
133 |
+
public function setAzurePropertyType($name, $type = 'Edm.String')
|
134 |
+
{
|
135 |
+
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
|
136 |
+
$this->setAzureProperty($name, '', $type);
|
137 |
+
} else {
|
138 |
+
$this->_dynamicProperties[strtolower($name)]->Type = $type;
|
139 |
+
}
|
140 |
+
return $this;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Get an Azure property
|
145 |
+
*
|
146 |
+
* @param string $name Property name
|
147 |
+
* @param mixed $value Property value
|
148 |
+
* @param string $type Property type (Edm.xxxx)
|
149 |
+
* @return Microsoft_WindowsAzure_Storage_DynamicTableEntity
|
150 |
+
*/
|
151 |
+
public function getAzureProperty($name)
|
152 |
+
{
|
153 |
+
if (strtolower($name) == 'partitionkey') {
|
154 |
+
return $this->getPartitionKey();
|
155 |
+
}
|
156 |
+
if (strtolower($name) == 'rowkey') {
|
157 |
+
return $this->getRowKey();
|
158 |
+
}
|
159 |
+
if (strtolower($name) == 'etag') {
|
160 |
+
return $this->getEtag();
|
161 |
+
}
|
162 |
+
|
163 |
+
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
|
164 |
+
$this->setAzureProperty($name);
|
165 |
+
}
|
166 |
+
|
167 |
+
return $this->_dynamicProperties[strtolower($name)]->Value;
|
168 |
+
}
|
169 |
+
|
170 |
+
/**
|
171 |
+
* Get an Azure property type
|
172 |
+
*
|
173 |
+
* @param string $name Property name
|
174 |
+
* @return string Property type (Edm.xxxx)
|
175 |
+
*/
|
176 |
+
public function getAzurePropertyType($name)
|
177 |
+
{
|
178 |
+
if (!array_key_exists(strtolower($name), $this->_dynamicProperties)) {
|
179 |
+
$this->setAzureProperty($name, '', $type);
|
180 |
+
}
|
181 |
+
|
182 |
+
return $this->_dynamicProperties[strtolower($name)]->Type;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Get Azure values
|
187 |
+
*
|
188 |
+
* @return array
|
189 |
+
*/
|
190 |
+
public function getAzureValues()
|
191 |
+
{
|
192 |
+
return array_merge(array_values($this->_dynamicProperties), parent::getAzureValues());
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Set Azure values
|
197 |
+
*
|
198 |
+
* @param array $values
|
199 |
+
* @param boolean $throwOnError Throw Microsoft_WindowsAzure_Exception when a property is not specified in $values?
|
200 |
+
* @throws Microsoft_WindowsAzure_Exception
|
201 |
+
*/
|
202 |
+
public function setAzureValues($values = array(), $throwOnError = false)
|
203 |
+
{
|
204 |
+
// Set parent values
|
205 |
+
parent::setAzureValues($values, false);
|
206 |
+
|
207 |
+
// Set current values
|
208 |
+
foreach ($values as $key => $value)
|
209 |
+
{
|
210 |
+
$this->$key = $value;
|
211 |
+
}
|
212 |
+
}
|
213 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/LeaseInstance.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 45390 2010-04-19 08:28:21Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Container Container name
|
54 |
+
* @property string $Name Name
|
55 |
+
* @property string $LeaseId Lease id
|
56 |
+
* @property string $LeaseTime Time remaining in the lease period, in seconds. This header is returned only for a successful request to break the lease. It provides an approximation as to when the lease period will expire.
|
57 |
+
*/
|
58 |
+
class Microsoft_WindowsAzure_Storage_LeaseInstance
|
59 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
60 |
+
{
|
61 |
+
/**
|
62 |
+
* Constructor
|
63 |
+
*
|
64 |
+
* @param string $containerName Container name
|
65 |
+
* @param string $name Name
|
66 |
+
* @param string $leaseId Lease id
|
67 |
+
* @param string $leaseTime Time remaining in the lease period, in seconds. This header is returned only for a successful request to break the lease. It provides an approximation as to when the lease period will expire.
|
68 |
+
*/
|
69 |
+
public function __construct($containerName, $name, $leaseId, $leaseTime)
|
70 |
+
{
|
71 |
+
$this->_data = array(
|
72 |
+
'container' => $containerName,
|
73 |
+
'name' => $name,
|
74 |
+
'leaseid' => $leaseId,
|
75 |
+
'leasetime' => $leaseTime
|
76 |
+
);
|
77 |
+
}
|
78 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/PageRegionInstance.php
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 45390 2010-04-19 08:28:21Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property int $start Page range start
|
54 |
+
* @property int $end Page range end
|
55 |
+
*/
|
56 |
+
class Microsoft_WindowsAzure_Storage_PageRegionInstance
|
57 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
58 |
+
{
|
59 |
+
/**
|
60 |
+
* Constructor
|
61 |
+
*
|
62 |
+
* @param int $start Page range start
|
63 |
+
* @param int $end Page range end
|
64 |
+
*/
|
65 |
+
public function __construct($start = 0, $end = 0)
|
66 |
+
{
|
67 |
+
$this->_data = array(
|
68 |
+
'start' => $start,
|
69 |
+
'end' => $end
|
70 |
+
);
|
71 |
+
}
|
72 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/Queue.php
ADDED
@@ -0,0 +1,582 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://todo name_todo
|
33 |
+
* @version $Id: Blob.php 24241 2009-07-22 09:43:13Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedKey
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKey.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_Http_Client
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/Http/Client.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_Http_Response
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/Http/Response.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_WindowsAzure_Storage
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Microsoft_WindowsAzure_Storage_QueueInstance
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/WindowsAzure/Storage/QueueInstance.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Microsoft_WindowsAzure_Storage_QueueMessage
|
68 |
+
*/
|
69 |
+
require_once 'Microsoft/WindowsAzure/Storage/QueueMessage.php';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @see Microsoft_WindowsAzure_Exception
|
73 |
+
*/
|
74 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
75 |
+
|
76 |
+
|
77 |
+
/**
|
78 |
+
* @category Microsoft
|
79 |
+
* @package Microsoft_WindowsAzure
|
80 |
+
* @subpackage Storage
|
81 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
82 |
+
* @license http://phpazure.codeplex.com/license
|
83 |
+
*/
|
84 |
+
class Microsoft_WindowsAzure_Storage_Queue extends Microsoft_WindowsAzure_Storage
|
85 |
+
{
|
86 |
+
/**
|
87 |
+
* Maximal message size (in bytes)
|
88 |
+
*/
|
89 |
+
const MAX_MESSAGE_SIZE = 8388608;
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Maximal message ttl (in seconds)
|
93 |
+
*/
|
94 |
+
const MAX_MESSAGE_TTL = 604800;
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Creates a new Microsoft_WindowsAzure_Storage_Queue instance
|
98 |
+
*
|
99 |
+
* @param string $host Storage host name
|
100 |
+
* @param string $accountName Account name for Windows Azure
|
101 |
+
* @param string $accountKey Account key for Windows Azure
|
102 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
103 |
+
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
|
104 |
+
*/
|
105 |
+
public function __construct($host = Microsoft_WindowsAzure_Storage::URL_DEV_QUEUE, $accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
|
106 |
+
{
|
107 |
+
parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
|
108 |
+
|
109 |
+
// API version
|
110 |
+
$this->_apiVersion = '2009-09-19';
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Check if a queue exists
|
115 |
+
*
|
116 |
+
* @param string $queueName Queue name
|
117 |
+
* @return boolean
|
118 |
+
*/
|
119 |
+
public function queueExists($queueName = '')
|
120 |
+
{
|
121 |
+
if ($queueName === '') {
|
122 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
123 |
+
}
|
124 |
+
if (!self::isValidQueueName($queueName)) {
|
125 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
126 |
+
}
|
127 |
+
|
128 |
+
// List queues
|
129 |
+
$queues = $this->listQueues($queueName, 1);
|
130 |
+
foreach ($queues as $queue) {
|
131 |
+
if ($queue->Name == $queueName) {
|
132 |
+
return true;
|
133 |
+
}
|
134 |
+
}
|
135 |
+
|
136 |
+
return false;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Create queue
|
141 |
+
*
|
142 |
+
* @param string $queueName Queue name
|
143 |
+
* @param array $metadata Key/value pairs of meta data
|
144 |
+
* @return object Queue properties
|
145 |
+
* @throws Microsoft_WindowsAzure_Exception
|
146 |
+
*/
|
147 |
+
public function createQueue($queueName = '', $metadata = array())
|
148 |
+
{
|
149 |
+
if ($queueName === '') {
|
150 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
151 |
+
}
|
152 |
+
if (!self::isValidQueueName($queueName)) {
|
153 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
154 |
+
}
|
155 |
+
|
156 |
+
// Create metadata headers
|
157 |
+
$headers = array();
|
158 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
159 |
+
|
160 |
+
// Perform request
|
161 |
+
$response = $this->_performRequest($queueName, '', Microsoft_Http_Client::PUT, $headers);
|
162 |
+
if ($response->isSuccessful()) {
|
163 |
+
return new Microsoft_WindowsAzure_Storage_QueueInstance(
|
164 |
+
$queueName,
|
165 |
+
$metadata
|
166 |
+
);
|
167 |
+
} else {
|
168 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
169 |
+
}
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Create queue if it does not exist
|
174 |
+
*
|
175 |
+
* @param string $queueName Queue name
|
176 |
+
* @param array $metadata Key/value pairs of meta data
|
177 |
+
* @throws Microsoft_WindowsAzure_Exception
|
178 |
+
*/
|
179 |
+
public function createQueueIfNotExists($queueName = '', $metadata = array())
|
180 |
+
{
|
181 |
+
if (!$this->queueExists($queueName)) {
|
182 |
+
$this->createQueue($queueName, $metadata);
|
183 |
+
}
|
184 |
+
}
|
185 |
+
|
186 |
+
/**
|
187 |
+
* Get queue
|
188 |
+
*
|
189 |
+
* @param string $queueName Queue name
|
190 |
+
* @return Microsoft_WindowsAzure_Storage_QueueInstance
|
191 |
+
* @throws Microsoft_WindowsAzure_Exception
|
192 |
+
*/
|
193 |
+
public function getQueue($queueName = '')
|
194 |
+
{
|
195 |
+
if ($queueName === '') {
|
196 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
197 |
+
}
|
198 |
+
if (!self::isValidQueueName($queueName)) {
|
199 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
200 |
+
}
|
201 |
+
|
202 |
+
// Perform request
|
203 |
+
$response = $this->_performRequest($queueName, '?comp=metadata', Microsoft_Http_Client::GET);
|
204 |
+
if ($response->isSuccessful()) {
|
205 |
+
// Parse metadata
|
206 |
+
$metadata = $this->_parseMetadataHeaders($response->getHeaders());
|
207 |
+
|
208 |
+
// Return queue
|
209 |
+
$queue = new Microsoft_WindowsAzure_Storage_QueueInstance(
|
210 |
+
$queueName,
|
211 |
+
$metadata
|
212 |
+
);
|
213 |
+
$queue->ApproximateMessageCount = intval($response->getHeader('x-ms-approximate-message-count'));
|
214 |
+
return $queue;
|
215 |
+
} else {
|
216 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
217 |
+
}
|
218 |
+
}
|
219 |
+
|
220 |
+
/**
|
221 |
+
* Get queue metadata
|
222 |
+
*
|
223 |
+
* @param string $queueName Queue name
|
224 |
+
* @return array Key/value pairs of meta data
|
225 |
+
* @throws Microsoft_WindowsAzure_Exception
|
226 |
+
*/
|
227 |
+
public function getQueueMetadata($queueName = '')
|
228 |
+
{
|
229 |
+
if ($queueName === '') {
|
230 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
231 |
+
}
|
232 |
+
if (!self::isValidQueueName($queueName)) {
|
233 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
234 |
+
}
|
235 |
+
|
236 |
+
return $this->getQueue($queueName)->Metadata;
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Set queue metadata
|
241 |
+
*
|
242 |
+
* Calling the Set Queue Metadata operation overwrites all existing metadata that is associated with the queue. It's not possible to modify an individual name/value pair.
|
243 |
+
*
|
244 |
+
* @param string $queueName Queue name
|
245 |
+
* @param array $metadata Key/value pairs of meta data
|
246 |
+
* @throws Microsoft_WindowsAzure_Exception
|
247 |
+
*/
|
248 |
+
public function setQueueMetadata($queueName = '', $metadata = array())
|
249 |
+
{
|
250 |
+
if ($queueName === '') {
|
251 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
252 |
+
}
|
253 |
+
if (!self::isValidQueueName($queueName)) {
|
254 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
255 |
+
}
|
256 |
+
if (count($metadata) == 0) {
|
257 |
+
return;
|
258 |
+
}
|
259 |
+
|
260 |
+
// Create metadata headers
|
261 |
+
$headers = array();
|
262 |
+
$headers = array_merge($headers, $this->_generateMetadataHeaders($metadata));
|
263 |
+
|
264 |
+
// Perform request
|
265 |
+
$response = $this->_performRequest($queueName, '?comp=metadata', Microsoft_Http_Client::PUT, $headers);
|
266 |
+
|
267 |
+
if (!$response->isSuccessful()) {
|
268 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Delete queue
|
274 |
+
*
|
275 |
+
* @param string $queueName Queue name
|
276 |
+
* @throws Microsoft_WindowsAzure_Exception
|
277 |
+
*/
|
278 |
+
public function deleteQueue($queueName = '')
|
279 |
+
{
|
280 |
+
if ($queueName === '') {
|
281 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
282 |
+
}
|
283 |
+
if (!self::isValidQueueName($queueName)) {
|
284 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
285 |
+
}
|
286 |
+
|
287 |
+
// Perform request
|
288 |
+
$response = $this->_performRequest($queueName, '', Microsoft_Http_Client::DELETE);
|
289 |
+
if (!$response->isSuccessful()) {
|
290 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
291 |
+
}
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* List queues
|
296 |
+
*
|
297 |
+
* @param string $prefix Optional. Filters the results to return only queues whose name begins with the specified prefix.
|
298 |
+
* @param int $maxResults Optional. Specifies the maximum number of queues to return per call to Azure storage. This does NOT affect list size returned by this function. (maximum: 5000)
|
299 |
+
* @param string $marker Optional string value that identifies the portion of the list to be returned with the next list operation.
|
300 |
+
* @param string $include Optional. Include this parameter to specify that the queue's metadata be returned as part of the response body. (allowed values: '', 'metadata')
|
301 |
+
* @param int $currentResultCount Current result count (internal use)
|
302 |
+
* @return array
|
303 |
+
* @throws Microsoft_WindowsAzure_Exception
|
304 |
+
*/
|
305 |
+
public function listQueues($prefix = null, $maxResults = null, $marker = null, $include = null, $currentResultCount = 0)
|
306 |
+
{
|
307 |
+
// Build query string
|
308 |
+
$queryString = array('comp=list');
|
309 |
+
if (!is_null($prefix)) {
|
310 |
+
$queryString[] = 'prefix=' . $prefix;
|
311 |
+
}
|
312 |
+
if (!is_null($maxResults)) {
|
313 |
+
$queryString[] = 'maxresults=' . $maxResults;
|
314 |
+
}
|
315 |
+
if (!is_null($marker)) {
|
316 |
+
$queryString[] = 'marker=' . $marker;
|
317 |
+
}
|
318 |
+
if (!is_null($include)) {
|
319 |
+
$queryString[] = 'include=' . $include;
|
320 |
+
}
|
321 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
322 |
+
|
323 |
+
// Perform request
|
324 |
+
$response = $this->_performRequest('', $queryString, Microsoft_Http_Client::GET);
|
325 |
+
if ($response->isSuccessful()) {
|
326 |
+
$xmlQueues = $this->_parseResponse($response)->Queues->Queue;
|
327 |
+
$xmlMarker = (string)$this->_parseResponse($response)->NextMarker;
|
328 |
+
|
329 |
+
$queues = array();
|
330 |
+
if (!is_null($xmlQueues)) {
|
331 |
+
for ($i = 0; $i < count($xmlQueues); $i++) {
|
332 |
+
$queues[] = new Microsoft_WindowsAzure_Storage_QueueInstance(
|
333 |
+
(string)$xmlQueues[$i]->Name,
|
334 |
+
$this->_parseMetadataElement($xmlQueues[$i])
|
335 |
+
);
|
336 |
+
}
|
337 |
+
}
|
338 |
+
$currentResultCount = $currentResultCount + count($queues);
|
339 |
+
if (!is_null($maxResults) && $currentResultCount < $maxResults) {
|
340 |
+
if (!is_null($xmlMarker) && $xmlMarker != '') {
|
341 |
+
$queues = array_merge($queues, $this->listQueues($prefix, $maxResults, $xmlMarker, $include, $currentResultCount));
|
342 |
+
}
|
343 |
+
}
|
344 |
+
if (!is_null($maxResults) && count($queues) > $maxResults) {
|
345 |
+
$queues = array_slice($queues, 0, $maxResults);
|
346 |
+
}
|
347 |
+
|
348 |
+
return $queues;
|
349 |
+
} else {
|
350 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
351 |
+
}
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* Put message into queue
|
356 |
+
*
|
357 |
+
* @param string $queueName Queue name
|
358 |
+
* @param string $message Message
|
359 |
+
* @param int $ttl Message Time-To-Live (in seconds). Defaults to 7 days if the parameter is omitted.
|
360 |
+
* @throws Microsoft_WindowsAzure_Exception
|
361 |
+
*/
|
362 |
+
public function putMessage($queueName = '', $message = '', $ttl = null)
|
363 |
+
{
|
364 |
+
if ($queueName === '') {
|
365 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
366 |
+
}
|
367 |
+
if (!self::isValidQueueName($queueName)) {
|
368 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
369 |
+
}
|
370 |
+
if (strlen($message) > self::MAX_MESSAGE_SIZE) {
|
371 |
+
throw new Microsoft_WindowsAzure_Exception('Message is too big. Message content should be < 8KB.');
|
372 |
+
}
|
373 |
+
if ($message == '') {
|
374 |
+
throw new Microsoft_WindowsAzure_Exception('Message is not specified.');
|
375 |
+
}
|
376 |
+
if (!is_null($ttl) && ($ttl <= 0 || $ttl > self::MAX_MESSAGE_SIZE)) {
|
377 |
+
throw new Microsoft_WindowsAzure_Exception('Message TTL is invalid. Maximal TTL is 7 days (' . self::MAX_MESSAGE_SIZE . ' seconds) and should be greater than zero.');
|
378 |
+
}
|
379 |
+
|
380 |
+
// Build query string
|
381 |
+
$queryString = array();
|
382 |
+
if (!is_null($ttl)) {
|
383 |
+
$queryString[] = 'messagettl=' . $ttl;
|
384 |
+
}
|
385 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
386 |
+
|
387 |
+
// Build body
|
388 |
+
$rawData = '';
|
389 |
+
$rawData .= '<QueueMessage>';
|
390 |
+
$rawData .= ' <MessageText>' . base64_encode($message) . '</MessageText>';
|
391 |
+
$rawData .= '</QueueMessage>';
|
392 |
+
|
393 |
+
// Perform request
|
394 |
+
$response = $this->_performRequest($queueName . '/messages', $queryString, Microsoft_Http_Client::POST, array(), false, $rawData);
|
395 |
+
|
396 |
+
if (!$response->isSuccessful()) {
|
397 |
+
throw new Microsoft_WindowsAzure_Exception('Error putting message into queue.');
|
398 |
+
}
|
399 |
+
}
|
400 |
+
|
401 |
+
/**
|
402 |
+
* Get queue messages
|
403 |
+
*
|
404 |
+
* @param string $queueName Queue name
|
405 |
+
* @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation.
|
406 |
+
* @param int $visibilityTimeout Optional. An integer value that specifies the message's visibility timeout in seconds. The maximum value is 2 hours. The default message visibility timeout is 30 seconds.
|
407 |
+
* @param string $peek Peek only?
|
408 |
+
* @return array
|
409 |
+
* @throws Microsoft_WindowsAzure_Exception
|
410 |
+
*/
|
411 |
+
public function getMessages($queueName = '', $numOfMessages = 1, $visibilityTimeout = null, $peek = false)
|
412 |
+
{
|
413 |
+
if ($queueName === '') {
|
414 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
415 |
+
}
|
416 |
+
if (!self::isValidQueueName($queueName)) {
|
417 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
418 |
+
}
|
419 |
+
if ($numOfMessages < 1 || $numOfMessages > 32 || intval($numOfMessages) != $numOfMessages) {
|
420 |
+
throw new Microsoft_WindowsAzure_Exception('Invalid number of messages to retrieve.');
|
421 |
+
}
|
422 |
+
if (!is_null($visibilityTimeout) && ($visibilityTimeout <= 0 || $visibilityTimeout > 7200)) {
|
423 |
+
throw new Microsoft_WindowsAzure_Exception('Visibility timeout is invalid. Maximum value is 2 hours (7200 seconds) and should be greater than zero.');
|
424 |
+
}
|
425 |
+
|
426 |
+
// Build query string
|
427 |
+
$queryString = array();
|
428 |
+
if ($peek) {
|
429 |
+
$queryString[] = 'peekonly=true';
|
430 |
+
}
|
431 |
+
if ($numOfMessages > 1) {
|
432 |
+
$queryString[] = 'numofmessages=' . $numOfMessages;
|
433 |
+
}
|
434 |
+
if (!$peek && !is_null($visibilityTimeout)) {
|
435 |
+
$queryString[] = 'visibilitytimeout=' . $visibilityTimeout;
|
436 |
+
}
|
437 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
438 |
+
|
439 |
+
// Perform request
|
440 |
+
$response = $this->_performRequest($queueName . '/messages', $queryString, Microsoft_Http_Client::GET);
|
441 |
+
if ($response->isSuccessful()) {
|
442 |
+
// Parse results
|
443 |
+
$result = $this->_parseResponse($response);
|
444 |
+
if (!$result) {
|
445 |
+
return array();
|
446 |
+
}
|
447 |
+
|
448 |
+
$xmlMessages = null;
|
449 |
+
if (count($result->QueueMessage) > 1) {
|
450 |
+
$xmlMessages = $result->QueueMessage;
|
451 |
+
} else {
|
452 |
+
$xmlMessages = array($result->QueueMessage);
|
453 |
+
}
|
454 |
+
|
455 |
+
$messages = array();
|
456 |
+
for ($i = 0; $i < count($xmlMessages); $i++) {
|
457 |
+
$messages[] = new Microsoft_WindowsAzure_Storage_QueueMessage(
|
458 |
+
(string)$xmlMessages[$i]->MessageId,
|
459 |
+
(string)$xmlMessages[$i]->InsertionTime,
|
460 |
+
(string)$xmlMessages[$i]->ExpirationTime,
|
461 |
+
($peek ? '' : (string)$xmlMessages[$i]->PopReceipt),
|
462 |
+
($peek ? '' : (string)$xmlMessages[$i]->TimeNextVisible),
|
463 |
+
(string)$xmlMessages[$i]->DequeueCount,
|
464 |
+
base64_decode((string)$xmlMessages[$i]->MessageText)
|
465 |
+
);
|
466 |
+
}
|
467 |
+
|
468 |
+
return $messages;
|
469 |
+
} else {
|
470 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
471 |
+
}
|
472 |
+
}
|
473 |
+
|
474 |
+
/**
|
475 |
+
* Peek queue messages
|
476 |
+
*
|
477 |
+
* @param string $queueName Queue name
|
478 |
+
* @param string $numOfMessages Optional. A nonzero integer value that specifies the number of messages to retrieve from the queue, up to a maximum of 32. By default, a single message is retrieved from the queue with this operation.
|
479 |
+
* @return array
|
480 |
+
* @throws Microsoft_WindowsAzure_Exception
|
481 |
+
*/
|
482 |
+
public function peekMessages($queueName = '', $numOfMessages = 1)
|
483 |
+
{
|
484 |
+
return $this->getMessages($queueName, $numOfMessages, null, true);
|
485 |
+
}
|
486 |
+
|
487 |
+
/**
|
488 |
+
* Clear queue messages
|
489 |
+
*
|
490 |
+
* @param string $queueName Queue name
|
491 |
+
* @throws Microsoft_WindowsAzure_Exception
|
492 |
+
*/
|
493 |
+
public function clearMessages($queueName = '')
|
494 |
+
{
|
495 |
+
if ($queueName === '') {
|
496 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
497 |
+
}
|
498 |
+
if (!self::isValidQueueName($queueName)) {
|
499 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
500 |
+
}
|
501 |
+
|
502 |
+
// Perform request
|
503 |
+
$response = $this->_performRequest($queueName . '/messages', '', Microsoft_Http_Client::DELETE);
|
504 |
+
if (!$response->isSuccessful()) {
|
505 |
+
throw new Microsoft_WindowsAzure_Exception('Error clearing messages from queue.');
|
506 |
+
}
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Delete queue message
|
511 |
+
*
|
512 |
+
* @param string $queueName Queue name
|
513 |
+
* @param Microsoft_WindowsAzure_Storage_QueueMessage $message Message to delete from queue. A message retrieved using "peekMessages" can NOT be deleted!
|
514 |
+
* @throws Microsoft_WindowsAzure_Exception
|
515 |
+
*/
|
516 |
+
public function deleteMessage($queueName = '', Microsoft_WindowsAzure_Storage_QueueMessage $message)
|
517 |
+
{
|
518 |
+
if ($queueName === '') {
|
519 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name is not specified.');
|
520 |
+
}
|
521 |
+
if (!self::isValidQueueName($queueName)) {
|
522 |
+
throw new Microsoft_WindowsAzure_Exception('Queue name does not adhere to queue naming conventions. See http://msdn.microsoft.com/en-us/library/dd179349.aspx for more information.');
|
523 |
+
}
|
524 |
+
if ($message->PopReceipt == '') {
|
525 |
+
throw new Microsoft_WindowsAzure_Exception('A message retrieved using "peekMessages" can NOT be deleted! Use "getMessages" instead.');
|
526 |
+
}
|
527 |
+
|
528 |
+
// Perform request
|
529 |
+
$response = $this->_performRequest($queueName . '/messages/' . $message->MessageId, '?popreceipt=' . $message->PopReceipt, Microsoft_Http_Client::DELETE);
|
530 |
+
if (!$response->isSuccessful()) {
|
531 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
532 |
+
}
|
533 |
+
}
|
534 |
+
|
535 |
+
/**
|
536 |
+
* Is valid queue name?
|
537 |
+
*
|
538 |
+
* @param string $queueName Queue name
|
539 |
+
* @return boolean
|
540 |
+
*/
|
541 |
+
public static function isValidQueueName($queueName = '')
|
542 |
+
{
|
543 |
+
if (preg_match("/^[a-z0-9][a-z0-9-]*$/", $queueName) === 0) {
|
544 |
+
return false;
|
545 |
+
}
|
546 |
+
|
547 |
+
if (strpos($queueName, '--') !== false) {
|
548 |
+
return false;
|
549 |
+
}
|
550 |
+
|
551 |
+
if (strtolower($queueName) != $queueName) {
|
552 |
+
return false;
|
553 |
+
}
|
554 |
+
|
555 |
+
if (strlen($queueName) < 3 || strlen($queueName) > 63) {
|
556 |
+
return false;
|
557 |
+
}
|
558 |
+
|
559 |
+
if (substr($queueName, -1) == '-') {
|
560 |
+
return false;
|
561 |
+
}
|
562 |
+
|
563 |
+
return true;
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Get error message from Microsoft_Http_Response
|
568 |
+
*
|
569 |
+
* @param Microsoft_Http_Response $response Repsonse
|
570 |
+
* @param string $alternativeError Alternative error message
|
571 |
+
* @return string
|
572 |
+
*/
|
573 |
+
protected function _getErrorMessage(Microsoft_Http_Response $response, $alternativeError = 'Unknown error.')
|
574 |
+
{
|
575 |
+
$response = $this->_parseResponse($response);
|
576 |
+
if ($response && $response->Message) {
|
577 |
+
return (string)$response->Message;
|
578 |
+
} else {
|
579 |
+
return $alternativeError;
|
580 |
+
}
|
581 |
+
}
|
582 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/QueueInstance.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobContainer.php 17553 2009-05-15 10:40:55Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Name Name of the queue
|
54 |
+
* @property array $Metadata Key/value pairs of meta data
|
55 |
+
* @property integer $ApproximateMessageCount The approximate number of messages in the queue
|
56 |
+
*/
|
57 |
+
class Microsoft_WindowsAzure_Storage_QueueInstance
|
58 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
59 |
+
{
|
60 |
+
/**
|
61 |
+
* Constructor
|
62 |
+
*
|
63 |
+
* @param string $name Name
|
64 |
+
* @param array $metadata Key/value pairs of meta data
|
65 |
+
*/
|
66 |
+
public function __construct($name, $metadata = array())
|
67 |
+
{
|
68 |
+
$this->_data = array(
|
69 |
+
'name' => $name,
|
70 |
+
'metadata' => $metadata,
|
71 |
+
'approximatemessagecount' => 0
|
72 |
+
);
|
73 |
+
}
|
74 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/QueueMessage.php
ADDED
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobContainer.php 17553 2009-05-15 10:40:55Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $MessageId Message ID
|
54 |
+
* @property string $InsertionTime Insertion time
|
55 |
+
* @property string $ExpirationTime Expiration time
|
56 |
+
* @property string $PopReceipt Receipt verification for deleting the message from queue.
|
57 |
+
* @property string $TimeNextVisible Next time the message is visible in the queue
|
58 |
+
* @property int $DequeueCount Number of times the message has been dequeued. This value is incremented each time the message is subsequently dequeued.
|
59 |
+
* @property string $MessageText Message text
|
60 |
+
*/
|
61 |
+
class Microsoft_WindowsAzure_Storage_QueueMessage
|
62 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
63 |
+
{
|
64 |
+
/**
|
65 |
+
* Constructor
|
66 |
+
*
|
67 |
+
* @param string $messageId Message ID
|
68 |
+
* @param string $insertionTime Insertion time
|
69 |
+
* @param string $expirationTime Expiration time
|
70 |
+
* @param string $popReceipt Receipt verification for deleting the message from queue.
|
71 |
+
* @param string $timeNextVisible Next time the message is visible in the queue
|
72 |
+
* @param int $dequeueCount Number of times the message has been dequeued. This value is incremented each time the message is subsequently dequeued.
|
73 |
+
* @param string $messageText Message text
|
74 |
+
*/
|
75 |
+
public function __construct($messageId, $insertionTime, $expirationTime, $popReceipt, $timeNextVisible, $dequeueCount, $messageText)
|
76 |
+
{
|
77 |
+
$this->_data = array(
|
78 |
+
'messageid' => $messageId,
|
79 |
+
'insertiontime' => $insertionTime,
|
80 |
+
'expirationtime' => $expirationTime,
|
81 |
+
'popreceipt' => $popReceipt,
|
82 |
+
'timenextvisible' => $timeNextVisible,
|
83 |
+
'dequeuecount' => $dequeueCount,
|
84 |
+
'messagetext' => $messageText
|
85 |
+
);
|
86 |
+
}
|
87 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/SignedIdentifier.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobContainer.php 24352 2009-07-24 06:44:32Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Id Id for the signed identifier
|
54 |
+
* @property string $Start The time at which the Shared Access Signature becomes valid.
|
55 |
+
* @property string $Expiry The time at which the Shared Access Signature becomes invalid.
|
56 |
+
* @property string $Permissions Signed permissions - read (r), write (w), delete (d) and list (l)
|
57 |
+
*/
|
58 |
+
class Microsoft_WindowsAzure_Storage_SignedIdentifier
|
59 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
60 |
+
{
|
61 |
+
/**
|
62 |
+
* Constructor
|
63 |
+
*
|
64 |
+
* @param string $id Id for the signed identifier
|
65 |
+
* @param string $start The time at which the Shared Access Signature becomes valid.
|
66 |
+
* @param string $expiry The time at which the Shared Access Signature becomes invalid.
|
67 |
+
* @param string $permissions Signed permissions - read (r), write (w), delete (d) and list (l)
|
68 |
+
*/
|
69 |
+
public function __construct($id = '', $start = '', $expiry = '', $permissions = '')
|
70 |
+
{
|
71 |
+
$this->_data = array(
|
72 |
+
'id' => $id,
|
73 |
+
'start' => $start,
|
74 |
+
'expiry' => $expiry,
|
75 |
+
'permissions' => $permissions
|
76 |
+
);
|
77 |
+
}
|
78 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 45390 2010-04-19 08:28:21Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @category Microsoft
|
44 |
+
* @package Microsoft_WindowsAzure
|
45 |
+
* @subpackage Storage
|
46 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
47 |
+
* @license http://phpazure.codeplex.com/license
|
48 |
+
*
|
49 |
+
*/
|
50 |
+
abstract class Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
51 |
+
{
|
52 |
+
/**
|
53 |
+
* Data
|
54 |
+
*
|
55 |
+
* @var array
|
56 |
+
*/
|
57 |
+
protected $_data = null;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Magic overload for setting properties
|
61 |
+
*
|
62 |
+
* @param string $name Name of the property
|
63 |
+
* @param string $value Value to set
|
64 |
+
*/
|
65 |
+
public function __set($name, $value) {
|
66 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
67 |
+
$this->_data[strtolower($name)] = $value;
|
68 |
+
return;
|
69 |
+
}
|
70 |
+
|
71 |
+
throw new Exception("Unknown property: " . $name);
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Magic overload for getting properties
|
76 |
+
*
|
77 |
+
* @param string $name Name of the property
|
78 |
+
*/
|
79 |
+
public function __get($name) {
|
80 |
+
if (array_key_exists(strtolower($name), $this->_data)) {
|
81 |
+
return $this->_data[strtolower($name)];
|
82 |
+
}
|
83 |
+
|
84 |
+
throw new Exception("Unknown property: " . $name);
|
85 |
+
}
|
86 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/Table.php
ADDED
@@ -0,0 +1,919 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Blob.php 14561 2009-05-07 08:05:12Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Credentials_CredentialsAbstract
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Credentials/CredentialsAbstract.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedKey
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKey.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @see Microsoft_WindowsAzure_Credentials_SharedKeyLite
|
48 |
+
*/
|
49 |
+
require_once 'Microsoft/WindowsAzure/Credentials/SharedKeyLite.php';
|
50 |
+
|
51 |
+
/**
|
52 |
+
* @see Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract
|
53 |
+
*/
|
54 |
+
require_once 'Microsoft/WindowsAzure/RetryPolicy/RetryPolicyAbstract.php';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @see Microsoft_Http_Client
|
58 |
+
*/
|
59 |
+
require_once 'Microsoft/Http/Client.php';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* @see Microsoft_Http_Response
|
63 |
+
*/
|
64 |
+
require_once 'Microsoft/Http/Response.php';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* @see Microsoft_WindowsAzure_Storage
|
68 |
+
*/
|
69 |
+
require_once 'Microsoft/WindowsAzure/Storage.php';
|
70 |
+
|
71 |
+
/**
|
72 |
+
* @see Microsoft_WindowsAzure_Storage_BatchStorageAbstract
|
73 |
+
*/
|
74 |
+
require_once 'Microsoft/WindowsAzure/Storage/BatchStorageAbstract.php';
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @see Microsoft_WindowsAzure_Storage_TableInstance
|
78 |
+
*/
|
79 |
+
require_once 'Microsoft/WindowsAzure/Storage/TableInstance.php';
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @see Microsoft_WindowsAzure_Storage_TableEntity
|
83 |
+
*/
|
84 |
+
require_once 'Microsoft/WindowsAzure/Storage/TableEntity.php';
|
85 |
+
|
86 |
+
/**
|
87 |
+
* @see Microsoft_WindowsAzure_Storage_DynamicTableEntity
|
88 |
+
*/
|
89 |
+
require_once 'Microsoft/WindowsAzure/Storage/DynamicTableEntity.php';
|
90 |
+
|
91 |
+
/**
|
92 |
+
* @see Microsoft_WindowsAzure_Storage_TableEntityQuery
|
93 |
+
*/
|
94 |
+
require_once 'Microsoft/WindowsAzure/Storage/TableEntityQuery.php';
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @see Microsoft_WindowsAzure_Exception
|
98 |
+
*/
|
99 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
100 |
+
|
101 |
+
|
102 |
+
/**
|
103 |
+
* @category Microsoft
|
104 |
+
* @package Microsoft_WindowsAzure
|
105 |
+
* @subpackage Storage
|
106 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
107 |
+
* @license http://phpazure.codeplex.com/license
|
108 |
+
*/
|
109 |
+
class Microsoft_WindowsAzure_Storage_Table
|
110 |
+
extends Microsoft_WindowsAzure_Storage_BatchStorageAbstract
|
111 |
+
{
|
112 |
+
/**
|
113 |
+
* Throw Microsoft_WindowsAzure_Exception when a property is not specified in Windows Azure?
|
114 |
+
* Defaults to true, making behaviour similar to Windows Azure StorageClient in .NET.
|
115 |
+
*
|
116 |
+
* @var boolean
|
117 |
+
*/
|
118 |
+
protected $_throwExceptionOnMissingData = true;
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Throw Microsoft_WindowsAzure_Exception when a property is not specified in Windows Azure?
|
122 |
+
* Defaults to true, making behaviour similar to Windows Azure StorageClient in .NET.
|
123 |
+
*
|
124 |
+
* @param boolean $value
|
125 |
+
*/
|
126 |
+
public function setThrowExceptionOnMissingData($value = true)
|
127 |
+
{
|
128 |
+
$this->_throwExceptionOnMissingData = $value;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Throw Microsoft_WindowsAzure_Exception when a property is not specified in Windows Azure?
|
133 |
+
*/
|
134 |
+
public function getThrowExceptionOnMissingData()
|
135 |
+
{
|
136 |
+
return $this->_throwExceptionOnMissingData;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* Creates a new Microsoft_WindowsAzure_Storage_Table instance
|
141 |
+
*
|
142 |
+
* @param string $host Storage host name
|
143 |
+
* @param string $accountName Account name for Windows Azure
|
144 |
+
* @param string $accountKey Account key for Windows Azure
|
145 |
+
* @param boolean $usePathStyleUri Use path-style URI's
|
146 |
+
* @param Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy Retry policy to use when making requests
|
147 |
+
*/
|
148 |
+
public function __construct($host = Microsoft_WindowsAzure_Storage::URL_DEV_TABLE, $accountName = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_ACCOUNT, $accountKey = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::DEVSTORE_KEY, $usePathStyleUri = false, Microsoft_WindowsAzure_RetryPolicy_RetryPolicyAbstract $retryPolicy = null)
|
149 |
+
{
|
150 |
+
parent::__construct($host, $accountName, $accountKey, $usePathStyleUri, $retryPolicy);
|
151 |
+
|
152 |
+
// Always use SharedKeyLite authentication
|
153 |
+
$this->_credentials = new Microsoft_WindowsAzure_Credentials_SharedKeyLite($accountName, $accountKey, $this->_usePathStyleUri);
|
154 |
+
|
155 |
+
// API version
|
156 |
+
$this->_apiVersion = '2009-09-19';
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Check if a table exists
|
161 |
+
*
|
162 |
+
* @param string $tableName Table name
|
163 |
+
* @return boolean
|
164 |
+
*/
|
165 |
+
public function tableExists($tableName = '')
|
166 |
+
{
|
167 |
+
if ($tableName === '') {
|
168 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
169 |
+
}
|
170 |
+
|
171 |
+
// List tables
|
172 |
+
$tables = $this->listTables(); // 2009-09-19 does not support $this->listTables($tableName); all of a sudden...
|
173 |
+
foreach ($tables as $table) {
|
174 |
+
if ($table->Name == $tableName) {
|
175 |
+
return true;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
return false;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* List tables
|
184 |
+
*
|
185 |
+
* @param string $nextTableName Next table name, used for listing tables when total amount of tables is > 1000.
|
186 |
+
* @return array
|
187 |
+
* @throws Microsoft_WindowsAzure_Exception
|
188 |
+
*/
|
189 |
+
public function listTables($nextTableName = '')
|
190 |
+
{
|
191 |
+
// Build query string
|
192 |
+
$queryString = array();
|
193 |
+
if ($nextTableName != '') {
|
194 |
+
$queryString[] = 'NextTableName=' . $nextTableName;
|
195 |
+
}
|
196 |
+
$queryString = self::createQueryStringFromArray($queryString);
|
197 |
+
|
198 |
+
// Perform request
|
199 |
+
$response = $this->_performRequest('Tables', $queryString, Microsoft_Http_Client::GET, null, true);
|
200 |
+
if ($response->isSuccessful()) {
|
201 |
+
// Parse result
|
202 |
+
$result = $this->_parseResponse($response);
|
203 |
+
|
204 |
+
if (!$result || !$result->entry) {
|
205 |
+
return array();
|
206 |
+
}
|
207 |
+
|
208 |
+
$entries = null;
|
209 |
+
if (count($result->entry) > 1) {
|
210 |
+
$entries = $result->entry;
|
211 |
+
} else {
|
212 |
+
$entries = array($result->entry);
|
213 |
+
}
|
214 |
+
|
215 |
+
// Create return value
|
216 |
+
$returnValue = array();
|
217 |
+
foreach ($entries as $entry) {
|
218 |
+
$tableName = $entry->xpath('.//m:properties/d:TableName');
|
219 |
+
$tableName = (string)$tableName[0];
|
220 |
+
|
221 |
+
$returnValue[] = new Microsoft_WindowsAzure_Storage_TableInstance(
|
222 |
+
(string)$entry->id,
|
223 |
+
$tableName,
|
224 |
+
(string)$entry->link['href'],
|
225 |
+
(string)$entry->updated
|
226 |
+
);
|
227 |
+
}
|
228 |
+
|
229 |
+
// More tables?
|
230 |
+
if (!is_null($response->getHeader('x-ms-continuation-NextTableName'))) {
|
231 |
+
$returnValue = array_merge($returnValue, $this->listTables($response->getHeader('x-ms-continuation-NextTableName')));
|
232 |
+
}
|
233 |
+
|
234 |
+
return $returnValue;
|
235 |
+
} else {
|
236 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
237 |
+
}
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* Create table
|
242 |
+
*
|
243 |
+
* @param string $tableName Table name
|
244 |
+
* @return Microsoft_WindowsAzure_Storage_TableInstance
|
245 |
+
* @throws Microsoft_WindowsAzure_Exception
|
246 |
+
*/
|
247 |
+
public function createTable($tableName = '')
|
248 |
+
{
|
249 |
+
if ($tableName === '') {
|
250 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
251 |
+
}
|
252 |
+
|
253 |
+
// Generate request body
|
254 |
+
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
255 |
+
<entry
|
256 |
+
xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices"
|
257 |
+
xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"
|
258 |
+
xmlns="http://www.w3.org/2005/Atom">
|
259 |
+
<title />
|
260 |
+
<updated>{tpl:Updated}</updated>
|
261 |
+
<author>
|
262 |
+
<name />
|
263 |
+
</author>
|
264 |
+
<id />
|
265 |
+
<content type="application/xml">
|
266 |
+
<m:properties>
|
267 |
+
<d:TableName>{tpl:TableName}</d:TableName>
|
268 |
+
</m:properties>
|
269 |
+
</content>
|
270 |
+
</entry>';
|
271 |
+
|
272 |
+
$requestBody = $this->_fillTemplate($requestBody, array(
|
273 |
+
'BaseUrl' => $this->getBaseUrl(),
|
274 |
+
'TableName' => htmlspecialchars($tableName),
|
275 |
+
'Updated' => $this->isoDate(),
|
276 |
+
'AccountName' => $this->_accountName
|
277 |
+
));
|
278 |
+
|
279 |
+
// Add header information
|
280 |
+
$headers = array();
|
281 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
282 |
+
$headers['DataServiceVersion'] = '1.0;NetFx';
|
283 |
+
$headers['MaxDataServiceVersion'] = '1.0;NetFx';
|
284 |
+
|
285 |
+
// Perform request
|
286 |
+
$response = $this->_performRequest('Tables', '', Microsoft_Http_Client::POST, $headers, true, $requestBody);
|
287 |
+
if ($response->isSuccessful()) {
|
288 |
+
// Parse response
|
289 |
+
$entry = $this->_parseResponse($response);
|
290 |
+
|
291 |
+
$tableName = $entry->xpath('.//m:properties/d:TableName');
|
292 |
+
$tableName = (string)$tableName[0];
|
293 |
+
|
294 |
+
return new Microsoft_WindowsAzure_Storage_TableInstance(
|
295 |
+
(string)$entry->id,
|
296 |
+
$tableName,
|
297 |
+
(string)$entry->link['href'],
|
298 |
+
(string)$entry->updated
|
299 |
+
);
|
300 |
+
} else {
|
301 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Create table if it does not exist
|
307 |
+
*
|
308 |
+
* @param string $tableName Table name
|
309 |
+
* @throws Microsoft_WindowsAzure_Exception
|
310 |
+
*/
|
311 |
+
public function createTableIfNotExists($tableName = '')
|
312 |
+
{
|
313 |
+
if (!$this->tableExists($tableName)) {
|
314 |
+
$this->createTable($tableName);
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
/**
|
319 |
+
* Delete table
|
320 |
+
*
|
321 |
+
* @param string $tableName Table name
|
322 |
+
* @throws Microsoft_WindowsAzure_Exception
|
323 |
+
*/
|
324 |
+
public function deleteTable($tableName = '')
|
325 |
+
{
|
326 |
+
if ($tableName === '') {
|
327 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
328 |
+
}
|
329 |
+
|
330 |
+
// Add header information
|
331 |
+
$headers = array();
|
332 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
333 |
+
|
334 |
+
// Perform request
|
335 |
+
$response = $this->_performRequest('Tables(\'' . $tableName . '\')', '', Microsoft_Http_Client::DELETE, $headers, true, null);
|
336 |
+
if (!$response->isSuccessful()) {
|
337 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
338 |
+
}
|
339 |
+
}
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Insert entity into table
|
343 |
+
*
|
344 |
+
* @param string $tableName Table name
|
345 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity Entity to insert
|
346 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntity
|
347 |
+
* @throws Microsoft_WindowsAzure_Exception
|
348 |
+
*/
|
349 |
+
public function insertEntity($tableName = '', Microsoft_WindowsAzure_Storage_TableEntity $entity = null)
|
350 |
+
{
|
351 |
+
if ($tableName === '') {
|
352 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
353 |
+
}
|
354 |
+
if (is_null($entity)) {
|
355 |
+
throw new Microsoft_WindowsAzure_Exception('Entity is not specified.');
|
356 |
+
}
|
357 |
+
|
358 |
+
// Generate request body
|
359 |
+
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
360 |
+
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
|
361 |
+
<title />
|
362 |
+
<updated>{tpl:Updated}</updated>
|
363 |
+
<author>
|
364 |
+
<name />
|
365 |
+
</author>
|
366 |
+
<id />
|
367 |
+
<content type="application/xml">
|
368 |
+
<m:properties>
|
369 |
+
{tpl:Properties}
|
370 |
+
</m:properties>
|
371 |
+
</content>
|
372 |
+
</entry>';
|
373 |
+
|
374 |
+
$requestBody = $this->_fillTemplate($requestBody, array(
|
375 |
+
'Updated' => $this->isoDate(),
|
376 |
+
'Properties' => $this->_generateAzureRepresentation($entity)
|
377 |
+
));
|
378 |
+
|
379 |
+
// Add header information
|
380 |
+
$headers = array();
|
381 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
382 |
+
|
383 |
+
// Perform request
|
384 |
+
$response = null;
|
385 |
+
if ($this->isInBatch()) {
|
386 |
+
$this->getCurrentBatch()->enlistOperation($tableName, '', Microsoft_Http_Client::POST, $headers, true, $requestBody);
|
387 |
+
return null;
|
388 |
+
} else {
|
389 |
+
$response = $this->_performRequest($tableName, '', Microsoft_Http_Client::POST, $headers, true, $requestBody);
|
390 |
+
}
|
391 |
+
if ($response->isSuccessful()) {
|
392 |
+
// Parse result
|
393 |
+
$result = $this->_parseResponse($response);
|
394 |
+
|
395 |
+
$timestamp = $result->xpath('//m:properties/d:Timestamp');
|
396 |
+
$timestamp = (string)$timestamp[0];
|
397 |
+
|
398 |
+
$etag = $result->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
|
399 |
+
$etag = (string)$etag['etag'];
|
400 |
+
|
401 |
+
// Update properties
|
402 |
+
$entity->setTimestamp($timestamp);
|
403 |
+
$entity->setEtag($etag);
|
404 |
+
|
405 |
+
return $entity;
|
406 |
+
} else {
|
407 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
408 |
+
}
|
409 |
+
}
|
410 |
+
|
411 |
+
/**
|
412 |
+
* Delete entity from table
|
413 |
+
*
|
414 |
+
* @param string $tableName Table name
|
415 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity Entity to delete
|
416 |
+
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
|
417 |
+
* @throws Microsoft_WindowsAzure_Exception
|
418 |
+
*/
|
419 |
+
public function deleteEntity($tableName = '', Microsoft_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
|
420 |
+
{
|
421 |
+
if ($tableName === '') {
|
422 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
423 |
+
}
|
424 |
+
if (is_null($entity)) {
|
425 |
+
throw new Microsoft_WindowsAzure_Exception('Entity is not specified.');
|
426 |
+
}
|
427 |
+
|
428 |
+
// Add header information
|
429 |
+
$headers = array();
|
430 |
+
if (!$this->isInBatch()) {
|
431 |
+
// http://social.msdn.microsoft.com/Forums/en-US/windowsazure/thread/9e255447-4dc7-458a-99d3-bdc04bdc5474/
|
432 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
433 |
+
}
|
434 |
+
$headers['Content-Length'] = 0;
|
435 |
+
if (!$verifyEtag) {
|
436 |
+
$headers['If-Match'] = '*';
|
437 |
+
} else {
|
438 |
+
$headers['If-Match'] = $entity->getEtag();
|
439 |
+
}
|
440 |
+
|
441 |
+
// Perform request
|
442 |
+
$response = null;
|
443 |
+
if ($this->isInBatch()) {
|
444 |
+
$this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Microsoft_Http_Client::DELETE, $headers, true, null);
|
445 |
+
return null;
|
446 |
+
} else {
|
447 |
+
$response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', Microsoft_Http_Client::DELETE, $headers, true, null);
|
448 |
+
}
|
449 |
+
if (!$response->isSuccessful()) {
|
450 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
451 |
+
}
|
452 |
+
}
|
453 |
+
|
454 |
+
/**
|
455 |
+
* Retrieve entity from table, by id
|
456 |
+
*
|
457 |
+
* @param string $tableName Table name
|
458 |
+
* @param string $partitionKey Partition key
|
459 |
+
* @param string $rowKey Row key
|
460 |
+
* @param string $entityClass Entity class name*
|
461 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntity
|
462 |
+
* @throws Microsoft_WindowsAzure_Exception
|
463 |
+
*/
|
464 |
+
public function retrieveEntityById($tableName = '', $partitionKey = '', $rowKey = '', $entityClass = 'Microsoft_WindowsAzure_Storage_DynamicTableEntity')
|
465 |
+
{
|
466 |
+
if ($tableName === '') {
|
467 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
468 |
+
}
|
469 |
+
if ($partitionKey === '') {
|
470 |
+
throw new Microsoft_WindowsAzure_Exception('Partition key is not specified.');
|
471 |
+
}
|
472 |
+
if ($rowKey === '') {
|
473 |
+
throw new Microsoft_WindowsAzure_Exception('Row key is not specified.');
|
474 |
+
}
|
475 |
+
if ($entityClass === '') {
|
476 |
+
throw new Microsoft_WindowsAzure_Exception('Entity class is not specified.');
|
477 |
+
}
|
478 |
+
|
479 |
+
|
480 |
+
// Check for combined size of partition key and row key
|
481 |
+
// http://msdn.microsoft.com/en-us/library/dd179421.aspx
|
482 |
+
if (strlen($partitionKey . $rowKey) >= 256) {
|
483 |
+
// Start a batch if possible
|
484 |
+
if ($this->isInBatch()) {
|
485 |
+
throw new Microsoft_WindowsAzure_Exception('Entity cannot be retrieved. A transaction is required to retrieve the entity, but another transaction is already active.');
|
486 |
+
}
|
487 |
+
|
488 |
+
$this->startBatch();
|
489 |
+
}
|
490 |
+
|
491 |
+
// Fetch entities from Azure
|
492 |
+
$result = $this->retrieveEntities(
|
493 |
+
$this->select()
|
494 |
+
->from($tableName)
|
495 |
+
->wherePartitionKey($partitionKey)
|
496 |
+
->whereRowKey($rowKey),
|
497 |
+
'',
|
498 |
+
$entityClass
|
499 |
+
);
|
500 |
+
|
501 |
+
// Return
|
502 |
+
if (count($result) == 1) {
|
503 |
+
return $result[0];
|
504 |
+
}
|
505 |
+
|
506 |
+
return null;
|
507 |
+
}
|
508 |
+
|
509 |
+
/**
|
510 |
+
* Create a new Microsoft_WindowsAzure_Storage_TableEntityQuery
|
511 |
+
*
|
512 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
513 |
+
*/
|
514 |
+
public function select()
|
515 |
+
{
|
516 |
+
return new Microsoft_WindowsAzure_Storage_TableEntityQuery();
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Retrieve entities from table
|
521 |
+
*
|
522 |
+
* @param string $tableName|Microsoft_WindowsAzure_Storage_TableEntityQuery Table name -or- Microsoft_WindowsAzure_Storage_TableEntityQuery instance
|
523 |
+
* @param string $filter Filter condition (not applied when $tableName is a Microsoft_WindowsAzure_Storage_TableEntityQuery instance)
|
524 |
+
* @param string $entityClass Entity class name
|
525 |
+
* @param string $nextPartitionKey Next partition key, used for listing entities when total amount of entities is > 1000.
|
526 |
+
* @param string $nextRowKey Next row key, used for listing entities when total amount of entities is > 1000.
|
527 |
+
* @return array Array of Microsoft_WindowsAzure_Storage_TableEntity
|
528 |
+
* @throws Microsoft_WindowsAzure_Exception
|
529 |
+
*/
|
530 |
+
public function retrieveEntities($tableName = '', $filter = '', $entityClass = 'Microsoft_WindowsAzure_Storage_DynamicTableEntity', $nextPartitionKey = null, $nextRowKey = null)
|
531 |
+
{
|
532 |
+
if ($tableName === '') {
|
533 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
534 |
+
}
|
535 |
+
if ($entityClass === '') {
|
536 |
+
throw new Microsoft_WindowsAzure_Exception('Entity class is not specified.');
|
537 |
+
}
|
538 |
+
|
539 |
+
// Convenience...
|
540 |
+
if (class_exists($filter)) {
|
541 |
+
$entityClass = $filter;
|
542 |
+
$filter = '';
|
543 |
+
}
|
544 |
+
|
545 |
+
// Query string
|
546 |
+
$queryString = '';
|
547 |
+
|
548 |
+
// Determine query
|
549 |
+
if (is_string($tableName)) {
|
550 |
+
// Option 1: $tableName is a string
|
551 |
+
|
552 |
+
// Append parentheses
|
553 |
+
$tableName .= '()';
|
554 |
+
|
555 |
+
// Build query
|
556 |
+
$query = array();
|
557 |
+
|
558 |
+
// Filter?
|
559 |
+
if ($filter !== '') {
|
560 |
+
$query[] = '$filter=' . Microsoft_WindowsAzure_Storage_TableEntityQuery::encodeQuery($filter);
|
561 |
+
}
|
562 |
+
|
563 |
+
// Build queryString
|
564 |
+
if (count($query) > 0) {
|
565 |
+
$queryString = '?' . implode('&', $query);
|
566 |
+
}
|
567 |
+
} else if (get_class($tableName) == 'Microsoft_WindowsAzure_Storage_TableEntityQuery') {
|
568 |
+
// Option 2: $tableName is a Microsoft_WindowsAzure_Storage_TableEntityQuery instance
|
569 |
+
|
570 |
+
// Build queryString
|
571 |
+
$queryString = $tableName->assembleQueryString(true);
|
572 |
+
|
573 |
+
// Change $tableName
|
574 |
+
$tableName = $tableName->assembleFrom(true);
|
575 |
+
} else {
|
576 |
+
throw new Microsoft_WindowsAzure_Exception('Invalid argument: $tableName');
|
577 |
+
}
|
578 |
+
|
579 |
+
// Add continuation querystring parameters?
|
580 |
+
if (!is_null($nextPartitionKey) && !is_null($nextRowKey)) {
|
581 |
+
if ($queryString !== '') {
|
582 |
+
$queryString .= '&';
|
583 |
+
}
|
584 |
+
|
585 |
+
$queryString .= '&NextPartitionKey=' . rawurlencode($nextPartitionKey) . '&NextRowKey=' . rawurlencode($nextRowKey);
|
586 |
+
}
|
587 |
+
|
588 |
+
// Perform request
|
589 |
+
$response = null;
|
590 |
+
if ($this->isInBatch() && $this->getCurrentBatch()->getOperationCount() == 0) {
|
591 |
+
$this->getCurrentBatch()->enlistOperation($tableName, $queryString, Microsoft_Http_Client::GET, array(), true, null);
|
592 |
+
$response = $this->getCurrentBatch()->commit();
|
593 |
+
|
594 |
+
// Get inner response (multipart)
|
595 |
+
$innerResponse = $response->getBody();
|
596 |
+
$innerResponse = substr($innerResponse, strpos($innerResponse, 'HTTP/1.1 200 OK'));
|
597 |
+
$innerResponse = substr($innerResponse, 0, strpos($innerResponse, '--batchresponse'));
|
598 |
+
$response = Microsoft_Http_Response::fromString($innerResponse);
|
599 |
+
} else {
|
600 |
+
$response = $this->_performRequest($tableName, $queryString, Microsoft_Http_Client::GET, array(), true, null);
|
601 |
+
}
|
602 |
+
|
603 |
+
if ($response->isSuccessful()) {
|
604 |
+
// Parse result
|
605 |
+
$result = $this->_parseResponse($response);
|
606 |
+
if (!$result) {
|
607 |
+
return array();
|
608 |
+
}
|
609 |
+
|
610 |
+
$entries = null;
|
611 |
+
if ($result->entry) {
|
612 |
+
if (count($result->entry) > 1) {
|
613 |
+
$entries = $result->entry;
|
614 |
+
} else {
|
615 |
+
$entries = array($result->entry);
|
616 |
+
}
|
617 |
+
} else {
|
618 |
+
// This one is tricky... If we have properties defined, we have an entity.
|
619 |
+
$properties = $result->xpath('//m:properties');
|
620 |
+
if ($properties) {
|
621 |
+
$entries = array($result);
|
622 |
+
} else {
|
623 |
+
return array();
|
624 |
+
}
|
625 |
+
}
|
626 |
+
|
627 |
+
// Create return value
|
628 |
+
$returnValue = array();
|
629 |
+
foreach ($entries as $entry) {
|
630 |
+
// Parse properties
|
631 |
+
$properties = $entry->xpath('.//m:properties');
|
632 |
+
$properties = $properties[0]->children('http://schemas.microsoft.com/ado/2007/08/dataservices');
|
633 |
+
|
634 |
+
// Create entity
|
635 |
+
$entity = new $entityClass('', '');
|
636 |
+
$entity->setAzureValues((array)$properties, $this->_throwExceptionOnMissingData);
|
637 |
+
|
638 |
+
// If we have a Microsoft_WindowsAzure_Storage_DynamicTableEntity, make sure all property types are OK
|
639 |
+
if ($entity instanceof Microsoft_WindowsAzure_Storage_DynamicTableEntity) {
|
640 |
+
foreach ($properties as $key => $value) {
|
641 |
+
$attributes = $value->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
|
642 |
+
$type = (string)$attributes['type'];
|
643 |
+
if ($type !== '') {
|
644 |
+
$entity->setAzurePropertyType($key, $type);
|
645 |
+
}
|
646 |
+
}
|
647 |
+
}
|
648 |
+
|
649 |
+
// Update etag
|
650 |
+
$etag = $entry->attributes('http://schemas.microsoft.com/ado/2007/08/dataservices/metadata');
|
651 |
+
$etag = (string)$etag['etag'];
|
652 |
+
$entity->setEtag($etag);
|
653 |
+
|
654 |
+
// Add to result
|
655 |
+
$returnValue[] = $entity;
|
656 |
+
}
|
657 |
+
|
658 |
+
// More entities?
|
659 |
+
if (!is_null($response->getHeader('x-ms-continuation-NextPartitionKey')) && !is_null($response->getHeader('x-ms-continuation-NextRowKey'))) {
|
660 |
+
if (strpos($queryString, '$top') === false) {
|
661 |
+
$returnValue = array_merge($returnValue, $this->retrieveEntities($tableName, $filter, $entityClass, $response->getHeader('x-ms-continuation-NextPartitionKey'), $response->getHeader('x-ms-continuation-NextRowKey')));
|
662 |
+
}
|
663 |
+
}
|
664 |
+
|
665 |
+
// Return
|
666 |
+
return $returnValue;
|
667 |
+
} else {
|
668 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
669 |
+
}
|
670 |
+
}
|
671 |
+
|
672 |
+
/**
|
673 |
+
* Update entity by replacing it
|
674 |
+
*
|
675 |
+
* @param string $tableName Table name
|
676 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity Entity to update
|
677 |
+
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
|
678 |
+
* @throws Microsoft_WindowsAzure_Exception
|
679 |
+
*/
|
680 |
+
public function updateEntity($tableName = '', Microsoft_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
|
681 |
+
{
|
682 |
+
return $this->_changeEntity(Microsoft_Http_Client::PUT, $tableName, $entity, $verifyEtag);
|
683 |
+
}
|
684 |
+
|
685 |
+
/**
|
686 |
+
* Update entity by adding or updating properties
|
687 |
+
*
|
688 |
+
* @param string $tableName Table name
|
689 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity Entity to update
|
690 |
+
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
|
691 |
+
* @param array $properties Properties to merge. All properties will be used when omitted.
|
692 |
+
* @throws Microsoft_WindowsAzure_Exception
|
693 |
+
*/
|
694 |
+
public function mergeEntity($tableName = '', Microsoft_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false, $properties = array())
|
695 |
+
{
|
696 |
+
$mergeEntity = null;
|
697 |
+
if (is_array($properties) && count($properties) > 0) {
|
698 |
+
// Build a new object
|
699 |
+
$mergeEntity = new Microsoft_WindowsAzure_Storage_DynamicTableEntity($entity->getPartitionKey(), $entity->getRowKey());
|
700 |
+
|
701 |
+
// Keep only values mentioned in $properties
|
702 |
+
$azureValues = $entity->getAzureValues();
|
703 |
+
foreach ($azureValues as $key => $value) {
|
704 |
+
if (in_array($value->Name, $properties)) {
|
705 |
+
$mergeEntity->setAzureProperty($value->Name, $value->Value, $value->Type);
|
706 |
+
}
|
707 |
+
}
|
708 |
+
} else {
|
709 |
+
$mergeEntity = $entity;
|
710 |
+
}
|
711 |
+
|
712 |
+
// Ensure entity timestamp matches updated timestamp
|
713 |
+
$entity->setTimestamp($this->isoDate());
|
714 |
+
|
715 |
+
return $this->_changeEntity(Microsoft_Http_Client::MERGE, $tableName, $mergeEntity, $verifyEtag);
|
716 |
+
}
|
717 |
+
|
718 |
+
/**
|
719 |
+
* Get error message from Microsoft_Http_Response
|
720 |
+
*
|
721 |
+
* @param Microsoft_Http_Response $response Repsonse
|
722 |
+
* @param string $alternativeError Alternative error message
|
723 |
+
* @return string
|
724 |
+
*/
|
725 |
+
protected function _getErrorMessage(Microsoft_Http_Response $response, $alternativeError = 'Unknown error.')
|
726 |
+
{
|
727 |
+
$response = $this->_parseResponse($response);
|
728 |
+
if ($response && $response->message) {
|
729 |
+
return (string)$response->message;
|
730 |
+
} else {
|
731 |
+
return $alternativeError;
|
732 |
+
}
|
733 |
+
}
|
734 |
+
|
735 |
+
/**
|
736 |
+
* Update entity / merge entity
|
737 |
+
*
|
738 |
+
* @param string $httpVerb HTTP verb to use (PUT = update, MERGE = merge)
|
739 |
+
* @param string $tableName Table name
|
740 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity Entity to update
|
741 |
+
* @param boolean $verifyEtag Verify etag of the entity (used for concurrency)
|
742 |
+
* @throws Microsoft_WindowsAzure_Exception
|
743 |
+
*/
|
744 |
+
protected function _changeEntity($httpVerb = Microsoft_Http_Client::PUT, $tableName = '', Microsoft_WindowsAzure_Storage_TableEntity $entity = null, $verifyEtag = false)
|
745 |
+
{
|
746 |
+
if ($tableName === '') {
|
747 |
+
throw new Microsoft_WindowsAzure_Exception('Table name is not specified.');
|
748 |
+
}
|
749 |
+
if (is_null($entity)) {
|
750 |
+
throw new Microsoft_WindowsAzure_Exception('Entity is not specified.');
|
751 |
+
}
|
752 |
+
|
753 |
+
// Add header information
|
754 |
+
$headers = array();
|
755 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
756 |
+
$headers['Content-Length'] = 0;
|
757 |
+
if (!$verifyEtag) {
|
758 |
+
$headers['If-Match'] = '*';
|
759 |
+
} else {
|
760 |
+
$headers['If-Match'] = $entity->getEtag();
|
761 |
+
}
|
762 |
+
|
763 |
+
// Generate request body
|
764 |
+
$requestBody = '<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
765 |
+
<entry xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
|
766 |
+
<title />
|
767 |
+
<updated>{tpl:Updated}</updated>
|
768 |
+
<author>
|
769 |
+
<name />
|
770 |
+
</author>
|
771 |
+
<id />
|
772 |
+
<content type="application/xml">
|
773 |
+
<m:properties>
|
774 |
+
{tpl:Properties}
|
775 |
+
</m:properties>
|
776 |
+
</content>
|
777 |
+
</entry>';
|
778 |
+
|
779 |
+
// Attempt to get timestamp from entity
|
780 |
+
$timestamp = $entity->getTimestamp();
|
781 |
+
if ($timestamp == Microsoft_WindowsAzure_Storage_TableEntity::DEFAULT_TIMESTAMP) {
|
782 |
+
$timestamp = $this->isoDate();
|
783 |
+
}
|
784 |
+
|
785 |
+
$requestBody = $this->_fillTemplate($requestBody, array(
|
786 |
+
'Updated' => $timestamp,
|
787 |
+
'Properties' => $this->_generateAzureRepresentation($entity)
|
788 |
+
));
|
789 |
+
|
790 |
+
// Add header information
|
791 |
+
$headers = array();
|
792 |
+
$headers['Content-Type'] = 'application/atom+xml';
|
793 |
+
if (!$verifyEtag) {
|
794 |
+
$headers['If-Match'] = '*';
|
795 |
+
} else {
|
796 |
+
$headers['If-Match'] = $entity->getEtag();
|
797 |
+
}
|
798 |
+
|
799 |
+
// Perform request
|
800 |
+
$response = null;
|
801 |
+
if ($this->isInBatch()) {
|
802 |
+
$this->getCurrentBatch()->enlistOperation($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody);
|
803 |
+
return null;
|
804 |
+
} else {
|
805 |
+
$response = $this->_performRequest($tableName . '(PartitionKey=\'' . $entity->getPartitionKey() . '\', RowKey=\'' . $entity->getRowKey() . '\')', '', $httpVerb, $headers, true, $requestBody);
|
806 |
+
}
|
807 |
+
if ($response->isSuccessful()) {
|
808 |
+
// Update properties
|
809 |
+
$entity->setEtag($response->getHeader('Etag'));
|
810 |
+
$entity->setTimestamp($response->getHeader('Last-modified'));
|
811 |
+
|
812 |
+
return $entity;
|
813 |
+
} else {
|
814 |
+
throw new Microsoft_WindowsAzure_Exception($this->_getErrorMessage($response, 'Resource could not be accessed.'));
|
815 |
+
}
|
816 |
+
}
|
817 |
+
|
818 |
+
/**
|
819 |
+
* Generate RFC 1123 compliant date string
|
820 |
+
*
|
821 |
+
* @return string
|
822 |
+
*/
|
823 |
+
protected function _rfcDate()
|
824 |
+
{
|
825 |
+
return gmdate('D, d M Y H:i:s', time()) . ' GMT'; // RFC 1123
|
826 |
+
}
|
827 |
+
|
828 |
+
/**
|
829 |
+
* Fill text template with variables from key/value array
|
830 |
+
*
|
831 |
+
* @param string $templateText Template text
|
832 |
+
* @param array $variables Array containing key/value pairs
|
833 |
+
* @return string
|
834 |
+
*/
|
835 |
+
protected function _fillTemplate($templateText, $variables = array())
|
836 |
+
{
|
837 |
+
foreach ($variables as $key => $value) {
|
838 |
+
$templateText = str_replace('{tpl:' . $key . '}', $value, $templateText);
|
839 |
+
}
|
840 |
+
return $templateText;
|
841 |
+
}
|
842 |
+
|
843 |
+
/**
|
844 |
+
* Generate Azure representation from entity (creates atompub markup from properties)
|
845 |
+
*
|
846 |
+
* @param Microsoft_WindowsAzure_Storage_TableEntity $entity
|
847 |
+
* @return string
|
848 |
+
*/
|
849 |
+
protected function _generateAzureRepresentation(Microsoft_WindowsAzure_Storage_TableEntity $entity = null)
|
850 |
+
{
|
851 |
+
// Generate Azure representation from entity
|
852 |
+
$azureRepresentation = array();
|
853 |
+
$azureValues = $entity->getAzureValues();
|
854 |
+
foreach ($azureValues as $azureValue) {
|
855 |
+
$value = array();
|
856 |
+
$value[] = '<d:' . $azureValue->Name;
|
857 |
+
if ($azureValue->Type != '') {
|
858 |
+
$value[] = ' m:type="' . $azureValue->Type . '"';
|
859 |
+
}
|
860 |
+
if (is_null($azureValue->Value)) {
|
861 |
+
$value[] = ' m:null="true"';
|
862 |
+
}
|
863 |
+
$value[] = '>';
|
864 |
+
|
865 |
+
if (!is_null($azureValue->Value)) {
|
866 |
+
if (strtolower($azureValue->Type) == 'edm.boolean') {
|
867 |
+
$value[] = ($azureValue->Value == true ? '1' : '0');
|
868 |
+
} else {
|
869 |
+
$value[] = htmlspecialchars($azureValue->Value);
|
870 |
+
}
|
871 |
+
}
|
872 |
+
|
873 |
+
$value[] = '</d:' . $azureValue->Name . '>';
|
874 |
+
$azureRepresentation[] = implode('', $value);
|
875 |
+
}
|
876 |
+
|
877 |
+
return implode('', $azureRepresentation);
|
878 |
+
}
|
879 |
+
|
880 |
+
/**
|
881 |
+
* Perform request using Microsoft_Http_Client channel
|
882 |
+
*
|
883 |
+
* @param string $path Path
|
884 |
+
* @param string $queryString Query string
|
885 |
+
* @param string $httpVerb HTTP verb the request will use
|
886 |
+
* @param array $headers x-ms headers to add
|
887 |
+
* @param boolean $forTableStorage Is the request for table storage?
|
888 |
+
* @param mixed $rawData Optional RAW HTTP data to be sent over the wire
|
889 |
+
* @param string $resourceType Resource type
|
890 |
+
* @param string $requiredPermission Required permission
|
891 |
+
* @return Microsoft_Http_Response
|
892 |
+
*/
|
893 |
+
protected function _performRequest(
|
894 |
+
$path = '/',
|
895 |
+
$queryString = '',
|
896 |
+
$httpVerb = Microsoft_Http_Client::GET,
|
897 |
+
$headers = array(),
|
898 |
+
$forTableStorage = false,
|
899 |
+
$rawData = null,
|
900 |
+
$resourceType = Microsoft_WindowsAzure_Storage::RESOURCE_UNKNOWN,
|
901 |
+
$requiredPermission = Microsoft_WindowsAzure_Credentials_CredentialsAbstract::PERMISSION_READ
|
902 |
+
) {
|
903 |
+
// Add headers
|
904 |
+
$headers['DataServiceVersion'] = '1.0;NetFx';
|
905 |
+
$headers['MaxDataServiceVersion'] = '1.0;NetFx';
|
906 |
+
|
907 |
+
// Perform request
|
908 |
+
return parent::_performRequest(
|
909 |
+
$path,
|
910 |
+
$queryString,
|
911 |
+
$httpVerb,
|
912 |
+
$headers,
|
913 |
+
$forTableStorage,
|
914 |
+
$rawData,
|
915 |
+
$resourceType,
|
916 |
+
$requiredPermission
|
917 |
+
);
|
918 |
+
}
|
919 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/TableEntity.php
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
|
42 |
+
/**
|
43 |
+
* @category Microsoft
|
44 |
+
* @package Microsoft_WindowsAzure
|
45 |
+
* @subpackage Storage
|
46 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
47 |
+
* @license http://phpazure.codeplex.com/license
|
48 |
+
*/
|
49 |
+
class Microsoft_WindowsAzure_Storage_TableEntity
|
50 |
+
{
|
51 |
+
/**
|
52 |
+
* Default timestamp if none has been provided
|
53 |
+
*/
|
54 |
+
const DEFAULT_TIMESTAMP = '1900-01-01T00:00:00';
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Partition key
|
58 |
+
*
|
59 |
+
* @var string
|
60 |
+
*/
|
61 |
+
protected $_partitionKey;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Row key
|
65 |
+
*
|
66 |
+
* @var string
|
67 |
+
*/
|
68 |
+
protected $_rowKey;
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Timestamp
|
72 |
+
*
|
73 |
+
* @var string
|
74 |
+
*/
|
75 |
+
protected $_timestamp;
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Etag
|
79 |
+
*
|
80 |
+
* @var string
|
81 |
+
*/
|
82 |
+
protected $_etag = '';
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Constructor
|
86 |
+
*
|
87 |
+
* @param string $partitionKey Partition key
|
88 |
+
* @param string $rowKey Row key
|
89 |
+
*/
|
90 |
+
public function __construct($partitionKey = '', $rowKey = '')
|
91 |
+
{
|
92 |
+
$this->_partitionKey = $partitionKey;
|
93 |
+
$this->_rowKey = $rowKey;
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Get partition key
|
98 |
+
*
|
99 |
+
* @azure PartitionKey
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
public function getPartitionKey()
|
103 |
+
{
|
104 |
+
return $this->_partitionKey;
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Set partition key
|
109 |
+
*
|
110 |
+
* @azure PartitionKey
|
111 |
+
* @param string $value
|
112 |
+
*/
|
113 |
+
public function setPartitionKey($value)
|
114 |
+
{
|
115 |
+
$this->_partitionKey = $value;
|
116 |
+
}
|
117 |
+
|
118 |
+
/**
|
119 |
+
* Get row key
|
120 |
+
*
|
121 |
+
* @azure RowKey
|
122 |
+
* @return string
|
123 |
+
*/
|
124 |
+
public function getRowKey()
|
125 |
+
{
|
126 |
+
return $this->_rowKey;
|
127 |
+
}
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Set row key
|
131 |
+
*
|
132 |
+
* @azure RowKey
|
133 |
+
* @param string $value
|
134 |
+
*/
|
135 |
+
public function setRowKey($value)
|
136 |
+
{
|
137 |
+
$this->_rowKey = $value;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* Get timestamp
|
142 |
+
*
|
143 |
+
* @azure Timestamp Edm.DateTime
|
144 |
+
* @return string
|
145 |
+
*/
|
146 |
+
public function getTimestamp()
|
147 |
+
{
|
148 |
+
if (null === $this->_timestamp) {
|
149 |
+
$this->setTimestamp(self::DEFAULT_TIMESTAMP);
|
150 |
+
}
|
151 |
+
return $this->_timestamp;
|
152 |
+
}
|
153 |
+
|
154 |
+
/**
|
155 |
+
* Set timestamp
|
156 |
+
*
|
157 |
+
* @azure Timestamp Edm.DateTime
|
158 |
+
* @param string $value
|
159 |
+
*/
|
160 |
+
public function setTimestamp($value = '1900-01-01T00:00:00')
|
161 |
+
{
|
162 |
+
$this->_timestamp = $value;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Get etag
|
167 |
+
*
|
168 |
+
* @return string
|
169 |
+
*/
|
170 |
+
public function getEtag()
|
171 |
+
{
|
172 |
+
return $this->_etag;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Set etag
|
177 |
+
*
|
178 |
+
* @param string $value
|
179 |
+
*/
|
180 |
+
public function setEtag($value = '')
|
181 |
+
{
|
182 |
+
$this->_etag = $value;
|
183 |
+
}
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Get Azure values
|
187 |
+
*
|
188 |
+
* @return array
|
189 |
+
*/
|
190 |
+
public function getAzureValues()
|
191 |
+
{
|
192 |
+
// Get accessors
|
193 |
+
$accessors = self::getAzureAccessors(get_class($this));
|
194 |
+
|
195 |
+
// Loop accessors and retrieve values
|
196 |
+
$returnValue = array();
|
197 |
+
foreach ($accessors as $accessor) {
|
198 |
+
if ($accessor->EntityType == 'ReflectionProperty') {
|
199 |
+
$property = $accessor->EntityAccessor;
|
200 |
+
$returnValue[] = (object)array(
|
201 |
+
'Name' => $accessor->AzurePropertyName,
|
202 |
+
'Type' => $accessor->AzurePropertyType,
|
203 |
+
'Value' => $this->$property,
|
204 |
+
);
|
205 |
+
} else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'get') {
|
206 |
+
$method = $accessor->EntityAccessor;
|
207 |
+
$returnValue[] = (object)array(
|
208 |
+
'Name' => $accessor->AzurePropertyName,
|
209 |
+
'Type' => $accessor->AzurePropertyType,
|
210 |
+
'Value' => $this->$method(),
|
211 |
+
);
|
212 |
+
}
|
213 |
+
}
|
214 |
+
|
215 |
+
// Return
|
216 |
+
return $returnValue;
|
217 |
+
}
|
218 |
+
|
219 |
+
/**
|
220 |
+
* Set Azure values
|
221 |
+
*
|
222 |
+
* @param array $values
|
223 |
+
* @param boolean $throwOnError Throw Microsoft_WindowsAzure_Exception when a property is not specified in $values?
|
224 |
+
* @throws Microsoft_WindowsAzure_Exception
|
225 |
+
*/
|
226 |
+
public function setAzureValues($values = array(), $throwOnError = false)
|
227 |
+
{
|
228 |
+
// Get accessors
|
229 |
+
$accessors = self::getAzureAccessors(get_class($this));
|
230 |
+
|
231 |
+
// Loop accessors and set values
|
232 |
+
$returnValue = array();
|
233 |
+
foreach ($accessors as $accessor) {
|
234 |
+
if (isset($values[$accessor->AzurePropertyName])) {
|
235 |
+
// Cast to correct type
|
236 |
+
if ($accessor->AzurePropertyType != '') {
|
237 |
+
switch (strtolower($accessor->AzurePropertyType)) {
|
238 |
+
case 'edm.int32':
|
239 |
+
case 'edm.int64':
|
240 |
+
$values[$accessor->AzurePropertyName] = intval($values[$accessor->AzurePropertyName]); break;
|
241 |
+
case 'edm.boolean':
|
242 |
+
if ($values[$accessor->AzurePropertyName] == 'true' || $values[$accessor->AzurePropertyName] == '1')
|
243 |
+
$values[$accessor->AzurePropertyName] = true;
|
244 |
+
else
|
245 |
+
$values[$accessor->AzurePropertyName] = false;
|
246 |
+
break;
|
247 |
+
case 'edm.double':
|
248 |
+
$values[$accessor->AzurePropertyName] = floatval($values[$accessor->AzurePropertyName]); break;
|
249 |
+
}
|
250 |
+
}
|
251 |
+
|
252 |
+
// Assign value
|
253 |
+
if ($accessor->EntityType == 'ReflectionProperty') {
|
254 |
+
$property = $accessor->EntityAccessor;
|
255 |
+
$this->$property = $values[$accessor->AzurePropertyName];
|
256 |
+
} else if ($accessor->EntityType == 'ReflectionMethod' && substr(strtolower($accessor->EntityAccessor), 0, 3) == 'set') {
|
257 |
+
$method = $accessor->EntityAccessor;
|
258 |
+
$this->$method($values[$accessor->AzurePropertyName]);
|
259 |
+
}
|
260 |
+
} else if ($throwOnError) {
|
261 |
+
throw new Microsoft_WindowsAzure_Exception("Property '" . $accessor->AzurePropertyName . "' was not found in \$values array");
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
// Return
|
266 |
+
return $returnValue;
|
267 |
+
}
|
268 |
+
|
269 |
+
/**
|
270 |
+
* Get Azure accessors from class
|
271 |
+
*
|
272 |
+
* @param string $className Class to get accessors for
|
273 |
+
* @return array
|
274 |
+
*/
|
275 |
+
public static function getAzureAccessors($className = '')
|
276 |
+
{
|
277 |
+
// List of accessors
|
278 |
+
$azureAccessors = array();
|
279 |
+
|
280 |
+
// Get all types
|
281 |
+
$type = new ReflectionClass($className);
|
282 |
+
|
283 |
+
// Loop all properties
|
284 |
+
$properties = $type->getProperties();
|
285 |
+
foreach ($properties as $property) {
|
286 |
+
$accessor = self::getAzureAccessor($property);
|
287 |
+
if (!is_null($accessor)) {
|
288 |
+
$azureAccessors[] = $accessor;
|
289 |
+
}
|
290 |
+
}
|
291 |
+
|
292 |
+
// Loop all methods
|
293 |
+
$methods = $type->getMethods();
|
294 |
+
foreach ($methods as $method) {
|
295 |
+
$accessor = self::getAzureAccessor($method);
|
296 |
+
if (!is_null($accessor)) {
|
297 |
+
$azureAccessors[] = $accessor;
|
298 |
+
}
|
299 |
+
}
|
300 |
+
|
301 |
+
// Return
|
302 |
+
return $azureAccessors;
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Get Azure accessor from reflection member
|
307 |
+
*
|
308 |
+
* @param ReflectionProperty|ReflectionMethod $member
|
309 |
+
* @return object
|
310 |
+
*/
|
311 |
+
public static function getAzureAccessor($member)
|
312 |
+
{
|
313 |
+
// Get comment
|
314 |
+
$docComment = $member->getDocComment();
|
315 |
+
|
316 |
+
// Check for Azure comment
|
317 |
+
if (strpos($docComment, '@azure') === false)
|
318 |
+
{
|
319 |
+
return null;
|
320 |
+
}
|
321 |
+
|
322 |
+
// Search for @azure contents
|
323 |
+
$azureComment = '';
|
324 |
+
$commentLines = explode("\n", $docComment);
|
325 |
+
foreach ($commentLines as $commentLine) {
|
326 |
+
if (strpos($commentLine, '@azure') !== false) {
|
327 |
+
$azureComment = trim(substr($commentLine, strpos($commentLine, '@azure') + 6));
|
328 |
+
while (strpos($azureComment, ' ') !== false) {
|
329 |
+
$azureComment = str_replace(' ', ' ', $azureComment);
|
330 |
+
}
|
331 |
+
break;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
// Fetch @azure properties
|
336 |
+
$azureProperties = explode(' ', $azureComment);
|
337 |
+
return (object)array(
|
338 |
+
'EntityAccessor' => $member->getName(),
|
339 |
+
'EntityType' => get_class($member),
|
340 |
+
'AzurePropertyName' => $azureProperties[0],
|
341 |
+
'AzurePropertyType' => isset($azureProperties[1]) ? $azureProperties[1] : ''
|
342 |
+
);
|
343 |
+
}
|
344 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/TableEntityQuery.php
ADDED
@@ -0,0 +1,363 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: Blob.php 14561 2009-05-07 08:05:12Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @category Microsoft
|
38 |
+
* @package Microsoft_WindowsAzure
|
39 |
+
* @subpackage Storage
|
40 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
41 |
+
* @license http://phpazure.codeplex.com/license
|
42 |
+
*/
|
43 |
+
class Microsoft_WindowsAzure_Storage_TableEntityQuery
|
44 |
+
{
|
45 |
+
/**
|
46 |
+
* From
|
47 |
+
*
|
48 |
+
* @var string
|
49 |
+
*/
|
50 |
+
protected $_from = '';
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Where
|
54 |
+
*
|
55 |
+
* @var array
|
56 |
+
*/
|
57 |
+
protected $_where = array();
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Order by
|
61 |
+
*
|
62 |
+
* @var array
|
63 |
+
*/
|
64 |
+
protected $_orderBy = array();
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Top
|
68 |
+
*
|
69 |
+
* @var int
|
70 |
+
*/
|
71 |
+
protected $_top = null;
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Partition key
|
75 |
+
*
|
76 |
+
* @var string
|
77 |
+
*/
|
78 |
+
protected $_partitionKey = null;
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Row key
|
82 |
+
*
|
83 |
+
* @var string
|
84 |
+
*/
|
85 |
+
protected $_rowKey = null;
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Select clause
|
89 |
+
*
|
90 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
91 |
+
*/
|
92 |
+
public function select()
|
93 |
+
{
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
/**
|
98 |
+
* From clause
|
99 |
+
*
|
100 |
+
* @param string $name Table name to select entities from
|
101 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
102 |
+
*/
|
103 |
+
public function from($name)
|
104 |
+
{
|
105 |
+
$this->_from = $name;
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Specify partition key
|
111 |
+
*
|
112 |
+
* @param string $value Partition key to query for
|
113 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
114 |
+
*/
|
115 |
+
public function wherePartitionKey($value = null)
|
116 |
+
{
|
117 |
+
$this->_partitionKey = $value;
|
118 |
+
return $this;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Specify row key
|
123 |
+
*
|
124 |
+
* @param string $value Row key to query for
|
125 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
126 |
+
*/
|
127 |
+
public function whereRowKey($value = null)
|
128 |
+
{
|
129 |
+
$this->_rowKey = $value;
|
130 |
+
return $this;
|
131 |
+
}
|
132 |
+
|
133 |
+
/**
|
134 |
+
* Add where clause
|
135 |
+
*
|
136 |
+
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
|
137 |
+
* @param string|array $value Value(s) to insert in question mark (?) parameters.
|
138 |
+
* @param string $cond Condition for the clause (and/or/not)
|
139 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
140 |
+
*/
|
141 |
+
public function where($condition, $value = null, $cond = '')
|
142 |
+
{
|
143 |
+
$condition = $this->_replaceOperators($condition);
|
144 |
+
|
145 |
+
if (!is_null($value)) {
|
146 |
+
$condition = $this->_quoteInto($condition, $value);
|
147 |
+
}
|
148 |
+
|
149 |
+
if (count($this->_where) == 0) {
|
150 |
+
$cond = '';
|
151 |
+
} else if ($cond !== '') {
|
152 |
+
$cond = ' ' . strtolower(trim($cond)) . ' ';
|
153 |
+
}
|
154 |
+
|
155 |
+
$this->_where[] = $cond . $condition;
|
156 |
+
return $this;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Add where clause with AND condition
|
161 |
+
*
|
162 |
+
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
|
163 |
+
* @param string|array $value Value(s) to insert in question mark (?) parameters.
|
164 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
165 |
+
*/
|
166 |
+
public function andWhere($condition, $value = null)
|
167 |
+
{
|
168 |
+
return $this->where($condition, $value, 'and');
|
169 |
+
}
|
170 |
+
|
171 |
+
/**
|
172 |
+
* Add where clause with OR condition
|
173 |
+
*
|
174 |
+
* @param string $condition Condition, can contain question mark(s) (?) for parameter insertion.
|
175 |
+
* @param string|array $value Value(s) to insert in question mark (?) parameters.
|
176 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
177 |
+
*/
|
178 |
+
public function orWhere($condition, $value = null)
|
179 |
+
{
|
180 |
+
return $this->where($condition, $value, 'or');
|
181 |
+
}
|
182 |
+
|
183 |
+
/**
|
184 |
+
* OrderBy clause
|
185 |
+
*
|
186 |
+
* @param string $column Column to sort by
|
187 |
+
* @param string $direction Direction to sort (asc/desc)
|
188 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
189 |
+
*/
|
190 |
+
public function orderBy($column, $direction = 'asc')
|
191 |
+
{
|
192 |
+
$this->_orderBy[] = $column . ' ' . $direction;
|
193 |
+
return $this;
|
194 |
+
}
|
195 |
+
|
196 |
+
/**
|
197 |
+
* Top clause
|
198 |
+
*
|
199 |
+
* @param int $top Top to fetch
|
200 |
+
* @return Microsoft_WindowsAzure_Storage_TableEntityQuery
|
201 |
+
*/
|
202 |
+
public function top($top = null)
|
203 |
+
{
|
204 |
+
$this->_top = (int)$top;
|
205 |
+
return $this;
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Assembles the query string
|
210 |
+
*
|
211 |
+
* @param boolean $urlEncode Apply URL encoding to the query string
|
212 |
+
* @return string
|
213 |
+
*/
|
214 |
+
public function assembleQueryString($urlEncode = false)
|
215 |
+
{
|
216 |
+
$query = array();
|
217 |
+
if (count($this->_where) != 0) {
|
218 |
+
$filter = implode('', $this->_where);
|
219 |
+
$query[] = '$filter=' . ($urlEncode ? self::encodeQuery($filter) : $filter);
|
220 |
+
}
|
221 |
+
|
222 |
+
if (count($this->_orderBy) != 0) {
|
223 |
+
$orderBy = implode(',', $this->_orderBy);
|
224 |
+
$query[] = '$orderby=' . ($urlEncode ? self::encodeQuery($orderBy) : $orderBy);
|
225 |
+
}
|
226 |
+
|
227 |
+
if (!is_null($this->_top)) {
|
228 |
+
$query[] = '$top=' . $this->_top;
|
229 |
+
}
|
230 |
+
|
231 |
+
if (count($query) != 0) {
|
232 |
+
return '?' . implode('&', $query);
|
233 |
+
}
|
234 |
+
|
235 |
+
return '';
|
236 |
+
}
|
237 |
+
|
238 |
+
/**
|
239 |
+
* Assemble from
|
240 |
+
*
|
241 |
+
* @param boolean $includeParentheses Include parentheses? ()
|
242 |
+
* @return string
|
243 |
+
*/
|
244 |
+
public function assembleFrom($includeParentheses = true)
|
245 |
+
{
|
246 |
+
$identifier = '';
|
247 |
+
if ($includeParentheses) {
|
248 |
+
$identifier .= '(';
|
249 |
+
|
250 |
+
if (!is_null($this->_partitionKey)) {
|
251 |
+
$identifier .= 'PartitionKey=\'' . $this->_partitionKey . '\'';
|
252 |
+
}
|
253 |
+
|
254 |
+
if (!is_null($this->_partitionKey) && !is_null($this->_rowKey)) {
|
255 |
+
$identifier .= ', ';
|
256 |
+
}
|
257 |
+
|
258 |
+
if (!is_null($this->_rowKey)) {
|
259 |
+
$identifier .= 'RowKey=\'' . $this->_rowKey . '\'';
|
260 |
+
}
|
261 |
+
|
262 |
+
$identifier .= ')';
|
263 |
+
}
|
264 |
+
return $this->_from . $identifier;
|
265 |
+
}
|
266 |
+
|
267 |
+
/**
|
268 |
+
* Assemble full query
|
269 |
+
*
|
270 |
+
* @return string
|
271 |
+
*/
|
272 |
+
public function assembleQuery()
|
273 |
+
{
|
274 |
+
$assembledQuery = $this->assembleFrom();
|
275 |
+
|
276 |
+
$queryString = $this->assembleQueryString();
|
277 |
+
if ($queryString !== '') {
|
278 |
+
$assembledQuery .= $queryString;
|
279 |
+
}
|
280 |
+
|
281 |
+
return $assembledQuery;
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Quotes a variable into a condition
|
286 |
+
*
|
287 |
+
* @param string $text Condition, can contain question mark(s) (?) for parameter insertion.
|
288 |
+
* @param string|array $value Value(s) to insert in question mark (?) parameters.
|
289 |
+
* @return string
|
290 |
+
*/
|
291 |
+
protected function _quoteInto($text, $value = null)
|
292 |
+
{
|
293 |
+
if (!is_array($value)) {
|
294 |
+
$text = str_replace('?', '\'' . addslashes($value) . '\'', $text);
|
295 |
+
} else {
|
296 |
+
$i = 0;
|
297 |
+
while(strpos($text, '?') !== false) {
|
298 |
+
if (is_numeric($value[$i])) {
|
299 |
+
$text = substr_replace($text, $value[$i++], strpos($text, '?'), 1);
|
300 |
+
} else {
|
301 |
+
$text = substr_replace($text, '\'' . addslashes($value[$i++]) . '\'', strpos($text, '?'), 1);
|
302 |
+
}
|
303 |
+
}
|
304 |
+
}
|
305 |
+
return $text;
|
306 |
+
}
|
307 |
+
|
308 |
+
/**
|
309 |
+
* Replace operators
|
310 |
+
*
|
311 |
+
* @param string $text
|
312 |
+
* @return string
|
313 |
+
*/
|
314 |
+
protected function _replaceOperators($text)
|
315 |
+
{
|
316 |
+
$text = str_replace('==', 'eq', $text);
|
317 |
+
$text = str_replace('>', 'gt', $text);
|
318 |
+
$text = str_replace('<', 'lt', $text);
|
319 |
+
$text = str_replace('>=', 'ge', $text);
|
320 |
+
$text = str_replace('<=', 'le', $text);
|
321 |
+
$text = str_replace('!=', 'ne', $text);
|
322 |
+
|
323 |
+
$text = str_replace('&&', 'and', $text);
|
324 |
+
$text = str_replace('||', 'or', $text);
|
325 |
+
$text = str_replace('!', 'not', $text);
|
326 |
+
|
327 |
+
return $text;
|
328 |
+
}
|
329 |
+
|
330 |
+
/**
|
331 |
+
* urlencode a query
|
332 |
+
*
|
333 |
+
* @param string $query Query to encode
|
334 |
+
* @return string Encoded query
|
335 |
+
*/
|
336 |
+
public static function encodeQuery($query)
|
337 |
+
{
|
338 |
+
$query = str_replace('/', '%2F', $query);
|
339 |
+
$query = str_replace('?', '%3F', $query);
|
340 |
+
$query = str_replace(':', '%3A', $query);
|
341 |
+
$query = str_replace('@', '%40', $query);
|
342 |
+
$query = str_replace('&', '%26', $query);
|
343 |
+
$query = str_replace('=', '%3D', $query);
|
344 |
+
$query = str_replace('+', '%2B', $query);
|
345 |
+
$query = str_replace(',', '%2C', $query);
|
346 |
+
$query = str_replace('$', '%24', $query);
|
347 |
+
|
348 |
+
|
349 |
+
$query = str_replace(' ', '%20', $query);
|
350 |
+
|
351 |
+
return $query;
|
352 |
+
}
|
353 |
+
|
354 |
+
/**
|
355 |
+
* __toString overload
|
356 |
+
*
|
357 |
+
* @return string
|
358 |
+
*/
|
359 |
+
public function __toString()
|
360 |
+
{
|
361 |
+
return $this->assembleQuery();
|
362 |
+
}
|
363 |
+
}
|
app/libs/Microsoft/WindowsAzure/Storage/TableInstance.php
ADDED
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Copyright (c) 2009 - 2010, RealDolmen
|
4 |
+
* All rights reserved.
|
5 |
+
*
|
6 |
+
* Redistribution and use in source and binary forms, with or without
|
7 |
+
* modification, are permitted provided that the following conditions are met:
|
8 |
+
* * Redistributions of source code must retain the above copyright
|
9 |
+
* notice, this list of conditions and the following disclaimer.
|
10 |
+
* * Redistributions in binary form must reproduce the above copyright
|
11 |
+
* notice, this list of conditions and the following disclaimer in the
|
12 |
+
* documentation and/or other materials provided with the distribution.
|
13 |
+
* * Neither the name of RealDolmen nor the
|
14 |
+
* names of its contributors may be used to endorse or promote products
|
15 |
+
* derived from this software without specific prior written permission.
|
16 |
+
*
|
17 |
+
* THIS SOFTWARE IS PROVIDED BY RealDolmen ''AS IS'' AND ANY
|
18 |
+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19 |
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
20 |
+
* DISCLAIMED. IN NO EVENT SHALL RealDolmen BE LIABLE FOR ANY
|
21 |
+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
22 |
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
23 |
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
24 |
+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
25 |
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
26 |
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
27 |
+
*
|
28 |
+
* @category Microsoft
|
29 |
+
* @package Microsoft_WindowsAzure
|
30 |
+
* @subpackage Storage
|
31 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
32 |
+
* @license http://phpazure.codeplex.com/license
|
33 |
+
* @version $Id: BlobInstance.php 14561 2009-05-07 08:05:12Z unknown $
|
34 |
+
*/
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @see Microsoft_WindowsAzure_Exception
|
38 |
+
*/
|
39 |
+
require_once 'Microsoft/WindowsAzure/Exception.php';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @see Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
43 |
+
*/
|
44 |
+
require_once 'Microsoft/WindowsAzure/Storage/StorageEntityAbstract.php';
|
45 |
+
|
46 |
+
/**
|
47 |
+
* @category Microsoft
|
48 |
+
* @package Microsoft_WindowsAzure
|
49 |
+
* @subpackage Storage
|
50 |
+
* @copyright Copyright (c) 2009 - 2010, RealDolmen (http://www.realdolmen.com)
|
51 |
+
* @license http://phpazure.codeplex.com/license
|
52 |
+
*
|
53 |
+
* @property string $Id Id
|
54 |
+
* @property string $Name Name
|
55 |
+
* @property string $Href Href
|
56 |
+
* @property string $Updated Updated
|
57 |
+
*/
|
58 |
+
class Microsoft_WindowsAzure_Storage_TableInstance
|
59 |
+
extends Microsoft_WindowsAzure_Storage_StorageEntityAbstract
|
60 |
+
{
|
61 |
+
/**
|
62 |
+
* Constructor
|
63 |
+
*
|
64 |
+
* @param string $id Id
|
65 |
+
* @param string $name Name
|
66 |
+
* @param string $href Href
|
67 |
+
* @param string $updated Updated
|
68 |
+
*/
|
69 |
+
public function __construct($id, $name, $href, $updated)
|
70 |
+
{
|
71 |
+
$this->_data = array(
|
72 |
+
'id' => $id,
|
73 |
+
'name' => $name,
|
74 |
+
'href' => $href,
|
75 |
+
'updated' => $updated
|
76 |
+
);
|
77 |
+
}
|
78 |
+
}
|
app/libs/aws/lib/requestcore/requestcore.class.php
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
/**
|
3 |
* Handles all HTTP requests using cURL and manages the responses.
|
4 |
*
|
5 |
-
* @version 2011.01
|
6 |
* @copyright 2006-2011 Ryan Parman
|
7 |
* @copyright 2006-2010 Foleeo Inc.
|
8 |
* @copyright 2010-2011 Amazon.com, Inc. or its affiliates.
|
@@ -94,7 +94,7 @@ class RequestCore
|
|
94 |
/**
|
95 |
* Default useragent string to use.
|
96 |
*/
|
97 |
-
public $useragent = 'RequestCore/1.4';
|
98 |
|
99 |
/**
|
100 |
* File to read from while streaming up.
|
@@ -131,6 +131,16 @@ class RequestCore
|
|
131 |
*/
|
132 |
public $seek_position = null;
|
133 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
|
135 |
/*%******************************************************************************************%*/
|
136 |
// CONSTANTS
|
@@ -441,6 +451,55 @@ class RequestCore
|
|
441 |
return $this;
|
442 |
}
|
443 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
444 |
|
445 |
/*%******************************************************************************************%*/
|
446 |
// PREPARE, SEND, AND PROCESS REQUEST
|
@@ -474,7 +533,15 @@ class RequestCore
|
|
474 |
$read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size
|
475 |
$this->read_stream_read += strlen($read);
|
476 |
|
477 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
478 |
}
|
479 |
|
480 |
/**
|
@@ -502,6 +569,12 @@ class RequestCore
|
|
502 |
$written_total += $written_last;
|
503 |
}
|
504 |
|
|
|
|
|
|
|
|
|
|
|
|
|
505 |
return $written_total;
|
506 |
}
|
507 |
|
@@ -522,7 +595,6 @@ class RequestCore
|
|
522 |
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
|
523 |
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, true);
|
524 |
curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
|
525 |
-
curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
|
526 |
curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5);
|
527 |
curl_setopt($curl_handle, CURLOPT_HEADER, true);
|
528 |
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
|
@@ -533,6 +605,11 @@ class RequestCore
|
|
533 |
curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent);
|
534 |
curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback'));
|
535 |
|
|
|
|
|
|
|
|
|
|
|
536 |
// Enable a proxy connection if requested.
|
537 |
if ($this->proxy)
|
538 |
{
|
2 |
/**
|
3 |
* Handles all HTTP requests using cURL and manages the responses.
|
4 |
*
|
5 |
+
* @version 2011.03.01
|
6 |
* @copyright 2006-2011 Ryan Parman
|
7 |
* @copyright 2006-2010 Foleeo Inc.
|
8 |
* @copyright 2010-2011 Amazon.com, Inc. or its affiliates.
|
94 |
/**
|
95 |
* Default useragent string to use.
|
96 |
*/
|
97 |
+
public $useragent = 'RequestCore/1.4.1';
|
98 |
|
99 |
/**
|
100 |
* File to read from while streaming up.
|
131 |
*/
|
132 |
public $seek_position = null;
|
133 |
|
134 |
+
/**
|
135 |
+
* The user-defined callback function to call when a stream is read from.
|
136 |
+
*/
|
137 |
+
public $registered_streaming_read_callback = null;
|
138 |
+
|
139 |
+
/**
|
140 |
+
* The user-defined callback function to call when a stream is written to.
|
141 |
+
*/
|
142 |
+
public $registered_streaming_write_callback = null;
|
143 |
+
|
144 |
|
145 |
/*%******************************************************************************************%*/
|
146 |
// CONSTANTS
|
451 |
return $this;
|
452 |
}
|
453 |
|
454 |
+
/**
|
455 |
+
* Register a callback function to execute whenever a data stream is read from using
|
456 |
+
* <CFRequest::streaming_read_callback()>.
|
457 |
+
*
|
458 |
+
* The user-defined callback function should accept three arguments:
|
459 |
+
*
|
460 |
+
* <ul>
|
461 |
+
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>
|
462 |
+
* <li><code>$file_handle</code> - <code>resource</code> - Required - The file handle resource that represents the file on the local file system.</li>
|
463 |
+
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>
|
464 |
+
* </ul>
|
465 |
+
*
|
466 |
+
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>
|
467 |
+
* <li>The name of a global function to execute, passed as a string.</li>
|
468 |
+
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>
|
469 |
+
* <li>An anonymous function (PHP 5.3+).</li></ul>
|
470 |
+
* @return $this A reference to the current instance.
|
471 |
+
*/
|
472 |
+
public function register_streaming_read_callback($callback)
|
473 |
+
{
|
474 |
+
$this->registered_streaming_read_callback = $callback;
|
475 |
+
|
476 |
+
return $this;
|
477 |
+
}
|
478 |
+
|
479 |
+
/**
|
480 |
+
* Register a callback function to execute whenever a data stream is written to using
|
481 |
+
* <CFRequest::streaming_write_callback()>.
|
482 |
+
*
|
483 |
+
* The user-defined callback function should accept two arguments:
|
484 |
+
*
|
485 |
+
* <ul>
|
486 |
+
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>
|
487 |
+
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>
|
488 |
+
* </ul>
|
489 |
+
*
|
490 |
+
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>
|
491 |
+
* <li>The name of a global function to execute, passed as a string.</li>
|
492 |
+
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>
|
493 |
+
* <li>An anonymous function (PHP 5.3+).</li></ul>
|
494 |
+
* @return $this A reference to the current instance.
|
495 |
+
*/
|
496 |
+
public function register_streaming_write_callback($callback)
|
497 |
+
{
|
498 |
+
$this->registered_streaming_write_callback = $callback;
|
499 |
+
|
500 |
+
return $this;
|
501 |
+
}
|
502 |
+
|
503 |
|
504 |
/*%******************************************************************************************%*/
|
505 |
// PREPARE, SEND, AND PROCESS REQUEST
|
533 |
$read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size
|
534 |
$this->read_stream_read += strlen($read);
|
535 |
|
536 |
+
$out = $read === false ? '' : $read;
|
537 |
+
|
538 |
+
// Execute callback function
|
539 |
+
if ($this->registered_streaming_read_callback)
|
540 |
+
{
|
541 |
+
call_user_func($this->registered_streaming_read_callback, $curl_handle, $file_handle, $out);
|
542 |
+
}
|
543 |
+
|
544 |
+
return $out;
|
545 |
}
|
546 |
|
547 |
/**
|
569 |
$written_total += $written_last;
|
570 |
}
|
571 |
|
572 |
+
// Execute callback function
|
573 |
+
if ($this->registered_streaming_write_callback)
|
574 |
+
{
|
575 |
+
call_user_func($this->registered_streaming_write_callback, $curl_handle, $written_total);
|
576 |
+
}
|
577 |
+
|
578 |
return $written_total;
|
579 |
}
|
580 |
|
595 |
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false);
|
596 |
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, true);
|
597 |
curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED);
|
|
|
598 |
curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5);
|
599 |
curl_setopt($curl_handle, CURLOPT_HEADER, true);
|
600 |
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true);
|
605 |
curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent);
|
606 |
curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback'));
|
607 |
|
608 |
+
if (!ini_get('safe_mode'))
|
609 |
+
{
|
610 |
+
curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, true);
|
611 |
+
}
|
612 |
+
|
613 |
// Enable a proxy connection if requested.
|
614 |
if ($this->proxy)
|
615 |
{
|
app/libs/aws/sdk.class.php
CHANGED
@@ -102,9 +102,9 @@ function __aws_sdk_ua_callback()
|
|
102 |
// INTERMEDIARY CONSTANTS
|
103 |
|
104 |
define('CFRUNTIME_NAME', 'aws-sdk-php');
|
105 |
-
define('CFRUNTIME_VERSION', '1.2.
|
106 |
// define('CFRUNTIME_BUILD', gmdate('YmdHis', filemtime(__FILE__))); // @todo: Hardcode for release.
|
107 |
-
define('CFRUNTIME_BUILD', '
|
108 |
define('CFRUNTIME_USERAGENT', CFRUNTIME_NAME . '/' . CFRUNTIME_VERSION . ' PHP/' . PHP_VERSION . ' ' . php_uname('s') . '/' . php_uname('r') . ' Arch/' . php_uname('m') . ' SAPI/' . php_sapi_name() . ' Integer/' . PHP_INT_MAX . ' Build/' . CFRUNTIME_BUILD . __aws_sdk_ua_callback());
|
109 |
|
110 |
|
@@ -115,7 +115,7 @@ define('CFRUNTIME_USERAGENT', CFRUNTIME_NAME . '/' . CFRUNTIME_VERSION . ' PHP/'
|
|
115 |
* Core functionality and default settings shared across all SDK classes. All methods and properties in this
|
116 |
* class are inherited by the service-specific classes.
|
117 |
*
|
118 |
-
* @version 2011.01
|
119 |
* @license See the included NOTICE.md file for more information.
|
120 |
* @copyright See the included NOTICE.md file for more information.
|
121 |
* @link http://aws.amazon.com/php/ PHP Developer Center
|
@@ -304,6 +304,16 @@ class CFRuntime
|
|
304 |
*/
|
305 |
public $max_retries = 3;
|
306 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
307 |
|
308 |
/*%******************************************************************************************%*/
|
309 |
// CONSTRUCTOR
|
@@ -578,6 +588,53 @@ class CFRuntime
|
|
578 |
return $this;
|
579 |
}
|
580 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
581 |
|
582 |
/*%******************************************************************************************%*/
|
583 |
// SET CUSTOM CLASSES
|
@@ -808,6 +865,17 @@ class CFRuntime
|
|
808 |
$request->add_header('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
|
809 |
$request->set_body($querystring);
|
810 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
811 |
// Add authentication headers
|
812 |
if ($signature_version === 3)
|
813 |
{
|
102 |
// INTERMEDIARY CONSTANTS
|
103 |
|
104 |
define('CFRUNTIME_NAME', 'aws-sdk-php');
|
105 |
+
define('CFRUNTIME_VERSION', '1.2.6');
|
106 |
// define('CFRUNTIME_BUILD', gmdate('YmdHis', filemtime(__FILE__))); // @todo: Hardcode for release.
|
107 |
+
define('CFRUNTIME_BUILD', '20110302071252');
|
108 |
define('CFRUNTIME_USERAGENT', CFRUNTIME_NAME . '/' . CFRUNTIME_VERSION . ' PHP/' . PHP_VERSION . ' ' . php_uname('s') . '/' . php_uname('r') . ' Arch/' . php_uname('m') . ' SAPI/' . php_sapi_name() . ' Integer/' . PHP_INT_MAX . ' Build/' . CFRUNTIME_BUILD . __aws_sdk_ua_callback());
|
109 |
|
110 |
|
115 |
* Core functionality and default settings shared across all SDK classes. All methods and properties in this
|
116 |
* class are inherited by the service-specific classes.
|
117 |
*
|
118 |
+
* @version 2011.03.01
|
119 |
* @license See the included NOTICE.md file for more information.
|
120 |
* @copyright See the included NOTICE.md file for more information.
|
121 |
* @link http://aws.amazon.com/php/ PHP Developer Center
|
304 |
*/
|
305 |
public $max_retries = 3;
|
306 |
|
307 |
+
/**
|
308 |
+
* The user-defined callback function to call when a stream is read from.
|
309 |
+
*/
|
310 |
+
public $registered_streaming_read_callback = null;
|
311 |
+
|
312 |
+
/**
|
313 |
+
* The user-defined callback function to call when a stream is written to.
|
314 |
+
*/
|
315 |
+
public $registered_streaming_write_callback = null;
|
316 |
+
|
317 |
|
318 |
/*%******************************************************************************************%*/
|
319 |
// CONSTRUCTOR
|
588 |
return $this;
|
589 |
}
|
590 |
|
591 |
+
/**
|
592 |
+
* Register a callback function to execute whenever a data stream is read from using
|
593 |
+
* <CFRequest::streaming_read_callback()>.
|
594 |
+
*
|
595 |
+
* The user-defined callback function should accept three arguments:
|
596 |
+
*
|
597 |
+
* <ul>
|
598 |
+
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>
|
599 |
+
* <li><code>$file_handle</code> - <code>resource</code> - Required - The file handle resource that represents the file on the local file system.</li>
|
600 |
+
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>
|
601 |
+
* </ul>
|
602 |
+
*
|
603 |
+
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>
|
604 |
+
* <li>The name of a global function to execute, passed as a string.</li>
|
605 |
+
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>
|
606 |
+
* <li>An anonymous function (PHP 5.3+).</li></ul>
|
607 |
+
* @return $this A reference to the current instance.
|
608 |
+
*/
|
609 |
+
public function register_streaming_read_callback($callback)
|
610 |
+
{
|
611 |
+
$this->registered_streaming_read_callback = $callback;
|
612 |
+
return $this;
|
613 |
+
}
|
614 |
+
|
615 |
+
/**
|
616 |
+
* Register a callback function to execute whenever a data stream is written to using
|
617 |
+
* <CFRequest::streaming_write_callback()>.
|
618 |
+
*
|
619 |
+
* The user-defined callback function should accept two arguments:
|
620 |
+
*
|
621 |
+
* <ul>
|
622 |
+
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li>
|
623 |
+
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li>
|
624 |
+
* </ul>
|
625 |
+
*
|
626 |
+
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul>
|
627 |
+
* <li>The name of a global function to execute, passed as a string.</li>
|
628 |
+
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li>
|
629 |
+
* <li>An anonymous function (PHP 5.3+).</li></ul>
|
630 |
+
* @return $this A reference to the current instance.
|
631 |
+
*/
|
632 |
+
public function register_streaming_write_callback($callback)
|
633 |
+
{
|
634 |
+
$this->registered_streaming_write_callback = $callback;
|
635 |
+
return $this;
|
636 |
+
}
|
637 |
+
|
638 |
|
639 |
/*%******************************************************************************************%*/
|
640 |
// SET CUSTOM CLASSES
|
865 |
$request->add_header('Content-Type', 'application/x-www-form-urlencoded; charset=utf-8');
|
866 |
$request->set_body($querystring);
|
867 |
|
868 |
+
// Pass along registered stream callbacks
|
869 |
+
if ($this->registered_streaming_read_callback)
|
870 |
+
{
|
871 |
+
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
872 |
+
}
|
873 |
+
|
874 |
+
if ($this->registered_streaming_write_callback)
|
875 |
+
{
|
876 |
+
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
877 |
+
}
|
878 |
+
|
879 |
// Add authentication headers
|
880 |
if ($signature_version === 3)
|
881 |
{
|
app/libs/aws/services/as.class.php
CHANGED
@@ -47,7 +47,7 @@
|
|
47 |
*
|
48 |
* </ul>
|
49 |
*
|
50 |
-
* @version
|
51 |
* @license See the included NOTICE.md file for complete information.
|
52 |
* @copyright See the included NOTICE.md file for complete information.
|
53 |
* @link http://aws.amazon.com/autoscaling/Amazon Auto-Scaling
|
@@ -84,6 +84,11 @@ class AmazonAS extends CFRuntime
|
|
84 |
*/
|
85 |
const REGION_APAC_SE1 = 'autoscaling.ap-southeast-1.amazonaws.com';
|
86 |
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
/*%******************************************************************************************%*/
|
89 |
// SETTERS
|
47 |
*
|
48 |
* </ul>
|
49 |
*
|
50 |
+
* @version Tue Mar 01 17:12:19 PST 2011
|
51 |
* @license See the included NOTICE.md file for complete information.
|
52 |
* @copyright See the included NOTICE.md file for complete information.
|
53 |
* @link http://aws.amazon.com/autoscaling/Amazon Auto-Scaling
|
84 |
*/
|
85 |
const REGION_APAC_SE1 = 'autoscaling.ap-southeast-1.amazonaws.com';
|
86 |
|
87 |
+
/**
|
88 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
89 |
+
*/
|
90 |
+
const REGION_APAC_NE1 = 'autoscaling.ap-northeast-1.amazonaws.com';
|
91 |
+
|
92 |
|
93 |
/*%******************************************************************************************%*/
|
94 |
// SETTERS
|
app/libs/aws/services/cloudformation.class.php
CHANGED
@@ -33,7 +33,7 @@
|
|
33 |
* Amazon CloudFormation makes use of other AWS products. If you need additional technical information about a specific AWS
|
34 |
* product, you can find the product's technical documentation at http://aws.amazon.com/documentation/.
|
35 |
*
|
36 |
-
* @version
|
37 |
* @license See the included NOTICE.md file for complete information.
|
38 |
* @copyright See the included NOTICE.md file for complete information.
|
39 |
* @link http://aws.amazon.com/cloudformation/Amazon CloudFormation
|
@@ -70,6 +70,11 @@ class AmazonCloudFormation extends CFRuntime
|
|
70 |
*/
|
71 |
const REGION_APAC_SE1 = 'cloudformation.ap-southeast-1.amazonaws.com';
|
72 |
|
|
|
|
|
|
|
|
|
|
|
73 |
|
74 |
/*%******************************************************************************************%*/
|
75 |
// SETTERS
|
33 |
* Amazon CloudFormation makes use of other AWS products. If you need additional technical information about a specific AWS
|
34 |
* product, you can find the product's technical documentation at http://aws.amazon.com/documentation/.
|
35 |
*
|
36 |
+
* @version Tue Mar 01 17:13:02 PST 2011
|
37 |
* @license See the included NOTICE.md file for complete information.
|
38 |
* @copyright See the included NOTICE.md file for complete information.
|
39 |
* @link http://aws.amazon.com/cloudformation/Amazon CloudFormation
|
70 |
*/
|
71 |
const REGION_APAC_SE1 = 'cloudformation.ap-southeast-1.amazonaws.com';
|
72 |
|
73 |
+
/**
|
74 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
75 |
+
*/
|
76 |
+
const REGION_APAC_NE1 = 'cloudformation.ap-northeast-1.amazonaws.com';
|
77 |
+
|
78 |
|
79 |
/*%******************************************************************************************%*/
|
80 |
// SETTERS
|
app/libs/aws/services/cloudfront.class.php
CHANGED
@@ -197,6 +197,17 @@ class AmazonCloudFront extends CFRuntime
|
|
197 |
$request->request_class = $this->request_class;
|
198 |
$request->response_class = $this->response_class;
|
199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
// Generate required headers.
|
201 |
$request->set_method($method);
|
202 |
$canonical_date = gmdate($this->util->konst($this->util, 'DATE_FORMAT_RFC2616'));
|
197 |
$request->request_class = $this->request_class;
|
198 |
$request->response_class = $this->response_class;
|
199 |
|
200 |
+
// Pass along registered stream callbacks
|
201 |
+
if ($this->registered_streaming_read_callback)
|
202 |
+
{
|
203 |
+
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
204 |
+
}
|
205 |
+
|
206 |
+
if ($this->registered_streaming_write_callback)
|
207 |
+
{
|
208 |
+
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
209 |
+
}
|
210 |
+
|
211 |
// Generate required headers.
|
212 |
$request->set_method($method);
|
213 |
$canonical_date = gmdate($this->util->konst($this->util, 'DATE_FORMAT_RFC2616'));
|
app/libs/aws/services/cloudwatch.class.php
CHANGED
@@ -31,7 +31,7 @@
|
|
31 |
* automatically make changes to the resources you are monitoring, based on rules that you define. For example, you can
|
32 |
* create alarms that initiate Auto Scaling and Simple Notification Service actions on your behalf.
|
33 |
*
|
34 |
-
* @version
|
35 |
* @license See the included NOTICE.md file for complete information.
|
36 |
* @copyright See the included NOTICE.md file for complete information.
|
37 |
* @link http://aws.amazon.com/cloudwatch/Amazon CloudWatch
|
@@ -68,6 +68,11 @@ class AmazonCloudWatch extends CFRuntime
|
|
68 |
*/
|
69 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
70 |
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
/*%******************************************************************************************%*/
|
73 |
// SETTERS
|
31 |
* automatically make changes to the resources you are monitoring, based on rules that you define. For example, you can
|
32 |
* create alarms that initiate Auto Scaling and Simple Notification Service actions on your behalf.
|
33 |
*
|
34 |
+
* @version Tue Mar 01 17:13:39 PST 2011
|
35 |
* @license See the included NOTICE.md file for complete information.
|
36 |
* @copyright See the included NOTICE.md file for complete information.
|
37 |
* @link http://aws.amazon.com/cloudwatch/Amazon CloudWatch
|
68 |
*/
|
69 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
70 |
|
71 |
+
/**
|
72 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
73 |
+
*/
|
74 |
+
const REGION_APAC_NE1 = 'ap-northeast-1';
|
75 |
+
|
76 |
|
77 |
/*%******************************************************************************************%*/
|
78 |
// SETTERS
|
app/libs/aws/services/ec2.class.php
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
*
|
29 |
* Visit <a href="http://aws.amazon.com/ec2/">http://aws.amazon.com/ec2/</a> for more information.
|
30 |
*
|
31 |
-
* @version
|
32 |
* @license See the included NOTICE.md file for complete information.
|
33 |
* @copyright See the included NOTICE.md file for complete information.
|
34 |
* @link http://aws.amazon.com/ec2/Amazon Elastic Compute Cloud
|
@@ -65,6 +65,11 @@ class AmazonEC2 extends CFRuntime
|
|
65 |
*/
|
66 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
67 |
|
|
|
|
|
|
|
|
|
|
|
68 |
/**
|
69 |
* The "pending" state code of an EC2 instance. Useful for conditionals.
|
70 |
*/
|
28 |
*
|
29 |
* Visit <a href="http://aws.amazon.com/ec2/">http://aws.amazon.com/ec2/</a> for more information.
|
30 |
*
|
31 |
+
* @version Tue Mar 01 17:14:56 PST 2011
|
32 |
* @license See the included NOTICE.md file for complete information.
|
33 |
* @copyright See the included NOTICE.md file for complete information.
|
34 |
* @link http://aws.amazon.com/ec2/Amazon Elastic Compute Cloud
|
65 |
*/
|
66 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
67 |
|
68 |
+
/**
|
69 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
70 |
+
*/
|
71 |
+
const REGION_APAC_NE1 = 'ap-northeast-1';
|
72 |
+
|
73 |
/**
|
74 |
* The "pending" state code of an EC2 instance. Useful for conditionals.
|
75 |
*/
|
app/libs/aws/services/elasticbeanstalk.class.php
CHANGED
@@ -36,7 +36,7 @@
|
|
36 |
*
|
37 |
* </ul>
|
38 |
*
|
39 |
-
* @version
|
40 |
* @license See the included NOTICE.md file for complete information.
|
41 |
* @copyright See the included NOTICE.md file for complete information.
|
42 |
* @link http://aws.amazon.com/elasticbeanstalk/AWS Elastic Beanstalk
|
36 |
*
|
37 |
* </ul>
|
38 |
*
|
39 |
+
* @version Tue Mar 01 17:14:17 PST 2011
|
40 |
* @license See the included NOTICE.md file for complete information.
|
41 |
* @copyright See the included NOTICE.md file for complete information.
|
42 |
* @link http://aws.amazon.com/elasticbeanstalk/AWS Elastic Beanstalk
|
app/libs/aws/services/elb.class.php
CHANGED
@@ -20,7 +20,7 @@
|
|
20 |
* of your application. It makes it easy for you to distribute application loads between two or more EC2 instances. Elastic
|
21 |
* Load Balancing enables availability through redundancy and supports traffic growth of your application.
|
22 |
*
|
23 |
-
* @version
|
24 |
* @license See the included NOTICE.md file for complete information.
|
25 |
* @copyright See the included NOTICE.md file for complete information.
|
26 |
* @link http://aws.amazon.com/elasticloadbalancing/Amazon Elastic Load Balancing
|
@@ -57,6 +57,11 @@ class AmazonELB extends CFRuntime
|
|
57 |
*/
|
58 |
const REGION_APAC_SE1 = 'elasticloadbalancing.ap-southeast-1.amazonaws.com';
|
59 |
|
|
|
|
|
|
|
|
|
|
|
60 |
|
61 |
/*%******************************************************************************************%*/
|
62 |
// SETTERS
|
20 |
* of your application. It makes it easy for you to distribute application loads between two or more EC2 instances. Elastic
|
21 |
* Load Balancing enables availability through redundancy and supports traffic growth of your application.
|
22 |
*
|
23 |
+
* @version Tue Mar 01 17:15:42 PST 2011
|
24 |
* @license See the included NOTICE.md file for complete information.
|
25 |
* @copyright See the included NOTICE.md file for complete information.
|
26 |
* @link http://aws.amazon.com/elasticloadbalancing/Amazon Elastic Load Balancing
|
57 |
*/
|
58 |
const REGION_APAC_SE1 = 'elasticloadbalancing.ap-southeast-1.amazonaws.com';
|
59 |
|
60 |
+
/**
|
61 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
62 |
+
*/
|
63 |
+
const REGION_APAC_NE1 = 'elasticloadbalancing.ap-northeast-1.amazonaws.com';
|
64 |
+
|
65 |
|
66 |
/*%******************************************************************************************%*/
|
67 |
// SETTERS
|
app/libs/aws/services/emr.class.php
CHANGED
@@ -19,7 +19,7 @@
|
|
19 |
* This is the Amazon Elastic MapReduce API Reference Guide. This guide is for programmers who need detailed information
|
20 |
* about the Amazon Elastic MapReduce APIs.
|
21 |
*
|
22 |
-
* @version
|
23 |
* @license See the included NOTICE.md file for complete information.
|
24 |
* @copyright See the included NOTICE.md file for complete information.
|
25 |
* @link http://aws.amazon.com/elasticmapreduce/Amazon Elastic MapReduce
|
@@ -56,6 +56,11 @@ class AmazonEMR extends CFRuntime
|
|
56 |
*/
|
57 |
const REGION_APAC_SE1 = 'ap-southeast-1.elasticmapreduce.amazonaws.com';
|
58 |
|
|
|
|
|
|
|
|
|
|
|
59 |
|
60 |
/*%******************************************************************************************%*/
|
61 |
// SETTERS
|
19 |
* This is the Amazon Elastic MapReduce API Reference Guide. This guide is for programmers who need detailed information
|
20 |
* about the Amazon Elastic MapReduce APIs.
|
21 |
*
|
22 |
+
* @version Tue Mar 01 17:16:53 PST 2011
|
23 |
* @license See the included NOTICE.md file for complete information.
|
24 |
* @copyright See the included NOTICE.md file for complete information.
|
25 |
* @link http://aws.amazon.com/elasticmapreduce/Amazon Elastic MapReduce
|
56 |
*/
|
57 |
const REGION_APAC_SE1 = 'ap-southeast-1.elasticmapreduce.amazonaws.com';
|
58 |
|
59 |
+
/**
|
60 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
61 |
+
*/
|
62 |
+
const REGION_APAC_NE1 = 'ap-northeast-1.elasticmapreduce.amazonaws.com';
|
63 |
+
|
64 |
|
65 |
/*%******************************************************************************************%*/
|
66 |
// SETTERS
|
app/libs/aws/services/iam.class.php
CHANGED
@@ -44,7 +44,7 @@
|
|
44 |
* We will refer to Amazon AWS Identity and Access Management using the abbreviated form IAM. All copyrights and legal
|
45 |
* protections still apply.
|
46 |
*
|
47 |
-
* @version
|
48 |
* @license See the included NOTICE.md file for complete information.
|
49 |
* @copyright See the included NOTICE.md file for complete information.
|
50 |
* @link http://aws.amazon.com/iam/Amazon Identity and Access Management Service
|
44 |
* We will refer to Amazon AWS Identity and Access Management using the abbreviated form IAM. All copyrights and legal
|
45 |
* protections still apply.
|
46 |
*
|
47 |
+
* @version Tue Mar 01 17:17:30 PST 2011
|
48 |
* @license See the included NOTICE.md file for complete information.
|
49 |
* @copyright See the included NOTICE.md file for complete information.
|
50 |
* @link http://aws.amazon.com/iam/Amazon Identity and Access Management Service
|
app/libs/aws/services/importexport.class.php
CHANGED
@@ -22,7 +22,7 @@
|
|
22 |
* high-speed internal network and bypassing the Internet. For large data sets, AWS Import/Export is often faster than
|
23 |
* Internet transfer and more cost effective than upgrading your connectivity.
|
24 |
*
|
25 |
-
* @version
|
26 |
* @license See the included NOTICE.md file for complete information.
|
27 |
* @copyright See the included NOTICE.md file for complete information.
|
28 |
* @link http://aws.amazon.com/importexport/Amazon Import/Export Service
|
22 |
* high-speed internal network and bypassing the Internet. For large data sets, AWS Import/Export is often faster than
|
23 |
* Internet transfer and more cost effective than upgrading your connectivity.
|
24 |
*
|
25 |
+
* @version Tue Mar 01 17:18:09 PST 2011
|
26 |
* @license See the included NOTICE.md file for complete information.
|
27 |
* @copyright See the included NOTICE.md file for complete information.
|
28 |
* @link http://aws.amazon.com/importexport/Amazon Import/Export Service
|
app/libs/aws/services/rds.class.php
CHANGED
@@ -28,7 +28,7 @@
|
|
28 |
* flexible: you can scale your database instance's compute resources and storage capacity to meet your application's
|
29 |
* demand. As with all Amazon Web Services, there are no up-front investments, and you pay only for the resources you use.
|
30 |
*
|
31 |
-
* @version
|
32 |
* @license See the included NOTICE.md file for complete information.
|
33 |
* @copyright See the included NOTICE.md file for complete information.
|
34 |
* @link http://aws.amazon.com/rds/Amazon Relational Database Service
|
@@ -65,6 +65,11 @@ class AmazonRDS extends CFRuntime
|
|
65 |
*/
|
66 |
const REGION_APAC_SE1 = 'rds.ap-southeast-1.amazonaws.com';
|
67 |
|
|
|
|
|
|
|
|
|
|
|
68 |
|
69 |
/*%******************************************************************************************%*/
|
70 |
// SETTERS
|
28 |
* flexible: you can scale your database instance's compute resources and storage capacity to meet your application's
|
29 |
* demand. As with all Amazon Web Services, there are no up-front investments, and you pay only for the resources you use.
|
30 |
*
|
31 |
+
* @version Tue Mar 01 17:18:44 PST 2011
|
32 |
* @license See the included NOTICE.md file for complete information.
|
33 |
* @copyright See the included NOTICE.md file for complete information.
|
34 |
* @link http://aws.amazon.com/rds/Amazon Relational Database Service
|
65 |
*/
|
66 |
const REGION_APAC_SE1 = 'rds.ap-southeast-1.amazonaws.com';
|
67 |
|
68 |
+
/**
|
69 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
70 |
+
*/
|
71 |
+
const REGION_APAC_NE1 = 'rds.ap-northeast-1.amazonaws.com';
|
72 |
+
|
73 |
|
74 |
/*%******************************************************************************************%*/
|
75 |
// SETTERS
|
app/libs/aws/services/s3.class.php
CHANGED
@@ -49,7 +49,7 @@ class S3_Exception extends Exception {}
|
|
49 |
*
|
50 |
* Visit <http://aws.amazon.com/s3/> for more information.
|
51 |
*
|
52 |
-
* @version 2011.
|
53 |
* @license See the included NOTICE.md file for more information.
|
54 |
* @copyright See the included NOTICE.md file for more information.
|
55 |
* @link http://aws.amazon.com/s3/ Amazon Simple Storage Service
|
@@ -85,6 +85,11 @@ class AmazonS3 extends CFRuntime
|
|
85 |
*/
|
86 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
87 |
|
|
|
|
|
|
|
|
|
|
|
88 |
/**
|
89 |
* ACL: Owner-only read/write.
|
90 |
*/
|
@@ -470,6 +475,17 @@ class AmazonS3 extends CFRuntime
|
|
470 |
$request->request_class = $this->request_class;
|
471 |
$request->response_class = $this->response_class;
|
472 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
473 |
// Streaming uploads
|
474 |
if (isset($opt['fileUpload']))
|
475 |
{
|
@@ -805,16 +821,15 @@ class AmazonS3 extends CFRuntime
|
|
805 |
* Sets the region to use for subsequent Amazon S3 operations. This will also reset any prior use of
|
806 |
* <enable_path_style()>.
|
807 |
*
|
808 |
-
* @param string $region (Required) The region to use for subsequent Amazon S3 operations. [Allowed values: `AmazonS3::REGION_US_E1 `, `AmazonS3::REGION_US_W1`, `AmazonS3::REGION_EU_W1`, `AmazonS3::REGION_APAC_SE1`]
|
809 |
* @return $this A reference to the current instance.
|
810 |
*/
|
811 |
public function set_region($region)
|
812 |
{
|
813 |
switch ($region)
|
814 |
{
|
815 |
-
case self::
|
816 |
-
|
817 |
-
$this->set_hostname('s3-' . $region . '.amazonaws.com');
|
818 |
$this->enable_path_style(false);
|
819 |
break;
|
820 |
|
@@ -823,9 +838,11 @@ class AmazonS3 extends CFRuntime
|
|
823 |
$this->enable_path_style(); // Always use path-style access for EU endpoint.
|
824 |
break;
|
825 |
|
|
|
|
|
|
|
826 |
default:
|
827 |
-
|
828 |
-
$this->set_hostname(self::DEFAULT_URL);
|
829 |
$this->enable_path_style(false);
|
830 |
break;
|
831 |
}
|
@@ -870,7 +887,7 @@ class AmazonS3 extends CFRuntime
|
|
870 |
* However, bucket names must be unique across all of Amazon S3.
|
871 |
*
|
872 |
* @param string $bucket (Required) The name of the bucket to create.
|
873 |
-
* @param string $region (Required) The preferred geographical location for the bucket. [Allowed values: `AmazonS3::REGION_US_E1 `, `AmazonS3::REGION_US_W1`, `AmazonS3::REGION_EU_W1`, `AmazonS3::REGION_APAC_SE1`]
|
874 |
* @param string $acl (Optional) The ACL settings for the specified bucket. [Allowed values: <code>AmazonS3::ACL_PRIVATE</code>, <code>AmazonS3::ACL_PUBLIC</code>, <code>AmazonS3::ACL_OPEN</code>, <code>AmazonS3::ACL_AUTH_READ</code>, <code>AmazonS3::ACL_OWNER_READ</code>, <code>AmazonS3::ACL_OWNER_FULL_CONTROL</code>]. The default value is <ACL_PRIVATE>.
|
875 |
* @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
|
876 |
* <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request.</li></ul>
|
@@ -908,10 +925,8 @@ class AmazonS3 extends CFRuntime
|
|
908 |
|
909 |
switch ($region)
|
910 |
{
|
911 |
-
case self::
|
912 |
-
|
913 |
-
$xml->LocationConstraint = $region;
|
914 |
-
$opt['body'] = $xml->asXML();
|
915 |
break;
|
916 |
|
917 |
case self::REGION_EU_W1: // Ireland
|
@@ -920,8 +935,12 @@ class AmazonS3 extends CFRuntime
|
|
920 |
$opt['body'] = $xml->asXML();
|
921 |
break;
|
922 |
|
923 |
-
|
924 |
-
|
|
|
|
|
|
|
|
|
925 |
break;
|
926 |
}
|
927 |
|
49 |
*
|
50 |
* Visit <http://aws.amazon.com/s3/> for more information.
|
51 |
*
|
52 |
+
* @version 2011.03.01
|
53 |
* @license See the included NOTICE.md file for more information.
|
54 |
* @copyright See the included NOTICE.md file for more information.
|
55 |
* @link http://aws.amazon.com/s3/ Amazon Simple Storage Service
|
85 |
*/
|
86 |
const REGION_APAC_SE1 = 'ap-southeast-1';
|
87 |
|
88 |
+
/**
|
89 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
90 |
+
*/
|
91 |
+
const REGION_APAC_NE1 = 'ap-northeast-1';
|
92 |
+
|
93 |
/**
|
94 |
* ACL: Owner-only read/write.
|
95 |
*/
|
475 |
$request->request_class = $this->request_class;
|
476 |
$request->response_class = $this->response_class;
|
477 |
|
478 |
+
// Pass along registered stream callbacks
|
479 |
+
if ($this->registered_streaming_read_callback)
|
480 |
+
{
|
481 |
+
$request->register_streaming_read_callback($this->registered_streaming_read_callback);
|
482 |
+
}
|
483 |
+
|
484 |
+
if ($this->registered_streaming_write_callback)
|
485 |
+
{
|
486 |
+
$request->register_streaming_write_callback($this->registered_streaming_write_callback);
|
487 |
+
}
|
488 |
+
|
489 |
// Streaming uploads
|
490 |
if (isset($opt['fileUpload']))
|
491 |
{
|
821 |
* Sets the region to use for subsequent Amazon S3 operations. This will also reset any prior use of
|
822 |
* <enable_path_style()>.
|
823 |
*
|
824 |
+
* @param string $region (Required) The region to use for subsequent Amazon S3 operations. [Allowed values: `AmazonS3::REGION_US_E1 `, `AmazonS3::REGION_US_W1`, `AmazonS3::REGION_EU_W1`, `AmazonS3::REGION_APAC_SE1`, `AmazonS3::REGION_APAC_NE1`]
|
825 |
* @return $this A reference to the current instance.
|
826 |
*/
|
827 |
public function set_region($region)
|
828 |
{
|
829 |
switch ($region)
|
830 |
{
|
831 |
+
case self::REGION_US_E1: // Northern Virginia
|
832 |
+
$this->set_hostname(self::DEFAULT_URL);
|
|
|
833 |
$this->enable_path_style(false);
|
834 |
break;
|
835 |
|
838 |
$this->enable_path_style(); // Always use path-style access for EU endpoint.
|
839 |
break;
|
840 |
|
841 |
+
case self::REGION_US_W1: // Northern California
|
842 |
+
case self::REGION_APAC_SE1: // Singapore
|
843 |
+
case self::REGION_APAC_NE1: // Japan
|
844 |
default:
|
845 |
+
$this->set_hostname('s3-' . $region . '.amazonaws.com');
|
|
|
846 |
$this->enable_path_style(false);
|
847 |
break;
|
848 |
}
|
887 |
* However, bucket names must be unique across all of Amazon S3.
|
888 |
*
|
889 |
* @param string $bucket (Required) The name of the bucket to create.
|
890 |
+
* @param string $region (Required) The preferred geographical location for the bucket. [Allowed values: `AmazonS3::REGION_US_E1 `, `AmazonS3::REGION_US_W1`, `AmazonS3::REGION_EU_W1`, `AmazonS3::REGION_APAC_SE1`, `AmazonS3::REGION_APAC_NE1`]
|
891 |
* @param string $acl (Optional) The ACL settings for the specified bucket. [Allowed values: <code>AmazonS3::ACL_PRIVATE</code>, <code>AmazonS3::ACL_PUBLIC</code>, <code>AmazonS3::ACL_OPEN</code>, <code>AmazonS3::ACL_AUTH_READ</code>, <code>AmazonS3::ACL_OWNER_READ</code>, <code>AmazonS3::ACL_OWNER_FULL_CONTROL</code>]. The default value is <ACL_PRIVATE>.
|
892 |
* @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul>
|
893 |
* <li><code>returnCurlHandle</code> - <code>boolean</code> - Optional - A private toggle specifying that the cURL handle be returned rather than actually completing the request.</li></ul>
|
925 |
|
926 |
switch ($region)
|
927 |
{
|
928 |
+
case self::REGION_US_E1: // Northern Virginia
|
929 |
+
$opt['body'] = '';
|
|
|
|
|
930 |
break;
|
931 |
|
932 |
case self::REGION_EU_W1: // Ireland
|
935 |
$opt['body'] = $xml->asXML();
|
936 |
break;
|
937 |
|
938 |
+
case self::REGION_US_W1: // Northern California
|
939 |
+
case self::REGION_APAC_SE1: // Singapore
|
940 |
+
case self::REGION_APAC_NE1: // Japan
|
941 |
+
default:
|
942 |
+
$xml->LocationConstraint = $region;
|
943 |
+
$opt['body'] = $xml->asXML();
|
944 |
break;
|
945 |
}
|
946 |
|
app/libs/aws/services/sdb.class.php
CHANGED
@@ -31,7 +31,7 @@
|
|
31 |
*
|
32 |
* Visit <a href="http://aws.amazon.com/simpledb/">http://aws.amazon.com/simpledb/</a> for more information.
|
33 |
*
|
34 |
-
* @version
|
35 |
* @license See the included NOTICE.md file for complete information.
|
36 |
* @copyright See the included NOTICE.md file for complete information.
|
37 |
* @link http://aws.amazon.com/simpledb/Amazon SimpleDB
|
@@ -68,6 +68,11 @@ class AmazonSDB extends CFRuntime
|
|
68 |
*/
|
69 |
const REGION_APAC_SE1 = 'sdb.ap-southeast-1.amazonaws.com';
|
70 |
|
|
|
|
|
|
|
|
|
|
|
71 |
|
72 |
/*%******************************************************************************************%*/
|
73 |
// SETTERS
|
31 |
*
|
32 |
* Visit <a href="http://aws.amazon.com/simpledb/">http://aws.amazon.com/simpledb/</a> for more information.
|
33 |
*
|
34 |
+
* @version Tue Mar 01 17:19:23 PST 2011
|
35 |
* @license See the included NOTICE.md file for complete information.
|
36 |
* @copyright See the included NOTICE.md file for complete information.
|
37 |
* @link http://aws.amazon.com/simpledb/Amazon SimpleDB
|
68 |
*/
|
69 |
const REGION_APAC_SE1 = 'sdb.ap-southeast-1.amazonaws.com';
|
70 |
|
71 |
+
/**
|
72 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
73 |
+
*/
|
74 |
+
const REGION_APAC_NE1 = 'sdb.ap-northeast-1.amazonaws.com';
|
75 |
+
|
76 |
|
77 |
/*%******************************************************************************************%*/
|
78 |
// SETTERS
|
app/libs/aws/services/ses.class.php
CHANGED
@@ -23,7 +23,7 @@
|
|
23 |
* For specific details on how to construct a service request, please consult the <a
|
24 |
* href="http://docs.amazonwebservices.com/ses/latest/DeveloperGuide">Amazon SES Developer Guide</a>.
|
25 |
*
|
26 |
-
* @version
|
27 |
* @license See the included NOTICE.md file for complete information.
|
28 |
* @copyright See the included NOTICE.md file for complete information.
|
29 |
* @link http://aws.amazon.com/ses/Amazon Simple Email Service
|
23 |
* For specific details on how to construct a service request, please consult the <a
|
24 |
* href="http://docs.amazonwebservices.com/ses/latest/DeveloperGuide">Amazon SES Developer Guide</a>.
|
25 |
*
|
26 |
+
* @version Tue Mar 01 17:16:20 PST 2011
|
27 |
* @license See the included NOTICE.md file for complete information.
|
28 |
* @copyright See the included NOTICE.md file for complete information.
|
29 |
* @link http://aws.amazon.com/ses/Amazon Simple Email Service
|
app/libs/aws/services/sns.class.php
CHANGED
@@ -17,7 +17,7 @@
|
|
17 |
/**
|
18 |
|
19 |
*
|
20 |
-
* @version
|
21 |
* @license See the included NOTICE.md file for complete information.
|
22 |
* @copyright See the included NOTICE.md file for complete information.
|
23 |
* @link http://aws.amazon.com/sns/Amazon Simple Notification Service
|
@@ -30,51 +30,44 @@ class AmazonSNS extends CFRuntime
|
|
30 |
// CLASS CONSTANTS
|
31 |
|
32 |
/**
|
33 |
-
*
|
34 |
-
* Specify the default queue URL.
|
35 |
*/
|
36 |
const DEFAULT_URL = 'sns.us-east-1.amazonaws.com';
|
37 |
|
38 |
/**
|
39 |
-
*
|
40 |
-
* Specify the queue URL for the US-East (Northern Virginia) Region.
|
41 |
*/
|
42 |
const REGION_US_E1 = self::DEFAULT_URL;
|
43 |
|
44 |
/**
|
45 |
-
*
|
46 |
-
* Specify the queue URL for the US-West (Northern California) Region.
|
47 |
*/
|
48 |
const REGION_US_W1 = 'sns.us-west-1.amazonaws.com';
|
49 |
|
50 |
/**
|
51 |
-
*
|
52 |
-
* Specify the queue URL for the EU (Ireland) Region.
|
53 |
*/
|
54 |
const REGION_EU_W1 = 'sns.eu-west-1.amazonaws.com';
|
55 |
|
56 |
/**
|
57 |
-
*
|
58 |
-
* Specify the queue URL for the Asia Pacific (Singapore) Region.
|
59 |
*/
|
60 |
const REGION_APAC_SE1 = 'sns.ap-southeast-1.amazonaws.com';
|
61 |
|
|
|
|
|
|
|
|
|
|
|
62 |
|
63 |
/*%******************************************************************************************%*/
|
64 |
// SETTERS
|
65 |
|
66 |
/**
|
67 |
-
*
|
68 |
-
* This allows you to explicitly sets the region for the service to use.
|
69 |
-
*
|
70 |
-
* Access:
|
71 |
-
* public
|
72 |
-
*
|
73 |
-
* Parameters:
|
74 |
-
* $region - _string_ (Required) The region to explicitly set. Available options are <REGION_US_E1>, <REGION_US_W1>, <REGION_EU_W1>, or <REGION_APAC_SE1>.
|
75 |
*
|
76 |
-
*
|
77 |
-
*
|
78 |
*/
|
79 |
public function set_region($region)
|
80 |
{
|
@@ -87,20 +80,11 @@ class AmazonSNS extends CFRuntime
|
|
87 |
// CONVENIENCE METHODS
|
88 |
|
89 |
/**
|
90 |
-
*
|
91 |
-
* Gets a simple list of Topic ARNs.
|
92 |
*
|
93 |
-
*
|
94 |
-
*
|
95 |
-
*
|
96 |
-
* Parameters:
|
97 |
-
* $pcre - _string_ (Optional) A Perl-Compatible Regular Expression (PCRE) to filter the names against.
|
98 |
-
*
|
99 |
-
* Returns:
|
100 |
-
* _array_ A list of Topic ARNs.
|
101 |
-
*
|
102 |
-
* See Also:
|
103 |
-
* [Perl-Compatible Regular Expression (PCRE) Docs](http://php.net/pcre)
|
104 |
*/
|
105 |
public function get_topic_list($pcre = null)
|
106 |
{
|
@@ -125,18 +109,11 @@ class AmazonSNS extends CFRuntime
|
|
125 |
// CONSTRUCTOR
|
126 |
|
127 |
/**
|
128 |
-
*
|
129 |
-
* Constructs a new instance of <AmazonSNS>.
|
130 |
-
*
|
131 |
-
* Access:
|
132 |
-
* public
|
133 |
-
*
|
134 |
-
* Parameters:
|
135 |
-
* $key - _string_ (Optional) Your Amazon API Key. If blank, it will look for the <AWS_KEY> constant.
|
136 |
-
* $secret_key - _string_ (Optional) Your Amazon API Secret Key. If blank, it will look for the <AWS_SECRET_KEY> constant.
|
137 |
*
|
138 |
-
*
|
139 |
-
*
|
|
|
140 |
*/
|
141 |
public function __construct($key = null, $secret_key = null)
|
142 |
{
|
@@ -438,7 +415,6 @@ class AmazonSNS extends CFRuntime
|
|
438 |
// EXCEPTIONS
|
439 |
|
440 |
/**
|
441 |
-
* Exception
|
442 |
-
* Default SNS Exception.
|
443 |
*/
|
444 |
class SNS_Exception extends Exception {}
|
17 |
/**
|
18 |
|
19 |
*
|
20 |
+
* @version Tue Mar 01 17:20:00 PST 2011
|
21 |
* @license See the included NOTICE.md file for complete information.
|
22 |
* @copyright See the included NOTICE.md file for complete information.
|
23 |
* @link http://aws.amazon.com/sns/Amazon Simple Notification Service
|
30 |
// CLASS CONSTANTS
|
31 |
|
32 |
/**
|
33 |
+
* Specify the default queue URL.
|
|
|
34 |
*/
|
35 |
const DEFAULT_URL = 'sns.us-east-1.amazonaws.com';
|
36 |
|
37 |
/**
|
38 |
+
* Specify the queue URL for the US-East (Northern Virginia) Region.
|
|
|
39 |
*/
|
40 |
const REGION_US_E1 = self::DEFAULT_URL;
|
41 |
|
42 |
/**
|
43 |
+
* Specify the queue URL for the US-West (Northern California) Region.
|
|
|
44 |
*/
|
45 |
const REGION_US_W1 = 'sns.us-west-1.amazonaws.com';
|
46 |
|
47 |
/**
|
48 |
+
* Specify the queue URL for the EU (Ireland) Region.
|
|
|
49 |
*/
|
50 |
const REGION_EU_W1 = 'sns.eu-west-1.amazonaws.com';
|
51 |
|
52 |
/**
|
53 |
+
* Specify the queue URL for the Asia Pacific (Singapore) Region.
|
|
|
54 |
*/
|
55 |
const REGION_APAC_SE1 = 'sns.ap-southeast-1.amazonaws.com';
|
56 |
|
57 |
+
/**
|
58 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
59 |
+
*/
|
60 |
+
const REGION_APAC_NE1 = 'sns.ap-northeast-1.amazonaws.com';
|
61 |
+
|
62 |
|
63 |
/*%******************************************************************************************%*/
|
64 |
// SETTERS
|
65 |
|
66 |
/**
|
67 |
+
* This allows you to explicitly sets the region for the service to use.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
*
|
69 |
+
* @param string $region (Required) The region to use for subsequent Amazon S3 operations. [Allowed values: `AmazonSNS::REGION_US_E1 `, `AmazonSNS::REGION_US_W1`, `AmazonSNS::REGION_EU_W1`, `AmazonSNS::REGION_APAC_SE1`]
|
70 |
+
* @return $this A reference to the current instance.
|
71 |
*/
|
72 |
public function set_region($region)
|
73 |
{
|
80 |
// CONVENIENCE METHODS
|
81 |
|
82 |
/**
|
83 |
+
* Gets a simple list of Topic ARNs.
|
|
|
84 |
*
|
85 |
+
* @param string $pcre (Optional) A Perl-Compatible Regular Expression (PCRE) to filter the names against.
|
86 |
+
* @return array A list of Topic ARNs.
|
87 |
+
* @link http://php.net/pcre Perl-Compatible Regular Expression (PCRE) Docs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
*/
|
89 |
public function get_topic_list($pcre = null)
|
90 |
{
|
109 |
// CONSTRUCTOR
|
110 |
|
111 |
/**
|
112 |
+
* Constructs a new instance of <AmazonSNS>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
113 |
*
|
114 |
+
* @param string $key (Optional) Your Amazon API Key. If blank, it will look for the `AWS_KEY` constant.
|
115 |
+
* @param string $secret_key (Optional) Your Amazon API Secret Key. If blank, it will look for the `AWS_SECRET_KEY` constant.
|
116 |
+
* @return boolean <code>false</code> if no valid values are set, otherwise <code>true</code>.
|
117 |
*/
|
118 |
public function __construct($key = null, $secret_key = null)
|
119 |
{
|
415 |
// EXCEPTIONS
|
416 |
|
417 |
/**
|
418 |
+
* Default SNS Exception.
|
|
|
419 |
*/
|
420 |
class SNS_Exception extends Exception {}
|
app/libs/aws/services/sqs.class.php
CHANGED
@@ -30,7 +30,7 @@
|
|
30 |
*
|
31 |
* Visit <a href="http://aws.amazon.com/sqs/">http://aws.amazon.com/sqs/</a> for more information.
|
32 |
*
|
33 |
-
* @version
|
34 |
* @license See the included NOTICE.md file for complete information.
|
35 |
* @copyright See the included NOTICE.md file for complete information.
|
36 |
* @link http://aws.amazon.com/sqs/Amazon Simple Queue Service
|
@@ -43,51 +43,44 @@ class AmazonSQS extends CFRuntime
|
|
43 |
// CLASS CONSTANTS
|
44 |
|
45 |
/**
|
46 |
-
*
|
47 |
-
* Specify the default queue URL.
|
48 |
*/
|
49 |
const DEFAULT_URL = 'sqs.us-east-1.amazonaws.com';
|
50 |
|
51 |
/**
|
52 |
-
*
|
53 |
-
* Specify the queue URL for the US-East (Northern Virginia) Region.
|
54 |
*/
|
55 |
const REGION_US_E1 = self::DEFAULT_URL;
|
56 |
|
57 |
/**
|
58 |
-
*
|
59 |
-
* Specify the queue URL for the US-West (Northern California) Region.
|
60 |
*/
|
61 |
const REGION_US_W1 = 'sqs.us-west-1.amazonaws.com';
|
62 |
|
63 |
/**
|
64 |
-
*
|
65 |
-
* Specify the queue URL for the EU (Ireland) Region.
|
66 |
*/
|
67 |
const REGION_EU_W1 = 'sqs.eu-west-1.amazonaws.com';
|
68 |
|
69 |
/**
|
70 |
-
*
|
71 |
-
* Specify the queue URL for the Asia Pacific (Singapore) Region.
|
72 |
*/
|
73 |
const REGION_APAC_SE1 = 'sqs.ap-southeast-1.amazonaws.com';
|
74 |
|
|
|
|
|
|
|
|
|
|
|
75 |
|
76 |
/*%******************************************************************************************%*/
|
77 |
// SETTERS
|
78 |
|
79 |
/**
|
80 |
-
*
|
81 |
-
* This allows you to explicitly sets the region for the service to use.
|
82 |
-
*
|
83 |
-
* Access:
|
84 |
-
* public
|
85 |
*
|
86 |
-
*
|
87 |
-
*
|
88 |
-
*
|
89 |
-
* Returns:
|
90 |
-
* `$this`
|
91 |
*/
|
92 |
public function set_region($region)
|
93 |
{
|
@@ -100,17 +93,10 @@ class AmazonSQS extends CFRuntime
|
|
100 |
// CONVENIENCE METHODS
|
101 |
|
102 |
/**
|
103 |
-
*
|
104 |
-
* Converts a queue URI into a queue ARN.
|
105 |
-
*
|
106 |
-
* Access:
|
107 |
-
* public
|
108 |
-
*
|
109 |
-
* Parameters:
|
110 |
-
* $queue_url - _string_ (Required) The queue URL to perform the action on. Retrieved when the queue is first created.
|
111 |
*
|
112 |
-
*
|
113 |
-
*
|
114 |
*/
|
115 |
function get_queue_arn($queue_url)
|
116 |
{
|
@@ -122,17 +108,10 @@ class AmazonSQS extends CFRuntime
|
|
122 |
}
|
123 |
|
124 |
/**
|
125 |
-
*
|
126 |
-
* Returns the approximate number of messages in the queue.
|
127 |
*
|
128 |
-
*
|
129 |
-
*
|
130 |
-
*
|
131 |
-
* Parameters:
|
132 |
-
* $queue_url - _string_ (Required) The queue URL to perform the action on. Retrieved when the queue is first created.
|
133 |
-
*
|
134 |
-
* Returns:
|
135 |
-
* _mixed_ The Approximate number of messages in the queue as an integer. If the queue doesn't exist, it returns the entire <CFResponse> object.
|
136 |
*/
|
137 |
public function get_queue_size($queue_url)
|
138 |
{
|
@@ -149,20 +128,11 @@ class AmazonSQS extends CFRuntime
|
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
-
*
|
153 |
-
* ONLY lists the queue URLs, as an array, on the SQS account.
|
154 |
-
*
|
155 |
-
* Access:
|
156 |
-
* public
|
157 |
-
*
|
158 |
-
* Parameters:
|
159 |
-
* $pcre - _string_ (Optional) A Perl-Compatible Regular Expression (PCRE) to filter the names against.
|
160 |
*
|
161 |
-
*
|
162 |
-
*
|
163 |
-
*
|
164 |
-
* See Also:
|
165 |
-
* [Perl-Compatible Regular Expression (PCRE) Docs](http://php.net/pcre)
|
166 |
*/
|
167 |
public function get_queue_list($pcre = null)
|
168 |
{
|
@@ -187,18 +157,11 @@ class AmazonSQS extends CFRuntime
|
|
187 |
// CONSTRUCTOR
|
188 |
|
189 |
/**
|
190 |
-
*
|
191 |
-
* Constructs a new instance of <AmazonSQS>.
|
192 |
-
*
|
193 |
-
* Access:
|
194 |
-
* public
|
195 |
-
*
|
196 |
-
* Parameters:
|
197 |
-
* $key - _string_ (Optional) Your Amazon API Key. If blank, it will look for the <AWS_KEY> constant.
|
198 |
-
* $secret_key - _string_ (Optional) Your Amazon API Secret Key. If blank, it will look for the <AWS_SECRET_KEY> constant.
|
199 |
*
|
200 |
-
*
|
201 |
-
*
|
|
|
202 |
*/
|
203 |
public function __construct($key = null, $secret_key = null)
|
204 |
{
|
@@ -498,7 +461,6 @@ class AmazonSQS extends CFRuntime
|
|
498 |
// EXCEPTIONS
|
499 |
|
500 |
/**
|
501 |
-
* Exception
|
502 |
-
* Default SQS Exception.
|
503 |
*/
|
504 |
class SQS_Exception extends Exception {}
|
30 |
*
|
31 |
* Visit <a href="http://aws.amazon.com/sqs/">http://aws.amazon.com/sqs/</a> for more information.
|
32 |
*
|
33 |
+
* @version Tue Mar 01 17:20:35 PST 2011
|
34 |
* @license See the included NOTICE.md file for complete information.
|
35 |
* @copyright See the included NOTICE.md file for complete information.
|
36 |
* @link http://aws.amazon.com/sqs/Amazon Simple Queue Service
|
43 |
// CLASS CONSTANTS
|
44 |
|
45 |
/**
|
46 |
+
* Specify the default queue URL.
|
|
|
47 |
*/
|
48 |
const DEFAULT_URL = 'sqs.us-east-1.amazonaws.com';
|
49 |
|
50 |
/**
|
51 |
+
* Specify the queue URL for the US-East (Northern Virginia) Region.
|
|
|
52 |
*/
|
53 |
const REGION_US_E1 = self::DEFAULT_URL;
|
54 |
|
55 |
/**
|
56 |
+
* Specify the queue URL for the US-West (Northern California) Region.
|
|
|
57 |
*/
|
58 |
const REGION_US_W1 = 'sqs.us-west-1.amazonaws.com';
|
59 |
|
60 |
/**
|
61 |
+
* Specify the queue URL for the EU (Ireland) Region.
|
|
|
62 |
*/
|
63 |
const REGION_EU_W1 = 'sqs.eu-west-1.amazonaws.com';
|
64 |
|
65 |
/**
|
66 |
+
* Specify the queue URL for the Asia Pacific (Singapore) Region.
|
|
|
67 |
*/
|
68 |
const REGION_APAC_SE1 = 'sqs.ap-southeast-1.amazonaws.com';
|
69 |
|
70 |
+
/**
|
71 |
+
* Specify the queue URL for the Asia Pacific (Japan) Region.
|
72 |
+
*/
|
73 |
+
const REGION_APAC_NE1 = 'sqs.ap-northeast-1.amazonaws.com';
|
74 |
+
|
75 |
|
76 |
/*%******************************************************************************************%*/
|
77 |
// SETTERS
|
78 |
|
79 |
/**
|
80 |
+
* This allows you to explicitly sets the region for the service to use.
|
|
|
|
|
|
|
|
|
81 |
*
|
82 |
+
* @param string $region (Required) The region to use for subsequent Amazon S3 operations. [Allowed values: `AmazonSQS::REGION_US_E1 `, `AmazonSQS::REGION_US_W1`, `AmazonSQS::REGION_EU_W1`, `AmazonSQS::REGION_APAC_SE1`]
|
83 |
+
* @return $this A reference to the current instance.
|
|
|
|
|
|
|
84 |
*/
|
85 |
public function set_region($region)
|
86 |
{
|
93 |
// CONVENIENCE METHODS
|
94 |
|
95 |
/**
|
96 |
+
* Converts a queue URI into a queue ARN.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
*
|
98 |
+
* @param string $queue_url (Required) The queue URL to perform the action on. Retrieved when the queue is first created.
|
99 |
+
* @return string An ARN representation of the queue URI.
|
100 |
*/
|
101 |
function get_queue_arn($queue_url)
|
102 |
{
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* Returns the approximate number of messages in the queue.
|
|
|
112 |
*
|
113 |
+
* @param string $queue_url (Required) The queue URL to perform the action on. Retrieved when the queue is first created.
|
114 |
+
* @return mixed The Approximate number of messages in the queue as an integer. If the queue doesn't exist, it returns the entire <CFResponse> object.
|
|
|
|
|
|
|
|
|
|
|
|
|
115 |
*/
|
116 |
public function get_queue_size($queue_url)
|
117 |
{
|
128 |
}
|
129 |
|
130 |
/**
|
131 |
+
* ONLY lists the queue URLs, as an array, on the SQS account.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
*
|
133 |
+
* @param string $pcre (Optional) A Perl-Compatible Regular Expression (PCRE) to filter the names against.
|
134 |
+
* @return array The list of matching queue names. If there are no results, the method will return an empty array.
|
135 |
+
* @link http://php.net/pcre Perl-Compatible Regular Expression (PCRE) Docs
|
|
|
|
|
136 |
*/
|
137 |
public function get_queue_list($pcre = null)
|
138 |
{
|
157 |
// CONSTRUCTOR
|
158 |
|
159 |
/**
|
160 |
+
* Constructs a new instance of <AmazonSQS>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
*
|
162 |
+
* @param string $key (Optional) Your Amazon API Key. If blank, it will look for the `AWS_KEY` constant.
|
163 |
+
* @param string $secret_key (Optional) Your Amazon API Secret Key. If blank, it will look for the `AWS_SECRET_KEY` constant.
|
164 |
+
* @return boolean <code>false</code> if no valid values are set, otherwise <code>true</code>.
|
165 |
*/
|
166 |
public function __construct($key = null, $secret_key = null)
|
167 |
{
|
461 |
// EXCEPTIONS
|
462 |
|
463 |
/**
|
464 |
+
* Default SQS Exception.
|
|
|
465 |
*/
|
466 |
class SQS_Exception extends Exception {}
|
app/list-tables.php
CHANGED
@@ -469,6 +469,8 @@ class BackWPup_Backups_Table extends WP_List_Table {
|
|
469 |
$r .= "<td $attributes><strong>".basename($backup['file'])."</strong><br />ftp://".$jobvalue['ftphost'].dirname($backup['file'])."/";
|
470 |
} elseif ($backup['type']=='RSC') {
|
471 |
$r .= "<td $attributes><strong>".basename($backup['file'])."</strong><br />RSC://".$jobvalue['rscContainer']."/".dirname($backup['file'])."/";
|
|
|
|
|
472 |
}
|
473 |
$actions = array();
|
474 |
$actions['delete'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&subpage=backups&action=delete&paged='.$this->get_pagenum().'&backupfiles[]='.esc_attr($backup['file'].':'.$backup['jobid'].':'.$backup['type']), 'bulk-backups') . "\" onclick=\"if ( confirm('" . esc_js(__("You are about to delete this Backup Archive. \n 'Cancel' to stop, 'OK' to delete.","backwpup")) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
469 |
$r .= "<td $attributes><strong>".basename($backup['file'])."</strong><br />ftp://".$jobvalue['ftphost'].dirname($backup['file'])."/";
|
470 |
} elseif ($backup['type']=='RSC') {
|
471 |
$r .= "<td $attributes><strong>".basename($backup['file'])."</strong><br />RSC://".$jobvalue['rscContainer']."/".dirname($backup['file'])."/";
|
472 |
+
} elseif ($backup['type']=='MSAZURE') {
|
473 |
+
$r .= "<td $attributes><strong>".basename($backup['file'])."</strong><br />azure://".$jobvalue['msazureContainer']."/".dirname($backup['file'])."/";
|
474 |
}
|
475 |
$actions = array();
|
476 |
$actions['delete'] = "<a class=\"submitdelete\" href=\"" . wp_nonce_url('admin.php?page=BackWPup&subpage=backups&action=delete&paged='.$this->get_pagenum().'&backupfiles[]='.esc_attr($backup['file'].':'.$backup['jobid'].':'.$backup['type']), 'bulk-backups') . "\" onclick=\"if ( confirm('" . esc_js(__("You are about to delete this Backup Archive. \n 'Cancel' to stop, 'OK' to delete.","backwpup")) . "') ) { return true;}return false;\">" . __('Delete') . "</a>";
|
app/options-edit-job.php
CHANGED
@@ -367,7 +367,7 @@ $dests=explode(',',strtoupper(BACKWPUP_DESTS));
|
|
367 |
<b><?PHP _e('Bucket:','backwpup'); ?></b><br />
|
368 |
<input id="awsBucketselected" name="awsBucketselected" type="hidden" value="<?PHP echo $jobvalue['awsBucket'];?>" />
|
369 |
<?PHP if (!empty($jobvalue['awsAccessKey']) and !empty($jobvalue['awsSecretKey'])) backwpup_get_aws_buckets(array('awsAccessKey'=>$jobvalue['awsAccessKey'],'awsSecretKey'=>$jobvalue['awsSecretKey'],'awsselected'=>$jobvalue['awsBucket'])); ?>
|
370 |
-
<?PHP _e('Create Bucket:','backwpup'); ?><input name="newawsBucket" type="text" value="" class="text" /> <select name="awsRegion" title="<?php _e('Bucket Region', 'backwpup'); ?>"><option value=""><?php _e('US-East (Northern Virginia)', 'backwpup'); ?></option><option value="us-west-1"><?php _e('US-West (Northern California)', 'backwpup'); ?></option><option value="EU"><?php _e('EU (Ireland)', 'backwpup'); ?></option><option value="ap-southeast-1"><?php _e('Asia Pacific (Singapore)', 'backwpup'); ?></option></select><br />
|
371 |
<b><?PHP _e('Directory in Bucket:','backwpup'); ?></b><br />
|
372 |
<input name="awsdir" type="text" value="<?PHP echo $jobvalue['awsdir'];?>" class="large-text" /><br />
|
373 |
<?PHP _e('Max. Backup Files in Bucket Folder:','backwpup'); ?><input name="awsmaxbackups" type="text" size="3" value="<?PHP echo $jobvalue['awsmaxbackups'];?>" class="small-text" /><span class="description"><?PHP _e('(Oldest files will deleted first.)','backwpup');?></span><br />
|
@@ -376,6 +376,31 @@ $dests=explode(',',strtoupper(BACKWPUP_DESTS));
|
|
376 |
</div>
|
377 |
</div>
|
378 |
<?PHP } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
379 |
|
380 |
<?PHP if (in_array('RSC',$dests)) { ?>
|
381 |
<div id="torsc" class="postbox" <?PHP if (!in_array("FILE",$todo) and !in_array("DB",$todo) and !in_array("WPEXP",$todo)) echo 'style="display:none;"';?>>
|
@@ -401,7 +426,7 @@ $dests=explode(',',strtoupper(BACKWPUP_DESTS));
|
|
401 |
<?PHP } ?>
|
402 |
|
403 |
<?PHP if (in_array('DROPBOX',$dests)) { ?>
|
404 |
-
<div id="
|
405 |
<h3 class="hndle"><span><?PHP _e('Backup to Dropbox','backwpup'); ?></span></h3>
|
406 |
<div class="inside">
|
407 |
<b><?PHP _e('Email:','backwpup'); ?></b><br />
|
367 |
<b><?PHP _e('Bucket:','backwpup'); ?></b><br />
|
368 |
<input id="awsBucketselected" name="awsBucketselected" type="hidden" value="<?PHP echo $jobvalue['awsBucket'];?>" />
|
369 |
<?PHP if (!empty($jobvalue['awsAccessKey']) and !empty($jobvalue['awsSecretKey'])) backwpup_get_aws_buckets(array('awsAccessKey'=>$jobvalue['awsAccessKey'],'awsSecretKey'=>$jobvalue['awsSecretKey'],'awsselected'=>$jobvalue['awsBucket'])); ?>
|
370 |
+
<?PHP _e('Create Bucket:','backwpup'); ?><input name="newawsBucket" type="text" value="" class="text" /> <select name="awsRegion" title="<?php _e('Bucket Region', 'backwpup'); ?>"><option value=""><?php _e('US-East (Northern Virginia)', 'backwpup'); ?></option><option value="us-west-1"><?php _e('US-West (Northern California)', 'backwpup'); ?></option><option value="EU"><?php _e('EU (Ireland)', 'backwpup'); ?></option><option value="ap-southeast-1"><?php _e('Asia Pacific (Singapore)', 'backwpup'); ?></option><option value="ap-northeast-1"><?php _e('Asia Pacific (Japan)', 'backwpup'); ?></option></select><br />
|
371 |
<b><?PHP _e('Directory in Bucket:','backwpup'); ?></b><br />
|
372 |
<input name="awsdir" type="text" value="<?PHP echo $jobvalue['awsdir'];?>" class="large-text" /><br />
|
373 |
<?PHP _e('Max. Backup Files in Bucket Folder:','backwpup'); ?><input name="awsmaxbackups" type="text" size="3" value="<?PHP echo $jobvalue['awsmaxbackups'];?>" class="small-text" /><span class="description"><?PHP _e('(Oldest files will deleted first.)','backwpup');?></span><br />
|
376 |
</div>
|
377 |
</div>
|
378 |
<?PHP } ?>
|
379 |
+
|
380 |
+
<?PHP if (in_array('MSAZURE',$dests)) { ?>
|
381 |
+
<div id="tomsazure" class="postbox" <?PHP if (!in_array("FILE",$todo) and !in_array("DB",$todo) and !in_array("WPEXP",$todo)) echo 'style="display:none;"';?>>
|
382 |
+
<h3 class="hndle"><span><?PHP _e('Backup to Micosoft Azure (Blob)','backwpup'); ?></span></h3>
|
383 |
+
<div class="inside">
|
384 |
+
<?PHP if (!(extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll'))) {
|
385 |
+
echo "<b>".__('curl Support required','backwpup')."</b>";
|
386 |
+
} else { ?>
|
387 |
+
<b><?PHP _e('Host:','backwpup'); ?></b><br />
|
388 |
+
<input id="msazureHost" name="msazureHost" type="text" value="<?PHP echo $jobvalue['msazureHost'];?>" class="large-text" /><span class="description"><?PHP _e('Normely: blob.core.windows.net','backwpup');?></span><br />
|
389 |
+
<b><?PHP _e('Account Name:','backwpup'); ?></b><br />
|
390 |
+
<input id="msazureAccName" name="msazureAccName" type="text" value="<?PHP echo $jobvalue['msazureAccName'];?>" class="large-text" /><br />
|
391 |
+
<b><?PHP _e('Access Key:','backwpup'); ?></b><br />
|
392 |
+
<input id="msazureKey" name="msazureKey" type="password" value="<?PHP echo $jobvalue['msazureKey'];?>" class="large-text" /><br />
|
393 |
+
<b><?PHP _e('Container:','backwpup'); ?></b><br />
|
394 |
+
<input id="msazureContainerselected" name="msazureContainerselected" type="hidden" value="<?PHP echo $jobvalue['msazureContainer'];?>" />
|
395 |
+
<?PHP if (!empty($jobvalue['msazureAccName']) and !empty($jobvalue['msazureKey'])) backwpup_get_msazure_container(array('msazureHost'=>$jobvalue['msazureHost'],'msazureAccName'=>$jobvalue['msazureAccName'],'msazureKey'=>$jobvalue['msazureKey'],'msazureselected'=>$jobvalue['msazureContainer'])); ?>
|
396 |
+
<?PHP _e('Create Container:','backwpup'); ?><input name="newmsazureContainer" type="text" value="" class="text" /> <br />
|
397 |
+
<b><?PHP _e('Directory in Container:','backwpup'); ?></b><br />
|
398 |
+
<input name="msazuredir" type="text" value="<?PHP echo $jobvalue['msazuredir'];?>" class="large-text" /><br />
|
399 |
+
<?PHP _e('Max. Backup Files in Container Folder:','backwpup'); ?><input name="msazuremaxbackups" type="text" size="3" value="<?PHP echo $jobvalue['msazuremaxbackups'];?>" class="small-text" /><span class="description"><?PHP _e('(Oldest files will deleted first.)','backwpup');?></span><br />
|
400 |
+
<?PHP } ?>
|
401 |
+
</div>
|
402 |
+
</div>
|
403 |
+
<?PHP } ?>
|
404 |
|
405 |
<?PHP if (in_array('RSC',$dests)) { ?>
|
406 |
<div id="torsc" class="postbox" <?PHP if (!in_array("FILE",$todo) and !in_array("DB",$todo) and !in_array("WPEXP",$todo)) echo 'style="display:none;"';?>>
|
426 |
<?PHP } ?>
|
427 |
|
428 |
<?PHP if (in_array('DROPBOX',$dests)) { ?>
|
429 |
+
<div id="todropbox" class="postbox" <?PHP if (!in_array("FILE",$todo) and !in_array("DB",$todo) and !in_array("WPEXP",$todo)) echo 'style="display:none;"';?>>
|
430 |
<h3 class="hndle"><span><?PHP _e('Backup to Dropbox','backwpup'); ?></span></h3>
|
431 |
<div class="inside">
|
432 |
<b><?PHP _e('Email:','backwpup'); ?></b><br />
|
app/options-save.php
CHANGED
@@ -156,10 +156,13 @@ function backwpup_backups_operations($action) {
|
|
156 |
|
157 |
$jobs=get_option('backwpup_jobs'); //Load jobs
|
158 |
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
159 |
-
|
160 |
-
|
161 |
-
|
162 |
-
|
|
|
|
|
|
|
163 |
}
|
164 |
|
165 |
$num=0;
|
@@ -175,6 +178,13 @@ function backwpup_backups_operations($action) {
|
|
175 |
$s3->delete_object($jobvalue['awsBucket'],$backups['file']);
|
176 |
}
|
177 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
178 |
} elseif ($backups['type']=='RSC') {
|
179 |
if (class_exists('CF_Authentication')) {
|
180 |
if (!empty($jobvalue['rscUsername']) and !empty($jobvalue['rscAPIKey']) and !empty($jobvalue['rscContainer'])) {
|
@@ -265,6 +275,29 @@ function backwpup_backups_operations($action) {
|
|
265 |
header('HTTP/1.0 '.$s3file->status.' Not Found');
|
266 |
die();
|
267 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
268 |
break;
|
269 |
case 'downloadrsc': //Download RSC Backup
|
270 |
check_admin_referer('download-backup');
|
@@ -425,6 +458,12 @@ function backwpup_save_job() { //Save Job settings
|
|
425 |
$jobs[$jobid]['awsBucket']=$_POST['awsBucket'];
|
426 |
$jobs[$jobid]['awsdir']=stripslashes($_POST['awsdir']);
|
427 |
$jobs[$jobid]['awsmaxbackups']=(int)$_POST['awsmaxbackups'];
|
|
|
|
|
|
|
|
|
|
|
|
|
428 |
$jobs[$jobid]['rscUsername']=$_POST['rscUsername'];
|
429 |
$jobs[$jobid]['rscAPIKey']=$_POST['rscAPIKey'];
|
430 |
$jobs[$jobid]['rscContainer']=$_POST['rscContainer'];
|
@@ -442,11 +481,30 @@ function backwpup_save_job() { //Save Job settings
|
|
442 |
if (!empty($_POST['newawsBucket']) and !empty($_POST['awsAccessKey']) and !empty($_POST['awsSecretKey'])) { //create new s3 bucket if needed
|
443 |
if (!class_exists('CFRuntime'))
|
444 |
require_once(dirname(__FILE__).'/libs/aws/sdk.class.php');
|
445 |
-
|
446 |
-
|
447 |
-
|
|
|
|
|
|
|
|
|
448 |
}
|
449 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
if (!empty($_POST['rscUsername']) and !empty($_POST['rscAPIKey']) and !empty($_POST['newrscContainer'])) { //create new Rackspase Container if needed
|
451 |
if (!class_exists('CF_Authentication'))
|
452 |
require_once(plugin_dir_path(__FILE__).'libs/rackspace/cloudfiles.php');
|
156 |
|
157 |
$jobs=get_option('backwpup_jobs'); //Load jobs
|
158 |
if (extension_loaded('curl') or @dl(PHP_SHLIB_SUFFIX == 'so' ? 'curl.so' : 'php_curl.dll')) {
|
159 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
160 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob'))
|
161 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
162 |
+
if (!class_exists('CFRuntime'))
|
163 |
+
require_once(dirname(__FILE__).'/libs/aws/sdk.class.php');
|
164 |
+
if (!class_exists('CF_Authentication'))
|
165 |
+
require_once(plugin_dir_path(__FILE__).'libs/rackspace/cloudfiles.php');
|
166 |
}
|
167 |
|
168 |
$num=0;
|
178 |
$s3->delete_object($jobvalue['awsBucket'],$backups['file']);
|
179 |
}
|
180 |
}
|
181 |
+
} elseif ($backups['type']=='MSAZURE') {
|
182 |
+
if (class_exists('Microsoft_WindowsAzure_Storage_Blob')) {
|
183 |
+
if (!empty($jobvalue['msazureHost']) and !empty($jobvalue['msazureAccName']) and !empty($jobvalue['msazureKey']) and !empty($jobvalue['msazureContainer'])) {
|
184 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($jobvalue['msazureHost'],$jobvalue['msazureAccName'],$jobvalue['msazureKey']);
|
185 |
+
$storageClient->deleteBlob($jobvalue['msazureContainer'],$backups['file']);
|
186 |
+
}
|
187 |
+
}
|
188 |
} elseif ($backups['type']=='RSC') {
|
189 |
if (class_exists('CF_Authentication')) {
|
190 |
if (!empty($jobvalue['rscUsername']) and !empty($jobvalue['rscAPIKey']) and !empty($jobvalue['rscContainer'])) {
|
275 |
header('HTTP/1.0 '.$s3file->status.' Not Found');
|
276 |
die();
|
277 |
}
|
278 |
+
break;
|
279 |
+
case 'downloadmsazure': //Download Microsoft Azure Backup
|
280 |
+
check_admin_referer('download-backup');
|
281 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
282 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob'))
|
283 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
284 |
+
$jobs=get_option('backwpup_jobs');
|
285 |
+
$jobid=$_GET['jobid'];
|
286 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($jobs[$jobid]['msazureHost'],$jobs[$jobid]['msazureAccName'],$jobs[$jobid]['msazureKey']);
|
287 |
+
|
288 |
+
header("Pragma: public");
|
289 |
+
header("Expires: 0");
|
290 |
+
header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
|
291 |
+
//header("Content-Type: ".$s3file->header->_info->content_type);
|
292 |
+
header("Content-Type: application/force-download");
|
293 |
+
header("Content-Type: application/octet-stream");
|
294 |
+
header("Content-Type: application/download");
|
295 |
+
header("Content-Disposition: attachment; filename=".basename($_GET['file']).";");
|
296 |
+
header("Content-Transfer-Encoding: binary");
|
297 |
+
//header("Content-Length: ".$s3file->header->_info->size_download);
|
298 |
+
echo $storageClient->getBlobData($jobs[$jobid]['msazureContainer'], $_GET['file']);
|
299 |
+
die();
|
300 |
+
|
301 |
break;
|
302 |
case 'downloadrsc': //Download RSC Backup
|
303 |
check_admin_referer('download-backup');
|
458 |
$jobs[$jobid]['awsBucket']=$_POST['awsBucket'];
|
459 |
$jobs[$jobid]['awsdir']=stripslashes($_POST['awsdir']);
|
460 |
$jobs[$jobid]['awsmaxbackups']=(int)$_POST['awsmaxbackups'];
|
461 |
+
$jobs[$jobid]['msazureHost']=$_POST['msazureHost'];
|
462 |
+
$jobs[$jobid]['msazureAccName']=$_POST['msazureAccName'];
|
463 |
+
$jobs[$jobid]['msazureKey']=$_POST['msazureKey'];
|
464 |
+
$jobs[$jobid]['msazureContainer']=$_POST['msazureContainer'];
|
465 |
+
$jobs[$jobid]['msazuredir']=stripslashes($_POST['msazuredir']);
|
466 |
+
$jobs[$jobid]['msazuremaxbackups']=(int)$_POST['msazuremaxbackups'];
|
467 |
$jobs[$jobid]['rscUsername']=$_POST['rscUsername'];
|
468 |
$jobs[$jobid]['rscAPIKey']=$_POST['rscAPIKey'];
|
469 |
$jobs[$jobid]['rscContainer']=$_POST['rscContainer'];
|
481 |
if (!empty($_POST['newawsBucket']) and !empty($_POST['awsAccessKey']) and !empty($_POST['awsSecretKey'])) { //create new s3 bucket if needed
|
482 |
if (!class_exists('CFRuntime'))
|
483 |
require_once(dirname(__FILE__).'/libs/aws/sdk.class.php');
|
484 |
+
try {
|
485 |
+
$s3 = new AmazonS3($_POST['awsAccessKey'], $_POST['awsSecretKey']);
|
486 |
+
$s3->create_bucket($_POST['newawsBucket'], $_POST['awsRegion']);
|
487 |
+
$jobs[$jobid]['awsBucket']=$_POST['newawsBucket'];
|
488 |
+
} catch (Exception $e) {
|
489 |
+
$backwpup_message=__($e->getMessage(),'backwpup');
|
490 |
+
}
|
491 |
}
|
492 |
|
493 |
+
if (!empty($_POST['newmsazureContainer']) and !empty($_POST['msazureHost']) and !empty($_POST['msazureAccName']) and !empty($_POST['msazureKey'])) { //create new s3 bucket if needed
|
494 |
+
if (!class_exists('Microsoft_WindowsAzure_Storage_Blob')) {
|
495 |
+
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__).'/libs');
|
496 |
+
require_once 'Microsoft/WindowsAzure/Storage/Blob.php';
|
497 |
+
}
|
498 |
+
try {
|
499 |
+
$storageClient = new Microsoft_WindowsAzure_Storage_Blob($_POST['msazureHost'],$_POST['msazureAccName'],$_POST['msazureKey']);
|
500 |
+
$result = $storageClient->createContainer($_POST['newmsazureContainer']);
|
501 |
+
$jobs[$jobid]['msazureContainer']=$result->Name;
|
502 |
+
} catch (Exception $e) {
|
503 |
+
$backwpup_message=__($e->getMessage(),'backwpup');
|
504 |
+
}
|
505 |
+
}
|
506 |
+
|
507 |
+
|
508 |
if (!empty($_POST['rscUsername']) and !empty($_POST['rscAPIKey']) and !empty($_POST['newrscContainer'])) { //create new Rackspase Container if needed
|
509 |
if (!class_exists('CF_Authentication'))
|
510 |
require_once(plugin_dir_path(__FILE__).'libs/rackspace/cloudfiles.php');
|
backwpup.php
CHANGED
@@ -4,7 +4,7 @@ Plugin Name: BackWPup
|
|
4 |
Plugin URI: http://danielhuesken.de/portfolio/backwpup/
|
5 |
Description: Backup and more of your WordPress Blog Database and Files.
|
6 |
Author: Daniel Hüsken
|
7 |
-
Version: 1.5.
|
8 |
Author URI: http://danielhuesken.de
|
9 |
Text Domain: backwpup
|
10 |
Domain Path: /lang/
|
@@ -34,12 +34,12 @@ if ( !defined('ABSPATH') )
|
|
34 |
//Set plugin dirname
|
35 |
define('BACKWPUP_PLUGIN_BASEDIR', dirname(plugin_basename(__FILE__)));
|
36 |
//Set Plugin Version
|
37 |
-
define('BACKWPUP_VERSION', '1.5.
|
38 |
//Set User Capability
|
39 |
define('BACKWPUP_USER_CAPABILITY', 'export');
|
40 |
//Set useable destinations
|
41 |
if (!defined('BACKWPUP_DESTS'))
|
42 |
-
define('BACKWPUP_DESTS', 'S3,RSC,FTP,DROPBOX');
|
43 |
//load Text Domain
|
44 |
load_plugin_textdomain('backwpup', false, BACKWPUP_PLUGIN_BASEDIR.'/lang');
|
45 |
//Load functions file
|
@@ -67,6 +67,7 @@ if (backwpup_env_checks()) {
|
|
67 |
// add ajax function
|
68 |
add_action('wp_ajax_backwpup_get_aws_buckets', 'backwpup_get_aws_buckets');
|
69 |
add_action('wp_ajax_backwpup_get_rsc_container', 'backwpup_get_rsc_container');
|
|
|
70 |
//Disabele WP_Corn
|
71 |
$cfg=get_option('backwpup');
|
72 |
if ($cfg['disablewpcron'])
|
4 |
Plugin URI: http://danielhuesken.de/portfolio/backwpup/
|
5 |
Description: Backup and more of your WordPress Blog Database and Files.
|
6 |
Author: Daniel Hüsken
|
7 |
+
Version: 1.5.5
|
8 |
Author URI: http://danielhuesken.de
|
9 |
Text Domain: backwpup
|
10 |
Domain Path: /lang/
|
34 |
//Set plugin dirname
|
35 |
define('BACKWPUP_PLUGIN_BASEDIR', dirname(plugin_basename(__FILE__)));
|
36 |
//Set Plugin Version
|
37 |
+
define('BACKWPUP_VERSION', '1.5.5');
|
38 |
//Set User Capability
|
39 |
define('BACKWPUP_USER_CAPABILITY', 'export');
|
40 |
//Set useable destinations
|
41 |
if (!defined('BACKWPUP_DESTS'))
|
42 |
+
define('BACKWPUP_DESTS', 'S3,RSC,FTP,DROPBOX,MSAZURE');
|
43 |
//load Text Domain
|
44 |
load_plugin_textdomain('backwpup', false, BACKWPUP_PLUGIN_BASEDIR.'/lang');
|
45 |
//Load functions file
|
67 |
// add ajax function
|
68 |
add_action('wp_ajax_backwpup_get_aws_buckets', 'backwpup_get_aws_buckets');
|
69 |
add_action('wp_ajax_backwpup_get_rsc_container', 'backwpup_get_rsc_container');
|
70 |
+
add_action('wp_ajax_backwpup_get_msazure_container', 'backwpup_get_msazure_container');
|
71 |
//Disabele WP_Corn
|
72 |
$cfg=get_option('backwpup');
|
73 |
if ($cfg['disablewpcron'])
|
readme.txt
CHANGED
@@ -1,10 +1,10 @@
|
|
1 |
=== BackWPup ===
|
2 |
Contributors: danielhuesken, zlli
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=daniel%40huesken-net%2ede&item_name=Daniel%20Huesken%20Plugin%20Donation&item_number=BackWPup&no_shipping=0&no_note=1&tax=0¤cy_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8
|
4 |
-
Tags: backup, admin, file, Database, mysql, cron, ftp, S3, export, xml, Rackspase, cloud,
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 3.1.0
|
7 |
-
Stable tag: 1.5.
|
8 |
|
9 |
Backup and more of your WordPress Blog Database and Files
|
10 |
|
@@ -21,6 +21,7 @@ Backup and more your Blog.
|
|
21 |
* Store backup to Folder
|
22 |
* Store backup to FTP Server
|
23 |
* Store backup to Amazon S3
|
|
|
24 |
* Store backup to RackSpaceCloud
|
25 |
* Store backup to DropBox
|
26 |
* Send Log/Backup by eMail
|
@@ -92,12 +93,19 @@ Destinations are:
|
|
92 |
* RSC = RackSpaceCloud
|
93 |
* FTP = FTP Server
|
94 |
* DROPBOX = Dropbox
|
|
|
95 |
|
96 |
== Screenshots ==
|
97 |
|
98 |
1. Job Page
|
99 |
|
100 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
= 1.5.2 =
|
102 |
* changes for user checking
|
103 |
* removed Plugin init action
|
1 |
=== BackWPup ===
|
2 |
Contributors: danielhuesken, zlli
|
3 |
Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=daniel%40huesken-net%2ede&item_name=Daniel%20Huesken%20Plugin%20Donation&item_number=BackWPup&no_shipping=0&no_note=1&tax=0¤cy_code=EUR&lc=DE&bn=PP%2dDonationsBF&charset=UTF%2d8
|
4 |
+
Tags: backup, admin, file, Database, mysql, cron, ftp, S3, export, xml, Rackspase, cloud, azure, dropbox
|
5 |
Requires at least: 2.8
|
6 |
Tested up to: 3.1.0
|
7 |
+
Stable tag: 1.5.5
|
8 |
|
9 |
Backup and more of your WordPress Blog Database and Files
|
10 |
|
21 |
* Store backup to Folder
|
22 |
* Store backup to FTP Server
|
23 |
* Store backup to Amazon S3
|
24 |
+
* Store backup to Microsoft Azure (Blob)
|
25 |
* Store backup to RackSpaceCloud
|
26 |
* Store backup to DropBox
|
27 |
* Send Log/Backup by eMail
|
93 |
* RSC = RackSpaceCloud
|
94 |
* FTP = FTP Server
|
95 |
* DROPBOX = Dropbox
|
96 |
+
* MSAZURE = Microsoft Azure (Blob)
|
97 |
|
98 |
== Screenshots ==
|
99 |
|
100 |
1. Job Page
|
101 |
|
102 |
== Changelog ==
|
103 |
+
= 1.5.5 =
|
104 |
+
* Updatet AWS SDK to ver.1.2.6 for Amazon S3
|
105 |
+
* Added AWS Regin "Northeast" (Japan)
|
106 |
+
* Added Microsoft Azure (Blob) as backup destination
|
107 |
+
* bug fixes
|
108 |
+
|
109 |
= 1.5.2 =
|
110 |
* changes for user checking
|
111 |
* removed Plugin init action
|