summaryrefslogtreecommitdiffstats
path: root/application/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'application/controllers')
-rw-r--r--application/controllers/file.php186
1 files changed, 181 insertions, 5 deletions
diff --git a/application/controllers/file.php b/application/controllers/file.php
index b8306b5bc..c84620d4f 100644
--- a/application/controllers/file.php
+++ b/application/controllers/file.php
@@ -62,14 +62,190 @@ class File extends CI_Controller {
if(isset($_FILES['file'])) {
$this->do_upload();
} elseif ($id != "file" && $this->file_mod->id_exists($id)) {
- $this->file_mod->download();
+ $this->_download();
} elseif ($id && $id != "file") {
- $this->file_mod->non_existent();
+ $this->_non_existent();
} else {
$this->upload_form();
}
}
+ function _download()
+ {
+ $id = $this->uri->segment(1);
+ $mode = $this->uri->segment(2);
+
+ $filedata = $this->file_mod->get_filedata($id);
+ $file = $this->file_mod->file($filedata['hash']);
+
+ if (!$this->file_mod->valid_id($id)) {
+ $this->non_existent();
+ return;
+ }
+
+ // don't allow unowned files to be downloaded
+ if ($filedata["user"] == 0) {
+ $this->file_mod->non_existent();
+ return;
+ }
+
+ // helps to keep traffic low when reloading
+ $etag = $filedata["hash"]."-".$filedata["date"];
+
+ // autodetect the mode for highlighting if the URL contains a / after the ID (/ID/)
+ // /ID/mode disables autodetection
+ $autodetect_mode = !$mode && substr_count(ltrim($this->uri->uri_string(), "/"), '/') >= 1;
+
+ if ($autodetect_mode) {
+ $mode = $this->file_mod->get_highlight_mode($filedata["mimetype"], $filedata["filename"]);
+ }
+
+ // resolve aliases of modes
+ // this is mainly used for compatibility
+ $mode = $this->file_mod->resolve_mode_alias($mode);
+
+ // create the qr code for /ID/
+ if ($mode == "qr") {
+ handle_etag($etag);
+ header("Content-disposition: inline; filename=\"".$id."_qr.png\"\n");
+ header("Content-Type: image/png\n");
+ passthru('qrencode -s 10 -o - '.escapeshellarg(site_url($id).'/'));
+ exit();
+ }
+
+ // user wants to the the plain file
+ if ($mode == 'plain') {
+ handle_etag($etag);
+ rangeDownload($file, $filedata["filename"], "text/plain");
+ exit();
+ }
+
+ if ($mode == 'info') {
+ $this->_display_info($id);
+ return;
+ }
+
+ // if there is no mimetype mapping we can't highlight it
+ $can_highlight = $this->file_mod->can_highlight($filedata["mimetype"]);
+
+ $filesize_too_big = filesize($file) > $this->config->item('upload_max_text_size');
+
+ if (!$can_highlight || $filesize_too_big || !$mode) {
+ // prevent javascript from being executed and forbid frames
+ // this should allow us to serve user submitted HTML content without huge security risks
+ foreach (array("X-WebKit-CSP", "X-Content-Security-Policy") as $header_name) {
+ header("$header_name: allow 'none'; img-src *; media-src *; font-src *; style-src * 'unsafe-inline'; script-src 'none'; object-src *; frame-src 'none'; ");
+ }
+ handle_etag($etag);
+ rangeDownload($file, $filedata["filename"], $filedata["mimetype"]);
+ exit();
+ }
+
+ $this->data['title'] = htmlspecialchars($filedata['filename']);
+ $this->data['id'] = $id;
+
+ header("Content-Type: text/html\n");
+
+ $this->data['current_highlight'] = htmlspecialchars($mode);
+ $this->data['timeout'] = $this->file_mod->get_timeout_string($id);
+
+ echo $this->load->view($this->var->view_dir.'/html_header', $this->data, true);
+
+ // highlight the file and chache the result
+ $this->load->library("MemcacheLibrary");
+ if (! $cached = $this->memcachelibrary->get($filedata['hash'].'_'.$mode)) {
+ ob_start();
+ if ($mode == "rmd") {
+ echo '<td class="markdownrender">'."\n";
+ passthru('perl '.FCPATH.'scripts/Markdown.pl '.escapeshellarg($file));
+ } elseif ($mode == "ascii") {
+ echo '<td class="code"><pre class="text">'."\n";
+ passthru('perl '.FCPATH.'scripts/ansi2html '.escapeshellarg($file));
+ echo "</pre>\n";
+ } else {
+ echo '<td class="numbers"><pre>';
+ // generate line numbers (links)
+ passthru('perl -ne \'print "<a href=\"#n$.\" class=\"no\" id=\"n$.\">$.</a>\n"\' '.escapeshellarg($file));
+ echo '</pre></td><td class="code">'."\n";
+ $this->load->library('geshi');
+ $this->geshi->initialize(array('set_language' => $mode, 'set_source' => file_get_contents($file), 'enable_classes' => 'true'));
+ echo $this->geshi->parse_code();
+ }
+ $cached = ob_get_contents();
+ ob_end_clean();
+ $this->memcachelibrary->set($filedata['hash'].'_'.$mode, $cached, 100);
+ }
+ echo $cached;
+
+ echo $this->load->view($this->var->view_dir.'/html_footer', $this->data, true);
+
+ return;
+ }
+
+ function _display_info($id)
+ {
+ $this->data["title"] .= " - Info $id";
+ $this->data["filedata"] = $this->file_mod->get_filedata($id);
+ $this->data["id"] = $id;
+ $this->data['timeout'] = $this->file_mod->get_timeout_string($id);
+
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/file_info', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ function _non_existent()
+ {
+ $this->data["title"] .= " - Not Found";
+ $this->output->set_status_header(404);
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/non_existent', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+
+ function _show_url($id, $mode)
+ {
+ $redirect = false;
+
+ if (!$this->muser->logged_in()) {
+ // keep the upload but require the user to login
+ $this->session->set_userdata("last_upload", array(
+ "id" => $id,
+ "mode" => $mode
+ ));
+ $this->session->set_flashdata("uri", "file/claim_id");
+ $this->muser->require_access();
+ }
+
+ if ($mode) {
+ $this->data['url'] = site_url($id).'/'.$mode;
+ } else {
+ $this->data['url'] = site_url($id).'/';
+
+ $filedata = $this->file_mod->get_filedata($id);
+ $file = $this->file_mod->file($filedata['hash']);
+ $type = $filedata['mimetype'];
+ $mode = $this->file_mod->should_highlight($type);
+
+ // If we detected a highlightable file redirect,
+ // otherwise show the URL because browsers would just show a DL dialog
+ if ($mode) {
+ $redirect = true;
+ }
+ }
+
+ if (is_cli_client()) {
+ $redirect = false;
+ }
+ if ($redirect) {
+ redirect($this->data['url'], "location", 303);
+ } else {
+ $this->load->view($this->var->view_dir.'/header', $this->data);
+ $this->load->view($this->var->view_dir.'/show_url', $this->data);
+ $this->load->view($this->var->view_dir.'/footer', $this->data);
+ }
+ }
+
function client()
{
$this->data['title'] .= ' - Client';
@@ -278,7 +454,7 @@ class File extends CI_Controller {
file_put_contents($file, $content);
chmod($file, 0600);
$this->file_mod->add_file($hash, $id, $filename);
- $this->file_mod->show_url($id, false);
+ $this->_show_url($id, false);
}
// Handles uploaded files
@@ -337,7 +513,7 @@ class File extends CI_Controller {
move_uploaded_file($_FILES['file']['tmp_name'], $file);
chmod($file, 0600);
$this->file_mod->add_file($hash, $id, $filename);
- $this->file_mod->show_url($id, $extension);
+ $this->_show_url($id, $extension);
}
function claim_id()
@@ -357,7 +533,7 @@ class File extends CI_Controller {
$this->session->unset_userdata("last_upload");
- $this->file_mod->show_url($id, $last_upload["mode"]);
+ $this->_show_url($id, $last_upload["mode"]);
}
/* Functions below this comment can only be run via the CLI