15 ## |
15 ## |
16 ## IMAGE FILE FETCHER |
16 ## IMAGE FILE FETCHER |
17 ## |
17 ## |
18 |
18 |
19 $plugins->attachHook('base_classes_initted', ' |
19 $plugins->attachHook('base_classes_initted', ' |
20 global $paths; |
20 global $paths; |
21 $paths->add_page(Array( |
21 $paths->add_page(Array( |
22 \'name\'=>\'Image fetcher pagelet\', |
22 \'name\'=>\'Image fetcher pagelet\', |
23 \'urlname\'=>\'GalleryFetcher\', |
23 \'urlname\'=>\'GalleryFetcher\', |
24 \'namespace\'=>\'Special\', |
24 \'namespace\'=>\'Special\', |
25 \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
25 \'special\'=>0,\'visible\'=>0,\'comments_on\'=>0,\'protected\'=>1,\'delvotes\'=>0,\'delvote_ips\'=>\'\', |
26 )); |
26 )); |
27 '); |
27 '); |
28 |
28 |
29 function page_Special_GalleryFetcher() |
29 function page_Special_GalleryFetcher() |
30 { |
30 { |
31 global $db, $session, $paths, $template, $plugins; // Common objects |
31 global $db, $session, $paths, $template, $plugins; // Common objects |
32 |
32 |
33 // artificial race condition for debug |
33 // artificial race condition for debug |
34 // sleep(5); |
34 // sleep(5); |
35 |
35 |
36 $type = $paths->getParam(0); |
36 $type = $paths->getParam(0); |
37 if ( !in_array($type, array('thumb', 'preview', 'full', 'embed')) ) |
37 if ( !in_array($type, array('thumb', 'preview', 'full', 'embed')) ) |
38 { |
38 { |
39 die('Hack attempt'); |
39 die('Hack attempt'); |
40 } |
40 } |
41 |
41 |
42 $id = intval($paths->getParam(1)); |
42 $id = intval($paths->getParam(1)); |
43 if ( !$id ) |
43 if ( !$id ) |
44 { |
44 { |
45 die('Hack attempt'); |
45 die('Hack attempt'); |
46 } |
46 } |
47 |
47 |
48 // Permissions object |
48 // Permissions object |
49 $perms = $session->fetch_page_acl($id, 'Gallery'); |
49 $perms = $session->fetch_page_acl($id, 'Gallery'); |
50 |
50 |
51 if ( !$perms->get_permissions('gal_full_res') && $type == 'full' ) |
51 if ( !$perms->get_permissions('gal_full_res') && $type == 'full' ) |
52 { |
52 { |
53 $type = 'preview'; |
53 $type = 'preview'; |
54 } |
54 } |
55 |
55 |
56 $q = $db->sql_query('SELECT img_title, img_filename, img_time_mod, is_folder FROM '.table_prefix.'gallery WHERE img_id=' . $id . ';'); |
56 while ( true ) |
57 if ( !$q ) |
57 { |
58 $db->_die(); |
58 $q = $db->sql_query('SELECT img_title, img_filename, img_time_mod, is_folder, processed FROM '.table_prefix.'gallery WHERE img_id=' . $id . ';'); |
59 |
59 if ( !$q ) |
60 if ( $db->numrows() < 1 ) |
60 $db->_die(); |
61 die('Image not found'); |
61 |
62 |
62 if ( $db->numrows() < 1 ) |
63 $row = $db->fetchrow(); |
63 die('Image not found'); |
64 |
64 |
65 switch ( $type ) |
65 $row = $db->fetchrow(); |
66 { |
66 if ( $row['processed'] == 1 || $type == 'full' ) |
67 case 'thumb': |
67 break; |
68 $filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . '-thumb.jpg'; |
68 sleep(1); |
69 $mimetype = 'image/jpeg'; |
69 } |
70 $ext = "jpg"; |
70 |
71 break; |
71 switch ( $type ) |
72 case 'preview': |
72 { |
73 $filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . '-preview.jpg'; |
73 case 'thumb': |
74 $mimetype = 'image/jpeg'; |
74 $filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . '-thumb.jpg'; |
75 $ext = "jpg"; |
75 $mimetype = 'image/jpeg'; |
76 break; |
76 $ext = "jpg"; |
77 case 'full': |
77 break; |
78 $filename = ENANO_ROOT . '/files/' . $row['img_filename']; |
78 case 'preview': |
79 $ext = get_file_extension($filename); |
79 $filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . '-preview.jpg'; |
80 switch($ext) |
80 $mimetype = 'image/jpeg'; |
81 { |
81 $ext = "jpg"; |
82 case 'png': $mimetype = 'image/png'; break; |
82 break; |
83 case 'gif': $mimetype = 'image/gif'; break; |
83 case 'full': |
84 case 'bmp': $mimetype = 'image/bmp'; break; |
84 $filename = ENANO_ROOT . '/files/' . $row['img_filename']; |
85 case 'jpg': case 'jpeg': $mimetype = 'image/jpeg'; break; |
85 $ext = get_file_extension($filename); |
86 case 'tif': case 'tiff': $mimetype = 'image/tiff'; break; |
86 switch($ext) |
87 default: $mimetype = 'application/octet-stream'; |
87 { |
88 } |
88 case 'png': $mimetype = 'image/png'; break; |
89 break; |
89 case 'gif': $mimetype = 'image/gif'; break; |
90 case 'embed': |
90 case 'bmp': $mimetype = 'image/bmp'; break; |
91 if ( !isset($_GET['width']) || !isset($_GET['height']) ) |
91 case 'jpg': case 'jpeg': $mimetype = 'image/jpeg'; break; |
92 { |
92 case 'tif': case 'tiff': $mimetype = 'image/tiff'; break; |
93 die('Missing width or height.'); |
93 default: $mimetype = 'application/octet-stream'; |
94 } |
94 } |
95 $width = intval($_GET['width']); |
95 break; |
96 $height = intval($_GET['height']); |
96 case 'embed': |
97 if ( empty($width) || empty($height) || $width > 2048 || $height > 2048 ) |
97 if ( !isset($_GET['width']) || !isset($_GET['height']) ) |
98 { |
98 { |
99 die('Bad width or height'); |
99 die('Missing width or height.'); |
100 } |
100 } |
101 |
101 $width = intval($_GET['width']); |
102 $ext = get_file_extension($row['img_filename']); |
102 $height = intval($_GET['height']); |
103 |
103 if ( empty($width) || empty($height) || $width > 2048 || $height > 2048 ) |
104 $src_filename = ENANO_ROOT . '/files/' . $row['img_filename']; |
104 { |
105 $dest_filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . "-embed-$width-$height.$ext"; |
105 die('Bad width or height'); |
106 $filename =& $dest_filename; |
106 } |
107 |
107 |
108 if ( !file_exists($dest_filename) ) |
108 $ext = get_file_extension($row['img_filename']); |
109 { |
109 |
110 if ( !scale_image($src_filename, $dest_filename, $width, $height, false) ) |
110 $src_filename = ENANO_ROOT . '/files/' . $row['img_filename']; |
111 { |
111 $dest_filename = ENANO_ROOT . '/cache/' . $row['img_filename'] . "-embed-$width-$height.$ext"; |
112 die('Image scaling process failed.'); |
112 $filename =& $dest_filename; |
113 } |
113 |
114 } |
114 if ( !file_exists($dest_filename) ) |
115 |
115 { |
116 break; |
116 if ( !scale_image($src_filename, $dest_filename, $width, $height, false) ) |
117 default: |
117 { |
118 die('PHP...insane...'); |
118 die('Image scaling process failed.'); |
119 break; |
119 } |
120 } |
120 } |
121 |
121 |
122 // Make sure we have permission to read this image |
122 break; |
123 if ( !$perms->get_permissions('read') ) |
123 default: |
124 { |
124 die('PHP...insane...'); |
125 $filename = ENANO_ROOT . '/plugins/gallery/denied.png'; |
125 break; |
126 $mimetype = 'image/png'; |
126 } |
127 } |
127 |
128 |
128 // Make sure we have permission to read this image |
129 if ( $row['is_folder'] == '1' ) |
129 if ( !$perms->get_permissions('read') ) |
130 { |
130 { |
131 $filename = ENANO_ROOT . '/plugins/gallery/folder.png'; |
131 $filename = ENANO_ROOT . '/plugins/gallery/denied.png'; |
132 $mimetype = 'image/png'; |
132 $mimetype = 'image/png'; |
133 } |
133 } |
134 |
134 |
135 if ( !file_exists($filename) ) |
135 if ( $row['is_folder'] == '1' ) |
136 die('Can\'t retrieve image file ' . $filename); |
136 { |
137 |
137 $filename = ENANO_ROOT . '/plugins/gallery/folder.png'; |
138 $contents = file_get_contents($filename); |
138 $mimetype = 'image/png'; |
139 // expire images 30 days from now |
139 } |
140 $expiry = time() + ( 30 * 86400 ); |
140 |
141 |
141 if ( !file_exists($filename) ) |
142 header('Content-type: ' . $mimetype); |
142 die('Can\'t retrieve image file ' . $filename); |
143 header('Content-length: ' . strlen($contents)); |
143 |
144 header('Last-Modified: ' . date('r', $row['img_time_mod'])); |
144 $contents = file_get_contents($filename); |
145 header('Expires: ' . date('r', $expiry)); |
145 // expire images 30 days from now |
146 |
146 $expiry = time() + ( 30 * 86400 ); |
147 // check for not-modified condition |
147 |
148 if ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ) |
148 header('Content-type: ' . $mimetype); |
149 { |
149 header('Content-length: ' . strlen($contents)); |
150 $time = @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); |
150 header('Last-Modified: ' . date('r', $row['img_time_mod'])); |
151 if ( ( !empty($time) && intval($row['img_time_mod']) <= $time ) || date('r', $row['img_time_mod']) === $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) |
151 header('Expires: ' . date('r', $expiry)); |
152 { |
152 |
153 header('HTTP/1.1 304 Not Modified'); |
153 // check for not-modified condition |
154 $db->close(); |
154 if ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ) |
155 exit; |
155 { |
156 } |
156 $time = @strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); |
157 } |
157 if ( ( !empty($time) && intval($row['img_time_mod']) <= $time ) || date('r', $row['img_time_mod']) === $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) |
158 |
158 { |
159 if ( isset($_GET['download']) ) |
159 header('HTTP/1.1 304 Not Modified'); |
160 { |
160 $db->close(); |
161 // determine an appropriate non-revealing filename |
161 exit; |
162 $filename = str_replace(' ', '_', $row['img_title']); |
162 } |
163 $filename = preg_replace('/([^\w\._-]+)/', '-', $filename); |
163 } |
164 $filename = trim($filename, '-'); |
164 |
165 $filename .= ".$ext"; |
165 if ( isset($_GET['download']) ) |
166 header('Content-disposition: attachment; filename=' . $filename); |
166 { |
167 } |
167 // determine an appropriate non-revealing filename |
168 |
168 $filename = str_replace(' ', '_', $row['img_title']); |
169 echo $contents; |
169 $filename = preg_replace('/([^\w\._-]+)/', '-', $filename); |
170 |
170 $filename = trim($filename, '-'); |
171 gzip_output(); |
171 $filename .= ".$ext"; |
172 |
172 header('Content-disposition: attachment; filename=' . $filename); |
173 $db->close(); |
173 } |
174 exit; |
174 |
175 |
175 echo $contents; |
|
176 |
|
177 gzip_output(); |
|
178 |
|
179 $db->close(); |
|
180 exit; |
|
181 |
176 } |
182 } |
177 |
183 |
178 ?> |
184 ?> |