1
+ <?php
2
+ /*=========================================================================
3
+ MIDAS Server
4
+ Copyright (c) Kitware SAS. 20 rue de la Villette. All rights reserved.
5
+ 69328 Lyon, FRANCE.
6
+
7
+ See Copyright.txt for details.
8
+ This software is distributed WITHOUT ANY WARRANTY; without even
9
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
10
+ PURPOSE. See the above copyright notices for more information.
11
+ =========================================================================*/
12
+
13
+ /** Component that will download a bitstream to the client */
14
+ class DownloadBitstreamComponent extends AppComponent
15
+ {
16
+
17
+ public $ testingmode ;
18
+
19
+ /** Constructor */
20
+ function __construct ()
21
+ {
22
+ }
23
+
24
+ /**
25
+ * Calling this will stream the file to the client.
26
+ * The parameter is a bitstream dao.
27
+ */
28
+ function download ($ bitstream )
29
+ {
30
+ $ mimetype = $ bitstream ->getMimetype ();
31
+ $ path = $ bitstream ->getAssetstore ()->getPath ().'/ ' .$ bitstream ->getPath ();
32
+ $ name = $ bitstream ->getName ();
33
+ if (!file_exists ($ path ))
34
+ {
35
+ throw new Zend_Exception ('Unable to find file on the disk ' );
36
+ }
37
+ $ chunkSize = 1024 * 8 ;
38
+ $ buffer = '' ;
39
+ $ fileSize = filesize ($ path );
40
+ $ handle = fopen ($ path , 'rb ' );
41
+ if ($ handle === false )
42
+ {
43
+ throw new Zend_Exception ('Unable to open the file ' );
44
+ }
45
+ if (!$ this ->testingmode ) //don't send any headers in testing mode since it will break it
46
+ {
47
+ $ modified = gmdate ('D, d M Y H:i:s ' ).' GMT ' ;
48
+ $ contentType = $ mimetype ;
49
+
50
+ header ('Cache-Control: must-revalidate, post-check=0, pre-check=0 ' );
51
+ header ('Last-Modified: ' .$ modified );
52
+ // if pdf set the content-type acordingly
53
+ if (!isset ($ contentType ) && pathinfo ($ name , PATHINFO_EXTENSION ) == 'pdf ' )
54
+ {
55
+ $ contentType = 'application/pdf ' ;
56
+ $ enableContentDisposition = false ;
57
+ }
58
+ if (!isset ($ contentType ))
59
+ {
60
+ $ contentType = 'application/octet-stream ' ;
61
+ }
62
+
63
+ // Hack for .vsp files (for OSA)
64
+ if (!isset ($ contentType ) && strlen ($ name ) > 4 && substr ($ name ,strlen ($ name ) - 4 , 4 ) == '.vsp ' )
65
+ {
66
+ $ contentType = 'application/isp ' ;
67
+ }
68
+
69
+ $ agent = env ('HTTP_USER_AGENT ' );
70
+ if (preg_match ('%Opera(/| )([0-9].[0-9]{1,2})% ' , $ agent ) || preg_match ('/MSIE ([0-9].[0-9]{1,2})/ ' , $ agent ))
71
+ {
72
+ header ('Content-Type: ' .$ contentType );
73
+ header ('Content-Disposition: attachment; filename=" ' .$ name .'"; ' );
74
+ header ('Expires: 0 ' );
75
+ header ('Accept-Ranges: bytes ' );
76
+ header ('Cache-Control: private ' , false );
77
+ header ('Pragma: private ' );
78
+ $ httpRange = env ('HTTP_RANGE ' );
79
+ if (isset ($ httpRange ))
80
+ {
81
+ list ($ toss , $ range ) = explode ('= ' , $ httpRange );
82
+ str_replace ($ range , '- ' , $ range );
83
+ $ size = $ fileSize - 1 ;
84
+ $ length = $ fileSize - $ range ;
85
+ header ('HTTP/1.1 206 Partial Content ' );
86
+ header ('Content-Length: ' .$ length );
87
+ header ('Content-Range: bytes ' .$ range .$ size .'/ ' .$ fileSize );
88
+ fseek ($ handle , $ range );
89
+ }
90
+ else
91
+ {
92
+ header ('Content-Length: ' .$ fileSize );
93
+ }
94
+ }
95
+ else
96
+ {
97
+ header ('Accept-Ranges: bytes ' );
98
+ header ('Expires: 0 ' );
99
+ header ('Content-Type: ' .$ contentType );
100
+ header ('Content-Length: ' .$ fileSize );
101
+ if (!isset ($ enableContentDisposition ) || $ enableContentDisposition == true )
102
+ {
103
+ header ('Content-Disposition: attachment; filename=" ' .$ name .'"; ' );
104
+ }
105
+ if (isset ($ httpRange ))
106
+ {
107
+ list ($ toss , $ range ) = explode ('= ' , $ httpRange );
108
+ str_replace ($ range , '- ' , $ range );
109
+ $ size = $ fileSize - 1 ;
110
+ $ length = $ fileSize - $ range ;
111
+ header ('HTTP/1.1 206 Partial Content ' );
112
+ header ('Content-Length: ' .$ length );
113
+ header ('Content-Range: bytes ' .$ range .$ size .'/ ' .$ fileSize );
114
+ fseek ($ handle , $ range );
115
+ }
116
+ }
117
+ }
118
+ set_time_limit (0 );
119
+
120
+ //kill the whole ob stack (Zend uses double nested output buffers)
121
+ while (!$ this ->testingmode && ob_get_level () > 0 )
122
+ {
123
+ ob_end_clean ();
124
+ }
125
+
126
+ while (!feof ($ handle ) && connection_status () == 0 )
127
+ {
128
+ $ buffer = fread ($ handle , $ chunkSize );
129
+ echo $ buffer ;
130
+ }
131
+ fclose ($ handle );
132
+
133
+ if (!$ this ->testingmode ) //don't exit if we are in testing mode
134
+ {
135
+ exit (connection_status () == 0 && !connection_aborted ());
136
+ }
137
+ }
138
+ } //end class
139
+
140
+
141
+
142
+
143
+
144
+
145
+
146
+
147
+
148
+
149
+
150
+
151
+
152
+
153
+
154
+ /**
155
+ * Gets an environment variable from available sources, and provides emulation
156
+ * for unsupported or inconsistent environment variables (i.e. DOCUMENT_ROOT on
157
+ * IIS, or SCRIPT_NAME in CGI mode). Also exposes some additional custom
158
+ * environment information.
159
+ *
160
+ * @param string $key Environment variable name.
161
+ * @return string Environment variable setting.
162
+ * @link http://book.cakephp.org/view/1130/env
163
+ */
164
+ function env ($ key ) {
165
+ if ($ key == 'HTTPS ' ) {
166
+ if (isset ($ _SERVER ['HTTPS ' ])) {
167
+ return (!empty ($ _SERVER ['HTTPS ' ]) && $ _SERVER ['HTTPS ' ] !== 'off ' );
168
+ }
169
+ return (strpos (env ('SCRIPT_URI ' ), 'https:// ' ) === 0 );
170
+ }
171
+
172
+ if ($ key == 'SCRIPT_NAME ' ) {
173
+ if (env ('CGI_MODE ' ) && isset ($ _ENV ['SCRIPT_URL ' ])) {
174
+ $ key = 'SCRIPT_URL ' ;
175
+ }
176
+ }
177
+
178
+ $ val = null ;
179
+ if (isset ($ _SERVER [$ key ])) {
180
+ $ val = $ _SERVER [$ key ];
181
+ } elseif (isset ($ _ENV [$ key ])) {
182
+ $ val = $ _ENV [$ key ];
183
+ } elseif (getenv ($ key ) !== false ) {
184
+ $ val = getenv ($ key );
185
+ }
186
+
187
+ if ($ key === 'REMOTE_ADDR ' && $ val === env ('SERVER_ADDR ' )) {
188
+ $ addr = env ('HTTP_PC_REMOTE_ADDR ' );
189
+ if ($ addr !== null ) {
190
+ $ val = $ addr ;
191
+ }
192
+ }
193
+
194
+ if ($ val !== null ) {
195
+ return $ val ;
196
+ }
197
+
198
+ switch ($ key ) {
199
+ case 'SCRIPT_FILENAME ' :
200
+ if (defined ('SERVER_IIS ' ) && SERVER_IIS === true ) {
201
+ return str_replace ('\\\\' , '\\' , env ('PATH_TRANSLATED ' ));
202
+ }
203
+ break ;
204
+ case 'DOCUMENT_ROOT ' :
205
+ $ name = env ('SCRIPT_NAME ' );
206
+ $ filename = env ('SCRIPT_FILENAME ' );
207
+ $ offset = 0 ;
208
+ if (!strpos ($ name , '.php ' )) {
209
+ $ offset = 4 ;
210
+ }
211
+ return substr ($ filename , 0 , strlen ($ filename ) - (strlen ($ name ) + $ offset ));
212
+ break ;
213
+ case 'PHP_SELF ' :
214
+ return str_replace (env ('DOCUMENT_ROOT ' ), '' , env ('SCRIPT_FILENAME ' ));
215
+ break ;
216
+ case 'CGI_MODE ' :
217
+ return (PHP_SAPI === 'cgi ' );
218
+ break ;
219
+ case 'HTTP_BASE ' :
220
+ $ host = env ('HTTP_HOST ' );
221
+ if (substr_count ($ host , '. ' ) !== 1 ) {
222
+ return preg_replace ('/^([^.])*/i ' , null , env ('HTTP_HOST ' ));
223
+ }
224
+ return '. ' . $ host ;
225
+ break ;
226
+ }
227
+ return null ;
228
+ }
0 commit comments