scratch – Diff between revs 123 and 136
?pathlinks?
Rev 123 | Rev 136 | |||
---|---|---|---|---|
1 | <?php |
1 | <?php |
|
2 | |
2 | |
|
3 | ########################################################################### |
3 | ########################################################################### |
|
4 | ## Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3 ## |
4 | ## Copyright (C) Wizardry and Steamworks 2017 - License: GNU GPLv3 ## |
|
5 | ########################################################################### |
5 | ########################################################################### |
|
6 | |
6 | |
|
7 | require_once('php/pseudocrypt.php'); |
7 | require_once('php/pseudocrypt.php'); |
|
8 | require_once('php/functions.php'); |
8 | require_once('php/functions.php'); |
|
9 | require_once('vendor/autoload.php'); |
9 | require_once('vendor/autoload.php'); |
|
10 | |
10 | |
|
11 | ### FFMpeg |
11 | ### FFMpeg |
|
12 | require_once('vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/FFMpeg.php'); |
12 | require_once('vendor/php-ffmpeg/php-ffmpeg/src/FFMpeg/FFMpeg.php'); |
|
13 | |
13 | |
|
14 | ### Aura URI |
14 | ### Aura URI |
|
15 | require_once('vendor/aura/uri/src/Aura/Uri/PublicSuffixList.php'); |
15 | require_once('vendor/aura/uri/src/Aura/Uri/PublicSuffixList.php'); |
|
16 | require_once('vendor/aura/uri/src/Aura/Uri/Url/Factory.php'); |
16 | require_once('vendor/aura/uri/src/Aura/Uri/Url/Factory.php'); |
|
17 | require_once('vendor/aura/uri/src/Aura/Uri/Query.php'); |
17 | require_once('vendor/aura/uri/src/Aura/Uri/Query.php'); |
|
18 | require_once('vendor/aura/uri/src/Aura/Uri/Host.php'); |
18 | require_once('vendor/aura/uri/src/Aura/Uri/Host.php'); |
|
19 | require_once('vendor/aura/uri/src/Aura/Uri/Url.php'); |
19 | require_once('vendor/aura/uri/src/Aura/Uri/Url.php'); |
|
20 | require_once('vendor/aura/uri/src/Aura/Uri/Path.php'); |
20 | require_once('vendor/aura/uri/src/Aura/Uri/Path.php'); |
|
21 | use Aura\Uri\Url\Factory as UrlFactory; |
21 | use Aura\Uri\Url\Factory as UrlFactory; |
|
22 | use Aura\Uri\PublicSuffixList; |
22 | use Aura\Uri\PublicSuffixList; |
|
23 | |
23 | |
|
24 | ### Load configuration. |
24 | ### Load configuration. |
|
25 | $config = spyc_load_file('config.yaml'); |
25 | $config = spyc_load_file('config.yaml'); |
|
26 | |
26 | |
|
27 | ### If no file has been specified for download then return. |
27 | ### If no file has been specified for download then return. |
|
28 | if (!isset($_GET['hash']) or empty($_GET['hash'])) { |
28 | if (!isset($_GET['hash']) or empty($_GET['hash'])) { |
|
29 | http_response_code(404); |
29 | http_response_code(404); |
|
30 | die('File not found.'); |
30 | die('File not found.'); |
|
31 | } |
31 | } |
|
32 | |
32 | |
|
33 | ### Find the requested file. |
33 | ### Find the requested file. |
|
34 | $file = array_shift( |
34 | $file = array_shift( |
|
35 | preg_grep( |
35 | preg_grep( |
|
36 | "/".$_GET['hash']."/", |
36 | "/".$_GET['hash']."/", |
|
37 | scandir($config['STORE_FOLDER']) |
37 | scandir($config['STORE_FOLDER']) |
|
38 | ) |
38 | ) |
|
39 | ); |
39 | ); |
|
40 | |
40 | |
|
41 | if (!isset($file) or empty($file)) { |
41 | if (!isset($file) or empty($file)) { |
|
42 | http_response_code(404); |
42 | http_response_code(404); |
|
43 | die('File not found.'); |
43 | die('File not found.'); |
|
44 | } |
44 | } |
|
45 | |
45 | |
|
46 | ### Check the path for path traversals. |
46 | ### Check the path for path traversals. |
|
47 | $fileExtension = pathinfo($file, PATHINFO_EXTENSION); |
47 | $fileExtension = pathinfo($file, PATHINFO_EXTENSION); |
|
48 | |
48 | |
|
49 | #### If the extension is not allowed then return. |
49 | #### If the extension is not allowed then return. |
|
50 | if (!isset($fileExtension) || |
50 | if (!isset($fileExtension) || |
|
51 | !in_array(strtoupper($fileExtension), |
51 | !in_array(strtoupper($fileExtension), |
|
52 | array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) { |
52 | array_map('strtoupper', $config['ALLOWED_FILE_EXTENSIONS']))) { |
|
53 | http_response_code(403); |
53 | http_response_code(403); |
|
54 | die('File extension not allowed.'); |
54 | die('File extension not allowed.'); |
|
55 | } |
55 | } |
|
56 | |
56 | |
|
57 | #### Build the user path. |
57 | #### Build the user path. |
|
58 | $userPath = join( |
58 | $userPath = join( |
|
59 | DIRECTORY_SEPARATOR, |
59 | DIRECTORY_SEPARATOR, |
|
60 | array( |
60 | array( |
|
61 | $config['STORE_FOLDER'], |
61 | $config['STORE_FOLDER'], |
|
62 | $file |
62 | $file |
|
63 | ) |
63 | ) |
|
64 | ); |
64 | ); |
|
65 | |
65 | |
|
66 | #### Check for path traversals |
66 | #### Check for path traversals |
|
67 | $pathPart = pathinfo($userPath); |
67 | $pathPart = pathinfo($userPath); |
|
68 | if (strcasecmp( |
68 | if (strcasecmp( |
|
69 | realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) { |
69 | realpath($pathPart['dirname']), realpath($config['STORE_FOLDER'])) != 0) { |
|
70 | http_response_code(500); |
70 | http_response_code(500); |
|
71 | die('Internal server error.'); |
71 | die('Internal server error.'); |
|
72 | } |
72 | } |
|
73 | |
73 | |
|
74 | #### Check if the file exists. |
74 | #### Check if the file exists. |
|
75 | if (!file_exists($userPath)) { |
75 | if (!file_exists($userPath)) { |
|
76 | http_response_code(404); |
76 | http_response_code(404); |
|
77 | die('File not found.'); |
77 | die('File not found.'); |
|
78 | } |
78 | } |
|
79 | |
79 | |
|
80 | ### Extract the server path. |
80 | ### Extract the server path. |
|
81 | $URLFactory = new UrlFactory( |
81 | $URLFactory = new UrlFactory( |
|
82 | $_SERVER, |
82 | $_SERVER, |
|
83 | new PublicSuffixList(require 'vendor/aura/uri/data/public-suffix-list.php') |
83 | new PublicSuffixList(require 'vendor/aura/uri/data/public-suffix-list.php') |
|
84 | ); |
84 | ); |
|
85 | $URL = $URLFactory->newCurrent(); |
85 | $URL = $URLFactory->newCurrent(); |
|
86 | |
86 | |
|
87 | ### HTTPs has to be enforced for opengraph sharing. |
87 | ### HTTPs has to be enforced for opengraph sharing. |
|
88 | if(strtoupper($URL->scheme) != 'HTTPS') |
88 | if(strtoupper($URL->scheme) != 'HTTPS') |
|
89 | $URL->setScheme('https'); |
89 | $URL->setScheme('https'); |
|
90 | |
90 | |
|
91 | $URL_PATH = array_shift( |
91 | $URL_PATH = array_shift( |
|
92 | explode( |
92 | explode( |
|
93 | 'og/'.$_GET['hash'], |
93 | 'og/'.$_GET['hash'], |
|
94 | $URL->getFull() |
94 | $URL->getFull() |
|
95 | ) |
95 | ) |
|
96 | ); |
96 | ); |
|
97 | |
97 | |
|
98 | $GRAPH_URL = $URL_PATH.'og/'.$_GET['hash']; |
98 | $GRAPH_URL = $URL_PATH.'og/'.$_GET['hash']; |
|
99 | $CANON_URL = $URL_PATH.'file.php?hash='.$_GET['hash']; |
99 | $CANON_URL = $URL_PATH.'file.php?hash='.$_GET['hash']; |
|
100 | $BASIC_URL = $URL_PATH.$_GET['hash']; |
100 | $BASIC_URL = $URL_PATH.$_GET['hash']; |
|
101 | |
101 | |
|
102 | switch(strtoupper($fileExtension)) { |
102 | switch(strtoupper($fileExtension)) { |
|
103 | case 'GIF': |
103 | case 'GIF': |
|
104 | list($width, $height) = getimagesize($userPath); |
104 | list($width, $height) = getimagesize($userPath); |
|
105 | echo <<<END |
105 | echo <<<END |
|
106 | <html> |
106 | <html> |
|
107 | <head> |
107 | <head> |
|
- | 108 | <meta property="fb:app_id" content="144991146129146"> |
||
108 | <meta property="og:site_name" content="Scratch Copy"> |
109 | <meta property="og:site_name" content="Scratch Copy"> |
|
- | 110 | <meta property="og:description" content="Scratch Copy"> |
||
109 | <meta property="og:url" content="$BASIC_URL"> |
111 | <meta property="og:url" content="$BASIC_URL"> |
|
110 | <meta property="og:title" content="Scratch Copy"> |
112 | <meta property="og:title" content="Scratch Copy"> |
|
111 | <meta property="og:type" content="video.other"> |
113 | <meta property="og:type" content="video.other"> |
|
112 | <meta property="og:image" content="$BASIC_URL"> |
114 | <meta property="og:image" content="$BASIC_URL"> |
|
113 | <meta property="og:image:width" content="$width"> |
115 | <meta property="og:image:width" content="$width"> |
|
114 | <meta property="og:image:height" content="$height"> |
116 | <meta property="og:image:height" content="$height"> |
|
115 | </head> |
117 | </head> |
|
116 | |
118 | |
|
117 | <body> |
119 | <body> |
|
118 | <p> |
120 | <p> |
|
119 | <img src="$BASIC_URL"> |
121 | <img src="$BASIC_URL"> |
|
120 | </p> |
122 | </p> |
|
121 | </body> |
123 | </body> |
|
122 | |
124 | |
|
123 | </html> |
125 | </html> |
|
124 | END; |
126 | END; |
|
125 | break; |
127 | break; |
|
126 | case 'MP4': |
128 | case 'MP4': |
|
127 | ### Create a thumbnail for the video. |
129 | ### Create a thumbnail for the video. |
|
128 | $file = strtolower( |
130 | $file = strtolower( |
|
129 | PseudoCrypt::hash( |
131 | PseudoCrypt::hash( |
|
130 | preg_replace( |
132 | preg_replace( |
|
131 | '/\D/', |
133 | '/\D/', |
|
132 | '', |
134 | '', |
|
133 | hash( |
135 | hash( |
|
134 | 'sha512', |
136 | 'sha512', |
|
135 | $_GET['hash'] |
137 | $_GET['hash'] |
|
136 | ) |
138 | ) |
|
137 | ), |
139 | ), |
|
138 | $config['ASSET_HASH_SIZE'] |
140 | $config['ASSET_HASH_SIZE'] |
|
139 | ) |
141 | ) |
|
140 | ); |
142 | ); |
|
141 | |
143 | |
|
142 | #### Build the user path. |
144 | #### Build the user path. |
|
143 | $userPath = join( |
145 | $userPath = join( |
|
144 | DIRECTORY_SEPARATOR, |
146 | DIRECTORY_SEPARATOR, |
|
145 | array( |
147 | array( |
|
146 | $config['STORE_FOLDER'], |
148 | $config['STORE_FOLDER'], |
|
147 | $file |
149 | $file |
|
148 | ) |
150 | ) |
|
149 | ); |
151 | ); |
|
150 | |
152 | |
|
151 | ### Do not re-create the thumbnail if it already exists. |
153 | ### Do not re-create the thumbnail if it already exists. |
|
152 | if(!file_exists($userPath.'.'.'jpg')) { |
154 | if(!file_exists($userPath.'.'.'jpg')) { |
|
153 | ### Extract thumbnail. |
155 | ### Extract thumbnail. |
|
154 | $ffmpeg = FFMpeg\FFMpeg::create(); |
156 | $ffmpeg = FFMpeg\FFMpeg::create(); |
|
155 | $video = $ffmpeg->open($CANON_URL); |
157 | $video = $ffmpeg->open($CANON_URL); |
|
156 | $frame = $video->frame( |
158 | $frame = $video->frame( |
|
157 | FFMpeg\Coordinate\TimeCode::fromSeconds( |
159 | FFMpeg\Coordinate\TimeCode::fromSeconds( |
|
158 | $config['VIDEO_PREVIEW_IMAGE_FRAME_SECOND'] |
160 | $config['VIDEO_PREVIEW_IMAGE_FRAME_SECOND'] |
|
159 | ) |
161 | ) |
|
160 | ); |
162 | ); |
|
161 | $frame->save($userPath.'.'.'jpg'); |
163 | $frame->save($userPath.'.'.'jpg'); |
|
162 | } |
164 | } |
|
163 | |
165 | |
|
164 | ### Get preview image size. |
166 | ### Get preview image size. |
|
165 | list($imageWidth, $imageHeight) = getimagesize($userPath.'.'.'jpg'); |
167 | list($imageWidth, $imageHeight) = getimagesize($userPath.'.'.'jpg'); |
|
166 | |
168 | |
|
167 | ### Probe video for width and height. |
169 | ### Probe video for width and height. |
|
168 | $ffprobe = FFMpeg\FFProbe::create(); |
170 | $ffprobe = FFMpeg\FFProbe::create(); |
|
169 | $dimension = $ffprobe |
171 | $dimension = $ffprobe |
|
170 | ->streams($CANON_URL) |
172 | ->streams($CANON_URL) |
|
171 | ->videos() |
173 | ->videos() |
|
172 | ->first() |
174 | ->first() |
|
173 | ->getDimensions(); |
175 | ->getDimensions(); |
|
- | 176 | $videoDuration = round( |
||
- | 177 | $ffprobe |
||
- | 178 | ->streams($CANON_URL) |
||
- | 179 | ->videos() |
||
- | 180 | ->first() |
||
- | 181 | ->get('duration'), |
||
- | 182 | 0, |
||
- | 183 | PHP_ROUND_HALF_UP |
||
- | 184 | ); |
||
174 | |
185 | |
|
175 | $videoWidth = $dimension->getWidth(); |
186 | $videoWidth = $dimension->getWidth(); |
|
176 | $videoHeight = $dimension->getHeight(); |
187 | $videoHeight = $dimension->getHeight(); |
|
177 | |
188 | |
|
178 | ### Build paths. |
189 | ### Build paths. |
|
179 | $PREVIEW_IMAGE_URL = $URL_PATH.$file; |
190 | $PREVIEW_IMAGE_URL = $URL_PATH.$file; |
|
180 | $FLOW_PLAYER_VIDEO_URL = $URL_PATH.'flowplayer/flowplayer.swf?config={"clip":"'.$BASIC_URL.'"}'; |
191 | $FLOW_PLAYER_VIDEO_URL = $URL_PATH.'flowplayer/flowplayer.swf?config={"clip":"'.$BASIC_URL.'"}'; |
|
181 | $FLOW_PLAYER = $URL_PATH.'flowplayer/flowplayer.swf'; |
192 | $FLOW_PLAYER = $URL_PATH.'flowplayer/flowplayer.swf'; |
|
182 | |
193 | |
|
183 | echo <<<END |
194 | echo <<<END |
|
184 | <html> |
195 | <html> |
|
185 | <head> |
196 | <head> |
|
- | 197 | <meta property="fb:app_id" content="144991146129146"> |
||
186 | <meta property="og:type" content="video.other"> |
198 | <meta property="og:type" content="video.other"> |
|
187 | <meta property="og:title" content="Scratch Copy"> |
199 | <meta property="og:title" content="Scratch Copy"> |
|
188 | <meta property="og:site_name" content="Scratch Copy"> |
200 | <meta property="og:site_name" content="Scratch Copy"> |
|
189 | |
- | ||
- | 201 | <meta property="og:description" content="Scratch Copy"> |
||
190 | <meta property="og:url" content="$GRAPH_URL"> |
202 | <meta property="og:url" content="$GRAPH_URL"> |
|
191 | |
- | ||
192 | <meta property="og:image" content="$PREVIEW_IMAGE_URL"> |
203 | <meta property="og:image" content="$PREVIEW_IMAGE_URL"> |
|
193 | <meta property="og:video" content='$FLOW_PLAYER_VIDEO_URL'> |
204 | <meta property="og:video" content='$FLOW_PLAYER_VIDEO_URL'> |
|
194 | <meta property="og:video:secure_url" content='$FLOW_PLAYER_VIDEO_URL'> |
205 | <meta property="og:video:secure_url" content='$FLOW_PLAYER_VIDEO_URL'> |
|
195 | <meta property="og:video:type" content="application/x-shockwave-flash"> |
206 | <meta property="og:video:type" content="application/x-shockwave-flash"> |
|
- | 207 | <meta property="video:duration" content="$videoDuration"> |
||
196 | <meta property="og:video:width" content="$videoWidth"> |
208 | <meta property="og:video:width" content="$videoWidth"> |
|
197 | <meta property="og:video:height" content="$videoHeight"> |
209 | <meta property="og:video:height" content="$videoHeight"> |
|
198 | |
- | ||
199 | <meta property="og:image:width" content="$imageWidth"> |
210 | <meta property="og:image:width" content="$imageWidth"> |
|
200 | <meta property="og:image:height" content="$imageHeight"> |
211 | <meta property="og:image:height" content="$imageHeight"> |
|
201 | </head> |
212 | </head> |
|
202 | |
213 | |
|
203 | <body> |
214 | <body> |
|
204 | <p> |
215 | <p> |
|
205 | <object width="$videoWidth" height="$videoHeight" id="Scratch Copy" name="Scratch Copy" data="$FLOW_PLAYER" type="application/x-shockwave-flash"><param name="movie" value="$FLOW_PLAYER" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="flashvars" value='config={"clip":"$BASIC_URL"}' /></object> |
216 | <object width="$videoWidth" height="$videoHeight" id="Scratch Copy" name="Scratch Copy" data="$FLOW_PLAYER" type="application/x-shockwave-flash"><param name="movie" value="$FLOW_PLAYER" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="flashvars" value='config={"clip":"$BASIC_URL"}' /></object> |
|
206 | </p> |
217 | </p> |
|
207 | </body> |
218 | </body> |
|
208 | |
219 | |
|
209 | </html> |
220 | </html> |
|
210 | END; |
221 | END; |
|
211 | break; |
222 | break; |
|
212 | } |
223 | } |
|
213 | |
224 | |
|
214 | |
225 | |
|
215 | |
226 | |
|
216 | |
227 | |