1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: namespace Pry\Net;
14:
15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
25: class HTTPDownload
26: {
27:
28: 29: 30: 31:
32: protected $path;
33:
34: 35: 36: 37: 38:
39: protected $name;
40:
41: 42: 43: 44:
45: protected $extension;
46:
47: 48: 49: 50:
51: protected $mime;
52:
53: 54: 55: 56:
57: protected $size;
58:
59: 60: 61: 62:
63: protected $resume;
64:
65: 66: 67: 68:
69: protected $seekStart;
70:
71: 72: 73: 74:
75: protected $seekEnd;
76:
77: public function __construct($path, $resume = false)
78: {
79: if (file_exists($path))
80: {
81: $this->path = $path;
82: $this->extension = strtolower(substr(strrchr($path, '.'), 1));
83: $this->getMime();
84: $this->size = filesize($path);
85: $this->seekStart = 0;
86: $this->seekEnd = -1;
87: $this->resume = $resume;
88: $this->name = basename($path);
89: }
90: else
91: {
92: throw new \Exception('Fichier innexistant');
93: }
94: }
95:
96: 97: 98:
99: public function download()
100: {
101: header("Cache-Control: cache, must-revalidate");
102: header("Pragma: public");
103: header('Expires: 0');
104: if ($this->resume)
105: {
106: $this->getRange();
107: header('HTTP/1.0 206 Partial Content');
108: header('Status: 206 Partial Content');
109: header('Accept-Ranges: bytes');
110: header('Content-Range: bytes ' . $this->seekStart . '-' . $this->seekEnd . '/' . $this->size);
111: header('Content-Length:' . ($this->seekEnd - $this->seekStart + 1));
112: }
113: else
114: {
115: header('Content-Length:' . $this->size);
116: }
117:
118: header('Content-Description: File Transfer');
119: header('Content-Type: ' . $this->mime);
120: header('Content-Disposition: attachment;filename="' . $this->name . '"');
121: header('Content-Transfer-Encoding: binary');
122:
123: $handle = fopen($this->path, 'rb');
124: if (!$handle)
125: {
126: throw new \Exception('Erreur pendant le téléchargement');
127: }
128: else
129: {
130: fseek($handle, $this->seekStart);
131: while (!feof($handle)) {
132: set_time_limit(0);
133: echo fread($handle, 1024 * 8);
134: flush();
135: ob_flush();
136: }
137: fclose($handle);
138: }
139: }
140:
141: 142: 143: 144: 145:
146: public function setMimeType($mime)
147: {
148: $this->mime = $mime;
149: }
150:
151: 152: 153: 154:
155: public function setName($name)
156: {
157: $this->name = $name;
158: }
159:
160: 161: 162: 163: 164:
165: private function getRange()
166: {
167:
168: if (isset($_SERVER['HTTP_RANGE']))
169: {
170: list($unit, $ranges) = explode('=', $_SERVER['HTTP_RANGE'], 2);
171: if ($unit == 'bytes')
172: {
173: list($range, $extraRange) = explode(',', $ranges, 2);
174:
175: list($seekStart, $seekEnd) = explode('-', $range, 2);
176:
177: if (!empty($seekStart) && $seekStart > 0)
178: $this->seekStart = intval($seekStart);
179:
180: if (!empty($seekEnd))
181: $this->seekEnd = min(abs(intval($seekEnd)), ($this->size) - 1);
182: }
183: }
184: }
185:
186: 187: 188:
189: private function getMime()
190: {
191: switch ($this->extension)
192: {
193: case 'txt': $this->mime = 'text/plain';
194: break;
195: case 'pdf': $this->mime = 'application/pdf';
196: break;
197: case 'rtf': $this->mime = 'application/rtf';
198: break;
199: case 'jpg': $this->mime = 'image/jpeg';
200: break;
201: case 'xls': $this->mime = 'application/vnd.ms-excel';
202: break;
203: case 'pps': $this->mime = 'application/vnd.ms-powerpoint';
204: break;
205: case 'doc': $this->mime = 'application/msword';
206: break;
207: case 'exe': $this->mime = 'application/octet-stream';
208: break;
209: case 'zip': $this->mime = 'application/zip';
210: break;
211: case 'mp3': $this->mime = 'audio/mpeg';
212: break;
213: case 'mpg': $this->mime = 'video/mpeg';
214: break;
215: case 'avi': $this->mime = 'video/x-msvideo';
216: break;
217: default: $this->mime = 'application/force-download';
218: }
219: }
220:
221: }