1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Application;
13:
14: use Nette;
15:
16:
17:
18: 19: 20: 21: 22:
23: class DownloadResponse extends Nette\Object implements IPresenterResponse
24: {
25:
26: private $file;
27:
28:
29: private $contentType;
30:
31:
32: private $name;
33:
34:
35: public $resuming = TRUE;
36:
37:
38: 39: 40: 41: 42:
43: public function __construct($file, $name = NULL, $contentType = NULL)
44: {
45: if (!is_file($file)) {
46: throw new BadRequestException("File '$file' doesn't exist.");
47: }
48:
49: $this->file = $file;
50: $this->name = $name ? $name : basename($file);
51: $this->contentType = $contentType ? $contentType : 'application/octet-stream';
52: }
53:
54:
55:
56: 57: 58: 59:
60: final public function getFile()
61: {
62: return $this->file;
63: }
64:
65:
66:
67: 68: 69: 70:
71: final public function getName()
72: {
73: return $this->name;
74: }
75:
76:
77:
78: 79: 80: 81:
82: final public function getContentType()
83: {
84: return $this->contentType;
85: }
86:
87:
88:
89: 90: 91: 92:
93: public function send(Nette\Web\IHttpRequest $httpRequest, Nette\Web\IHttpResponse $httpResponse)
94: {
95: $httpResponse->setContentType($this->contentType);
96: $httpResponse->setHeader('Content-Disposition', 'attachment; filename="' . $this->name . '"');
97:
98: $filesize = $length = filesize($this->file);
99: $handle = fopen($this->file, 'r');
100:
101: if ($this->resuming) {
102: $httpResponse->setHeader('Accept-Ranges', 'bytes');
103: $range = $httpRequest->getHeader('Range');
104: if ($range !== NULL) {
105: $range = substr($range, 6); 106: list($start, $end) = explode('-', $range);
107: if ($start == NULL) {
108: $start = 0;
109: }
110: if ($end == NULL) {
111: $end = $filesize - 1;
112: }
113:
114: if ($start < 0 || $end <= $start || $end > $filesize -1) {
115: $httpResponse->setCode(416); 116: return;
117: }
118:
119: $httpResponse->setCode(206);
120: $httpResponse->setHeader('Content-Range', 'bytes ' . $start . '-' . $end . '/' . $filesize);
121: $length = $end - $start + 1;
122: fseek($handle, $start);
123:
124: } else {
125: $httpResponse->setHeader('Content-Range', 'bytes 0-' . ($filesize - 1) . '/' . $filesize);
126: }
127: }
128:
129: $httpResponse->setHeader('Content-Length', $length);
130: while (!feof($handle)) {
131: echo fread($handle, 4e6);
132: }
133: fclose($handle);
134: }
135:
136: }
137: