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