diff --git a/js/zerobin.js b/js/zerobin.js index 9b2e9a2d..02872acf 100644 --- a/js/zerobin.js +++ b/js/zerobin.js @@ -482,6 +482,11 @@ $(function() { }; var zerobin = { + /** + * headers to send in AJAX requests + */ + headers: {'X-Requested-With': 'JSONHttpRequest'}, + /** * Get the current script location (without search or hash part of the URL). * eg. http://server.com/zero/?aaaa#bbbb --> http://server.com/zero/ @@ -666,7 +671,12 @@ $(function() { } if (comments[0].meta.burnafterreading) { - $.get(this.scriptLocation() + '?pasteid=' + this.pasteID() + '&deletetoken=burnafterreading', 'json') + $.ajax({ + // type: 'DELETE', // unfortunately many web servers will not support DELETE and PUT by default + url: this.scriptLocation() + '?pasteid=' + this.pasteID() + '&deletetoken=burnafterreading', + dataType: 'json', + headers: this.headers + }) .fail(function() { zerobin.showError(i18n._('Could not delete the paste, it was not stored in burn after reading mode.')); }); @@ -805,39 +815,52 @@ $(function() { nickname: ciphernickname }; - $.post(this.scriptLocation(), data_to_send, function(data) - { - if (data.status == 0) + $.ajax({ + type: 'POST', + url: this.scriptLocation(), + data: data_to_send, + dataType: 'json', + headers: this.headers, + success: function(data) { - zerobin.showStatus(i18n._('Comment posted.'), false); - $.get(zerobin.scriptLocation() + '?' + zerobin.pasteID() + '&json', function(data) + if (data.status == 0) { - if (data.status == 0) - { - zerobin.displayMessages(zerobin.pageKey(), data.messages); - } - else if (data.status == 1) - { - zerobin.showError(i18n._('Could not refresh display: %s', data.message)); - } - else - { - zerobin.showError(i18n._('Could not refresh display: %s', i18n._('unknown status'))); - } - }, 'json') - .fail(function() { - zerobin.showError(i18n._('Could not refresh display: %s', i18n._('server error or not responding'))); - }); + zerobin.showStatus(i18n._('Comment posted.'), false); + $.ajax({ + type: 'GET', + url: zerobin.scriptLocation() + '?' + zerobin.pasteID(), + dataType: 'json', + headers: zerobin.headers, + success: function(data) + { + if (data.status == 0) + { + zerobin.displayMessages(zerobin.pageKey(), data.messages); + } + else if (data.status == 1) + { + zerobin.showError(i18n._('Could not refresh display: %s', data.message)); + } + else + { + zerobin.showError(i18n._('Could not refresh display: %s', i18n._('unknown status'))); + } + } + }) + .fail(function() { + zerobin.showError(i18n._('Could not refresh display: %s', i18n._('server error or not responding'))); + }); + } + else if (data.status == 1) + { + zerobin.showError(i18n._('Could not post comment: %s', data.message)); + } + else + { + zerobin.showError(i18n._('Could not post comment: %s', i18n._('unknown status'))); + } } - else if (data.status == 1) - { - zerobin.showError(i18n._('Could not post comment: %s', data.message)); - } - else - { - zerobin.showError(i18n._('Could not post comment: %s', i18n._('unknown status'))); - } - }, 'json') + }) .fail(function() { zerobin.showError(i18n._('Could not post comment: %s', i18n._('server error or not responding'))); }); @@ -932,36 +955,44 @@ $(function() { data_to_send.attachmentname = cipherdata_attachment_name; } } - $.post(this.scriptLocation(), data_to_send, function(data) + $.ajax({ + type: 'POST', + url: this.scriptLocation(), + data: data_to_send, + dataType: 'json', + headers: this.headers, + success: function(data) + { + if (data.status == 0) { + zerobin.stateExistingPaste(); + var url = zerobin.scriptLocation() + '?' + data.id + '#' + randomkey; + var deleteUrl = zerobin.scriptLocation() + '?pasteid=' + data.id + '&deletetoken=' + data.deletetoken; + zerobin.showStatus('', false); + zerobin.errorMessage.addClass('hidden'); + + $('#pastelink').html(i18n._('Your paste is %s (Hit [Ctrl]+[c] to copy)', url, url)); + $('#deletelink').html('' + i18n._('Delete data') + ''); + zerobin.pasteResult.removeClass('hidden'); + // We pre-select the link so that the user only has to [Ctrl]+[c] the link. + helper.selectText('pasteurl'); + zerobin.showStatus('', false); + + helper.setElementText(zerobin.clearText, zerobin.message.val()); + helper.setElementText(zerobin.prettyPrint, zerobin.message.val()); + zerobin.formatPaste(data_to_send.formatter); + } + else if (data.status==1) + { + zerobin.showError(i18n._('Could not create paste: %s', data.message)); + } + else + { + zerobin.showError(i18n._('Could not create paste: %s', i18n._('unknown status'))); + } + } + }) + .fail(function() { - if (data.status == 0) { - zerobin.stateExistingPaste(); - var url = zerobin.scriptLocation() + '?' + data.id + '#' + randomkey; - var deleteUrl = zerobin.scriptLocation() + '?pasteid=' + data.id + '&deletetoken=' + data.deletetoken; - zerobin.showStatus('', false); - zerobin.errorMessage.addClass('hidden'); - - $('#pastelink').html(i18n._('Your paste is %s (Hit [Ctrl]+[c] to copy)', url, url)); - $('#deletelink').html('' + i18n._('Delete data') + ''); - zerobin.pasteResult.removeClass('hidden'); - // We pre-select the link so that the user only has to [Ctrl]+[c] the link. - helper.selectText('pasteurl'); - zerobin.showStatus('', false); - - helper.setElementText(zerobin.clearText, zerobin.message.val()); - helper.setElementText(zerobin.prettyPrint, zerobin.message.val()); - zerobin.formatPaste(data_to_send.formatter); - } - else if (data.status==1) - { - zerobin.showError(i18n._('Could not create paste: %s', data.message)); - } - else - { - zerobin.showError(i18n._('Could not create paste: %s', i18n._('unknown status'))); - } - }, 'json') - .fail(function() { zerobin.showError(i18n._('Could not create paste: %s', i18n._('server error or not responding'))); }); }, diff --git a/lib/request.php b/lib/request.php new file mode 100644 index 00000000..7b80f3b9 --- /dev/null +++ b/lib/request.php @@ -0,0 +1,160 @@ +_isJsonApi = true; + } + + // parse parameters, depending on request type + switch (array_key_exists('REQUEST_METHOD', $_SERVER) ? $_SERVER['REQUEST_METHOD'] : 'GET') + { + case 'PUT': + parse_str(file_get_contents($this->_inputStream), $this->_params); + break; + case 'POST': + $this->_params = $_POST; + break; + default: + $this->_params = $_GET; + } + + // prepare paremeters, depending on current operation + if ( + (array_key_exists('data', $this->_params) && !empty($this->_params['data'])) || + (array_key_exists('attachment', $this->_params) && !empty($this->_params['attachment'])) + ) + { + $this->_operation = 'create'; + } + elseif ( + array_key_exists('pasteid', $this->_params) && !empty($this->_params['pasteid']) && + array_key_exists('deletetoken', $this->_params) && !empty($this->_params['deletetoken']) + ) + { + $this->_operation = 'delete'; + } + // display an existing paste + elseif (array_key_exists('QUERY_STRING', $_SERVER) && !empty($_SERVER['QUERY_STRING'])) + { + $this->_operation = 'read'; + $this->_params['pasteid'] = $_SERVER['QUERY_STRING']; + } + } + + /** + * Get current operation. + * + * @access public + * @return string + */ + public function getOperation() + { + return $this->_operation; + } + + /** + * Get a request parameter. + * + * @access public + * @param string $param + * @param string $default + * @return string + */ + public function getParam($param, $default = '') + { + return array_key_exists($param, $this->_params) ? $this->_params[$param] : $default; + } + + /** + * If we are in a JSON API context. + * + * @access public + * @return bool + */ + public function isJsonApiCall() + { + return $this->_isJsonApi; + } + + /** + * Override the default input stream source + * + * @param unknown $input + */ + public function setInputStream($input) + { + $this->_inputStream = $input; + $this->__construct(); + } +} \ No newline at end of file diff --git a/lib/zerobin.php b/lib/zerobin.php index 9bef7c6d..2f51d2f4 100644 --- a/lib/zerobin.php +++ b/lib/zerobin.php @@ -87,6 +87,14 @@ class zerobin */ private $_model; + /** + * request + * + * @access private + * @var request + */ + private $_request; + /** * constructor * @@ -102,38 +110,27 @@ class zerobin throw new Exception(i18n::_('ZeroBin requires php 5.2.6 or above to work. Sorry.'), 1); } - // in case stupid admin has left magic_quotes enabled in php.ini - if (function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) - { - $_POST = array_map('filter::stripslashes_deep', $_POST); - $_GET = array_map('filter::stripslashes_deep', $_GET); - $_COOKIE = array_map('filter::stripslashes_deep', $_COOKIE); - } - // load config from ini file $this->_init(); - // create new paste or comment - if ( - (array_key_exists('data', $_POST) && !empty($_POST['data'])) || - (array_key_exists('attachment', $_POST) && !empty($_POST['attachment'])) - ) + switch ($this->_request->getOperation()) { - $this->_create(); - } - // delete an existing paste - elseif (!empty($_GET['deletetoken']) && !empty($_GET['pasteid'])) - { - $this->_delete($_GET['pasteid'], $_GET['deletetoken']); - } - // display an existing paste - elseif (!empty($_SERVER['QUERY_STRING'])) - { - $this->_read($_SERVER['QUERY_STRING']); + case 'create': + $this->_create(); + break; + case 'delete': + $this->_delete( + $this->_request->getParam('pasteid'), + $this->_request->getParam('deletetoken') + ); + break; + case 'read': + $this->_read($this->_request->getParam('pasteid')); + break; } // output JSON or HTML - if (strlen($this->_json)) + if ($this->_request->isJsonApiCall()) { header('Content-type: application/json'); echo $this->_json; @@ -164,6 +161,7 @@ class zerobin $this->_conf = new configuration; $this->_model = new model($this->_conf); + $this->_request = new request; } /** @@ -199,11 +197,9 @@ class zerobin ) ); - $has_attachment = array_key_exists('attachment', $_POST); - $has_attachmentname = $has_attachment && array_key_exists('attachmentname', $_POST) && !empty($_POST['attachmentname']); - $data = array_key_exists('data', $_POST) ? $_POST['data'] : ''; - $attachment = $has_attachment ? $_POST['attachment'] : ''; - $attachmentname = $has_attachmentname ? $_POST['attachmentname'] : ''; + $data = $this->_request->getParam('data'); + $attachment = $this->_request->getParam('attachment'); + $attachmentname = $this->_request->getParam('attachmentname'); // Ensure content is not too big. $sizelimit = $this->_conf->getKey('sizelimit'); @@ -218,18 +214,17 @@ class zerobin ); // The user posts a comment. - if ( - array_key_exists('parentid', $_POST) && !empty($_POST['parentid']) && - array_key_exists('pasteid', $_POST) && !empty($_POST['pasteid']) - ) + $pasteid = $this->_request->getParam('pasteid'); + $parentid = $this->_request->getParam('parentid'); + if (!empty($pasteid) && !empty($parentid)) { - $paste = $this->_model->getPaste($_POST['pasteid']); + $paste = $this->_model->getPaste($pasteid); if ($paste->exists()) { try { - $comment = $paste->getComment($_POST['parentid']); + $comment = $paste->getComment($parentid); - if (array_key_exists('nickname', $_POST) && !empty($_POST['nickname']) - ) $comment->setNickname($_POST['nickname']); + $nickname = $this->_request->getParam('nickname'); + if (!empty($nickname)) $comment->setNickname($nickname); $comment->setData($data); $comment->store(); @@ -248,24 +243,24 @@ class zerobin { $paste = $this->_model->getPaste(); try { - if ($has_attachment) + if (!empty($attachment)) { $paste->setAttachment($attachment); - if ($has_attachmentname) + if (!empty($attachmentname)) $paste->setAttachmentName($attachmentname); } - if (array_key_exists('expire', $_POST) && !empty($_POST['expire']) - ) $paste->setExpiration($_POST['expire']); + $expire = $this->_request->getParam('expire'); + if (!empty($expire)) $paste->setExpiration($expire); - if (array_key_exists('burnafterreading', $_POST) && !empty($_POST['burnafterreading']) - ) $paste->setBurnafterreading($_POST['burnafterreading']); + $burnafterreading = $this->_request->getParam('burnafterreading'); + if (!empty($burnafterreading)) $paste->setBurnafterreading($burnafterreading); - if (array_key_exists('opendiscussion', $_POST) && !empty($_POST['opendiscussion']) - ) $paste->setOpendiscussion($_POST['opendiscussion']); + $opendiscussion = $this->_request->getParam('opendiscussion'); + if (!empty($opendiscussion)) $paste->setOpendiscussion($opendiscussion); - if (array_key_exists('formatter', $_POST) && !empty($_POST['formatter']) - ) $paste->setFormatter($_POST['formatter']); + $formatter = $this->_request->getParam('formatter'); + if (!empty($formatter)) $paste->setFormatter($formatter); $paste->setData($data); $paste->store(); @@ -339,12 +334,6 @@ class zerobin */ private function _read($dataid) { - $isJson = false; - if (($pos = strpos($dataid, '&json')) !== false) { - $isJson = true; - $dataid = substr($dataid, 0, $pos); - } - try { $paste = $this->_model->getPaste($dataid); if ($paste->exists()) @@ -362,10 +351,9 @@ class zerobin } } catch (Exception $e) { $this->_error = $e->getMessage(); - return; } - if ($isJson) + if ($this->_request->isJsonApiCall()) { if (strlen($this->_error)) { diff --git a/tst/request.php b/tst/request.php index 6db43c33..e6901eb0 100644 --- a/tst/request.php +++ b/tst/request.php @@ -58,8 +58,10 @@ class requestTest extends PHPUnit_Framework_TestCase $this->reset(); $_SERVER['REQUEST_METHOD'] = 'PUT'; $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; - $_POST['data'] = 'foo'; + $file = tempnam(sys_get_temp_dir(), 'FOO'); + file_put_contents($file, 'data=foo'); $request = new request; + $request->setInputStream($file); $this->assertTrue($request->isJsonApiCall(), 'is JSON Api call'); $this->assertEquals('create', $request->getOperation()); $this->assertEquals('foo', $request->getParam('data')); diff --git a/tst/zerobin.php b/tst/zerobin.php index 6a1028ef..95f420e1 100644 --- a/tst/zerobin.php +++ b/tst/zerobin.php @@ -113,6 +113,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase { $this->reset(); $_POST = helper::getPaste(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -134,6 +136,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase { $this->reset(); $_POST = helper::getPaste(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -155,6 +159,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::confBackup(); helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -176,6 +182,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); $_SERVER['HTTP_X_FORWARDED_FOR'] = '::1'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; ob_start(); new zerobin; $content = ob_get_contents(); @@ -196,6 +204,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $this->_model->create(helper::getPasteId(), helper::getPaste()); $_POST = helper::getPaste(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -218,6 +228,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getPaste(); $_POST['expire'] = '5min'; $_POST['formatter'] = 'foo'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -244,6 +256,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); $_POST['expire'] = 'foo'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -270,6 +284,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); $_POST['burnafterreading'] = 'neither 1 nor 0'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -291,6 +307,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); $_POST['opendiscussion'] = 'neither 1 nor 0'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -312,6 +330,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::confBackup(); helper::createIniFile(CONF, $options); $_POST = helper::getPasteWithAttachment(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; $this->assertFalse($this->_model->exists(helper::getPasteId()), 'paste does not exists before posting data'); ob_start(); @@ -344,6 +364,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase helper::createIniFile(CONF, $options); $_POST = helper::getPaste(); $_POST['nickname'] = helper::getComment()['meta']['nickname']; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -372,6 +394,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = helper::getPasteId(); $_POST['nickname'] = 'foo'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; $this->_model->create(helper::getPasteId(), helper::getPaste()); ob_start(); @@ -395,6 +419,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getComment(); $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; $this->_model->create(helper::getPasteId(), helper::getPaste()); ob_start(); @@ -418,6 +444,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getComment(); $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = 'foo'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; $this->_model->create(helper::getPasteId(), helper::getPaste()); ob_start(); @@ -441,6 +469,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getComment(); $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; $paste = helper::getPaste(array('opendiscussion' => false)); $this->_model->create(helper::getPasteId(), $paste); @@ -465,6 +495,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getComment(); $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -490,6 +522,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $_POST = helper::getComment(); $_POST['pasteid'] = helper::getPasteId(); $_POST['parentid'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'POST'; $_SERVER['REMOTE_ADDR'] = '::1'; ob_start(); new zerobin; @@ -611,7 +645,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase { $this->reset(); $this->_model->create(helper::getPasteId(), helper::getPaste()); - $_SERVER['QUERY_STRING'] = helper::getPasteId() . '&json'; + $_SERVER['QUERY_STRING'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; ob_start(); new zerobin; $content = ob_get_contents(); @@ -626,7 +661,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase public function testReadInvalidJson() { $this->reset(); - $_SERVER['QUERY_STRING'] = helper::getPasteId() . '&json'; + $_SERVER['QUERY_STRING'] = helper::getPasteId(); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; ob_start(); new zerobin; $content = ob_get_contents(); @@ -784,6 +820,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data'); $_GET['pasteid'] = helper::getPasteId(); $_GET['deletetoken'] = 'burnafterreading'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'DELETE'; ob_start(); new zerobin; $content = ob_get_contents(); @@ -802,6 +840,8 @@ class zerobinTest extends PHPUnit_Framework_TestCase $this->assertTrue($this->_model->exists(helper::getPasteId()), 'paste exists before deleting data'); $_GET['pasteid'] = helper::getPasteId(); $_GET['deletetoken'] = 'burnafterreading'; + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'JSONHttpRequest'; + $_SERVER['REQUEST_METHOD'] = 'DELETE'; ob_start(); new zerobin; $content = ob_get_contents();