Skip to content

Commit 39fe12e

Browse files
authored
Merge pull request #413 from digilist/binary_files
Generate embed codes for direct links / binary files
2 parents 512a173 + b8437fb commit 39fe12e

10 files changed

+356
-1
lines changed

src/Detectors/Code.php

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ public function detect(): ?EmbedCode
1212
{
1313
return $this->detectFromEmbed()
1414
?: $this->detectFromOpenGraph()
15-
?: $this->detectFromTwitter();
15+
?: $this->detectFromTwitter()
16+
?: $this->detectFromContentType();
1617
}
1718

1819
private function detectFromEmbed(): ?EmbedCode
@@ -103,4 +104,39 @@ private function detectFromTwitter(): ?EmbedCode
103104

104105
return new EmbedCode($code, $width, $height);
105106
}
107+
108+
private function detectFromContentType()
109+
{
110+
if (!$this->extractor->getResponse()->hasHeader('content-type')) {
111+
return null;
112+
}
113+
114+
$contentType = $this->extractor->getResponse()->getHeader('content-type')[0];
115+
$isBinary = !preg_match('/(text|html|json)/', strtolower($contentType));
116+
if (!$isBinary) {
117+
return null;
118+
}
119+
120+
$url = $this->extractor->getRequest()->getUri();
121+
122+
if (strpos($contentType, 'video/') === 0 || $contentType === 'application/mp4') {
123+
$code = html('video', [
124+
'src' => $url,
125+
'controls' => true,
126+
]);
127+
} elseif (strpos($contentType, 'audio/') === 0) {
128+
$code = html('audio', [
129+
'src' => $url,
130+
'controls' => true,
131+
]);
132+
} elseif (strpos($contentType, 'image/') === 0) {
133+
$code = html('img', [
134+
'src' => $url,
135+
]);
136+
} else {
137+
return null;
138+
}
139+
140+
return new EmbedCode($code);
141+
}
106142
}

src/Http/CurlDispatcher.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ final class CurlDispatcher
1616
private RequestInterface $request;
1717
private $curl;
1818
private array $headers = [];
19+
private $isBinary = false;
1920
private $body;
2021
private ?int $error = null;
2122
private array $settings;
@@ -148,6 +149,11 @@ private function error(string $message, int $code)
148149
return;
149150
}
150151

152+
if ($this->isBinary && $code === CURLE_WRITE_ERROR) {
153+
// The write callback aborted the request to prevent a download of the binary file
154+
return;
155+
}
156+
151157
throw new NetworkException($message, $code, $this->request);
152158
}
153159

@@ -173,6 +179,10 @@ private function writeHeader($curl, $string): int
173179
$name = strtolower($matches[1]);
174180
$value = trim($matches[2]);
175181
$this->headers[] = [$name, $value];
182+
183+
if ($name === 'content-type') {
184+
$this->isBinary = !preg_match('/(text|html|json)/', strtolower($value));
185+
}
176186
} elseif ($this->headers) {
177187
$key = array_key_last($this->headers);
178188
$this->headers[$key][1] .= ' '.trim($string);
@@ -183,6 +193,10 @@ private function writeHeader($curl, $string): int
183193

184194
private function writeBody($curl, $string): int
185195
{
196+
if ($this->isBinary) {
197+
return -1;
198+
}
199+
186200
if (!$this->body) {
187201
$this->body = fopen('php://temp', 'w+');
188202
}

src/functions.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ function html(string $tagName, array $attributes, string $content = null): strin
3232
}
3333
}
3434

35+
if ($tagName === 'img') {
36+
return "${html} />";
37+
}
38+
3539
return "{$html}>{$content}</{$tagName}>";
3640
}
3741

tests/PagesTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,21 @@ public function testPages()
5252
$this->assertEmbed('http://www.wired.com/?p=2064839');
5353
}
5454

55+
public function testImageFile()
56+
{
57+
$this->assertEmbed('https://cdn2.thecatapi.com/images/cjd.jpg');
58+
}
59+
60+
public function testAudioFile()
61+
{
62+
$this->assertEmbed('https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3');
63+
}
64+
65+
public function testVideoFile()
66+
{
67+
$this->assertEmbed('http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4');
68+
}
69+
5570
public function testSnipplr()
5671
{
5772
$this->assertEmbed('http://snipplr.com/view/72914/better-html-5-basic-starter-template');
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
return [
5+
'headers' => [
6+
'date' => [
7+
'Mon, 14 Dec 2020 14:00:00 GMT'
8+
],
9+
'content-type' => [
10+
'image/jpeg'
11+
],
12+
'content-length' => [
13+
'115080'
14+
],
15+
'last-modified' => [
16+
'Thu, 27 Sep 2018 01:08:20 GMT'
17+
],
18+
'etag' => [
19+
'"cf16a912a37899c395d13e4365cddc66"'
20+
],
21+
'x-cache' => [
22+
'Hit from cloudfront'
23+
],
24+
'via' => [
25+
'1.1 a4fe306096165bb1e86e69365dc8fac2.cloudfront.net (CloudFront)'
26+
],
27+
'x-amz-cf-pop' => [
28+
'HIO50-C1'
29+
],
30+
'x-amz-cf-id' => [
31+
'yew4nkqHymQlbChZr0XE9a7vRwOOck-8ClURouHO_RqSOgwC0bXJRw=='
32+
],
33+
'age' => [
34+
'121'
35+
],
36+
'cache-control' => [
37+
'max-age=14400'
38+
],
39+
'cf-cache-status' => [
40+
'HIT'
41+
],
42+
'accept-ranges' => [
43+
'bytes'
44+
],
45+
'cf-request-id' => [
46+
'0703261d8600004150efa67000000001'
47+
],
48+
'expect-ct' => [
49+
'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"'
50+
],
51+
'report-to' => [
52+
'{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report?s=1WksnOmzyCOFgkV%2BlJJYZmdTzPcCDMCnrzrj3nWn7gE%2FBRMm8DbOd3wimmPEvxdWgUFFX66gl6QMRldKI4aO5IyzueCdEKkQGck2sDhY6MGQdMw%3D"}],"group":"cf-nel","max_age":604800}'
53+
],
54+
'nel' => [
55+
'{"report_to":"cf-nel","max_age":604800}'
56+
],
57+
'vary' => [
58+
'Accept-Encoding'
59+
],
60+
'server' => [
61+
'cloudflare'
62+
],
63+
'cf-ray' => [
64+
'601872dc0ce74150-HAM'
65+
],
66+
'Content-Location' => [
67+
'https://cdn2.thecatapi.com/images/cjd.jpg'
68+
],
69+
'X-Request-Time' => [
70+
'0.036 ms'
71+
]
72+
],
73+
'statusCode' => 200,
74+
'reasonPhrase' => 'OK',
75+
'body' => ''
76+
];
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
return [
5+
'headers' => [
6+
'x-guploader-uploadid' => [
7+
'ABg5-UxA3aE4ha-J6yJj6T2_w35hrI3w8q0i3OqMpAVe12aV5dVmshDI-ZZDSKmC_mrtxhdOanZH7EC1uzwHMd19YHE'
8+
],
9+
'expires' => [
10+
'Mon, 14 Dec 2020 15:00:04 GMT'
11+
],
12+
'date' => [
13+
'Mon, 14 Dec 2020 14:00:04 GMT'
14+
],
15+
'cache-control' => [
16+
'public, max-age=3600'
17+
],
18+
'last-modified' => [
19+
'Thu, 05 Dec 2013 18:43:53 GMT'
20+
],
21+
'etag' => [
22+
'"cab08b36195edb1a1231d2d09fa450e0"'
23+
],
24+
'x-goog-generation' => [
25+
'1386269033518000'
26+
],
27+
'x-goog-metageneration' => [
28+
'2'
29+
],
30+
'x-goog-stored-content-encoding' => [
31+
'identity'
32+
],
33+
'x-goog-stored-content-length' => [
34+
'158008374'
35+
],
36+
'content-type' => [
37+
'video/mp4'
38+
],
39+
'x-goog-hash' => [
40+
'crc32c=x4GOmQ==',
41+
'md5=yrCLNhle2xoSMdLQn6RQ4A=='
42+
],
43+
'x-goog-storage-class' => [
44+
'STANDARD'
45+
],
46+
'accept-ranges' => [
47+
'bytes'
48+
],
49+
'content-length' => [
50+
'158008374'
51+
],
52+
'access-control-allow-origin' => [
53+
'*'
54+
],
55+
'access-control-expose-headers' => [
56+
'origin, range'
57+
],
58+
'server' => [
59+
'UploadServer'
60+
],
61+
'Content-Location' => [
62+
'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'
63+
],
64+
'X-Request-Time' => [
65+
'0.305 ms'
66+
]
67+
],
68+
'statusCode' => 200,
69+
'reasonPhrase' => 'OK',
70+
'body' => ''
71+
];
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
return [
5+
'headers' => [
6+
'date' => [
7+
'Mon, 14 Dec 2020 14:00:02 GMT'
8+
],
9+
'server' => [
10+
'Apache/2.4.43 (Unix)'
11+
],
12+
'x-content-type-options' => [
13+
'nosniff'
14+
],
15+
'last-modified' => [
16+
'Sat, 05 Mar 2011 18:33:59 GMT'
17+
],
18+
'etag' => [
19+
'"887e4d-49dc0818373c0"'
20+
],
21+
'accept-ranges' => [
22+
'bytes'
23+
],
24+
'content-length' => [
25+
'8945229'
26+
],
27+
'cache-control' => [
28+
'max-age=1209600'
29+
],
30+
'expires' => [
31+
'Mon, 28 Dec 2020 14:00:02 GMT'
32+
],
33+
'content-type' => [
34+
'audio/mpeg'
35+
],
36+
'Content-Location' => [
37+
'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3'
38+
],
39+
'X-Request-Time' => [
40+
'0.100 ms'
41+
]
42+
],
43+
'statusCode' => 200,
44+
'reasonPhrase' => 'OK',
45+
'body' => ''
46+
];
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
return [
5+
'authorName' => null,
6+
'authorUrl' => null,
7+
'cms' => null,
8+
'code' => [
9+
'html' => '<img src="https://cdn2.thecatapi.com/images/cjd.jpg" />',
10+
'width' => null,
11+
'height' => null,
12+
'ratio' => null
13+
],
14+
'description' => null,
15+
'favicon' => 'https://cdn2.thecatapi.com/favicon.ico',
16+
'feeds' => [],
17+
'icon' => null,
18+
'image' => null,
19+
'keywords' => [],
20+
'language' => null,
21+
'languages' => [],
22+
'license' => null,
23+
'providerName' => 'Thecatapi',
24+
'providerUrl' => 'https://cdn2.thecatapi.com',
25+
'publishedTime' => null,
26+
'redirect' => null,
27+
'title' => null,
28+
'url' => 'https://cdn2.thecatapi.com/images/cjd.jpg',
29+
'linkedData' => [],
30+
'oEmbed' => []
31+
];
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
return [
5+
'authorName' => null,
6+
'authorUrl' => null,
7+
'cms' => null,
8+
'code' => [
9+
'html' => '<video src="http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4" controls></video>',
10+
'width' => null,
11+
'height' => null,
12+
'ratio' => null
13+
],
14+
'description' => null,
15+
'favicon' => 'http://commondatastorage.googleapis.com/favicon.ico',
16+
'feeds' => [],
17+
'icon' => null,
18+
'image' => null,
19+
'keywords' => [],
20+
'language' => null,
21+
'languages' => [],
22+
'license' => null,
23+
'providerName' => 'Commondatastorage',
24+
'providerUrl' => 'http://commondatastorage.googleapis.com',
25+
'publishedTime' => null,
26+
'redirect' => null,
27+
'title' => null,
28+
'url' => 'http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4',
29+
'linkedData' => [],
30+
'oEmbed' => []
31+
];

0 commit comments

Comments
 (0)