Změna HTTP hlaviček (odeslání souboru)

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Petr Daňa
Člen | 109
+
0
-

Jen bych se rád ujistil, že to dělám dobře (nebo se dozvěděl, že to mám dělat jinak :) ), ono to funguje, ale nejsem si jistý, jestli to dělám správně. Jde mi o odeslání souboru aplikací (tedy zabránění přímého stažení). Nejspíš normálně pomocí presenteru?

Router mám

$router[] = new Route('file/<file>', array('presenter' => 'File', 'action' => 'default'));

a k tomu presenter:

class FilePresenter extends Presenter
{
  public function renderDefault($file)
  {
    $fn = str_replace("..", "", $file);
    $fn = str_replace("\\", "", $fn);
    $file = WWW_DIR . "files/" . strtolower($fn);
    if (file_exists($file))
    {
      $response = Environment::getHttpResponse();
      $response->setHeader('Content-type', 'application/octet-stream');
      $response->setHeader('Content-Disposition', 'attachment;filename='.$fn);
      $response->setHeader('Pragma', 'no-cache');
      $response->setHeader('Expires', '0');
      readfile($file);
    } else
      $errmsgs[] = "Soubor '$file' neexistuje.";
  }
}

Jsou tam nějaké pozůstatky z původní aplikace (třeba ten else a errmsgs). Plus k tomu je prázdný template (bez něj to háže výjimku).

Je cesta přes presenter správná nebo se to má dělat jinak?

LM
Člen | 206
+
0
-

Možná zavolat:

$this->terminate();

By mělo zabránit hledat a renderovat šablonu, ale jestli je to správný postup si jistej nejsem. :-)

David Grudl
Nette Core | 8218
+
0
-

Výborně!

Jen pár tipů:

  • není-li to vyloženě nutné kvůli zpětné kompatibilitě, vyhodil bych strtolower, URL jsou case-sensitive
  • $errmsgs[] se dá nahradit za $this->forward('jineView') nebo $this->forward('jinyPresenter:jineView') či rovnou $this->forward('jinyPresenter:') (pozor na dvojtečku)
  • za (nebo před) readfile vložte $this->terminate() a nebude potřeba prázdný template.
Petr Daňa
Člen | 109
+
0
-

LM napsal(a):

Možná zavolat:

$this->terminate();

By mělo zabránit hledat a renderovat šablonu, ale jestli je to správný postup si jistej nejsem. :-)

Díky za tip. Pro jistotu jsem to tam dal, ikdyž jsem zjistil, že to tam asi není potřeba, odstranil jsem template a nevyžadoval ho, tak nevím, co jsem tam měl předtím za botu, že ho to chtělo. (Teď koukám, že David psal ve čtvrým bodě, ať se tam dá, tak ho tam nechám :) ).

Davide, díky za tipy. Co se týká toho strtolower, tak to je pozůstatek z původní aplikace, ale musí tam být, protože ty stránky, jak byly udělány, tak na stránkách mají názvy souborů různé velikosti písmen, a původně to bylo i na serveru, jenže tam byly nějaké šaškárny u poskytovatele, takže veškeré soubory na disku jsou teď malými písmeny, a než procházet to množství textu, tak jsem to udělal takhle – navíc při stažení uživatelem bude velikost podle toho, co je v textu a ne jak to je na serveru.

Co se týká toho errmsgs, tak to mě teprve čeká na úpravu. Spíš to asi budu řešit přes nějakou komponentu, až teda zjistím, jak to funguje (chtělo by to ty tutoriály ;) ), protože to jsou ty stavové hlášky vložené do hlavního layoutu.

tark
Člen | 22
+
0
-

David Grudl napsal(a):

  • za (nebo před) readfile vložte $this->terminate() a nebude potřeba prázdný template.

Díky za tip. Já to vždycky dělal pomocí die() :-D

krajaac
Člen | 45
+
0
-

Existuje nějaká možnost jak vypnout zapnutý profiler?

Používám postup pro odesílání souboru popsaný výše a trochu se do něho motá profiler z Laděnky… Buď se profiler pošle společně se souborem ($this->terminate před odesláním souboru), nebo při následujícím requestu ($this->terminate za odesláním souboru).

EDIT: Zatím jsem to vyřešil přidáním public static $enableProfiler = NULL a testování téhle proměnné v paintProfiler() v Laděnce.

Editoval krajaac (5. 2. 2009 19:40)

David Grudl
Nette Core | 8218
+
0
-

Doplnil jsem metodu Debug::disableProfiler();

krajaac
Člen | 45
+
0
-

David Grudl napsal(a):

Doplnil jsem metodu Debug::disableProfiler();

Díky!