Browse Source

Start on sniffing

master
J. King 4 years ago
parent
commit
1991f113f8
  1. 3
      composer.json
  2. 55
      composer.lock
  3. 109
      lib/MimeType.php
  4. 34
      vendor-bin/phpunit/composer.lock

3
composer.json

@ -12,7 +12,8 @@
}
],
"require": {
"php": "^7.1"
"php": "^7.1",
"psr/http-message": "^1.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.3",

55
composer.lock

@ -4,8 +4,59 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "8caea8ec6313d5a0b1057c54c7782356",
"packages": [],
"content-hash": "7310d28d306d123fbb958435959d94d4",
"packages": [
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
}
],
"packages-dev": [
{
"name": "bamarni/composer-bin-plugin",

109
lib/MimeType.php

@ -38,20 +38,20 @@ namespace MensBeam\Mime;
*/
class MimeType {
protected const TYPE_PATTERN = <<<'PATTERN'
<^
/^
[\t\r\n ]* # optional leading whitespace
([^/]+) # type
/ # type/subtype delimiter
([^\/]+) # type
\/ # type-subtype delimiter
([^;]+) # subtype (possibly with trailing whitespace)
(;.*)? # optional parameters, to be parsed separately
[\t\r\n ]* # optional trailing whitespace
$>sx
$/sx
PATTERN;
protected const PARAM_PATTERN = <<<'PATTERN'
<
/
[;\t\r\n ]* # parameter delimiter and leading whitespace, all optional
([^=;]*) # parameter name; may be empty
(?:= # parameter name/value delimiter
(?:= # parameter name-value delimiter
(
"(?:\\"|[^"])*(?:"|$)[^;]* # quoted parameter value and optional garbage
|[^;]* # unquoted parameter value (possibly with trailing whitespace)
@ -59,13 +59,52 @@ PATTERN;
)?
;? # optional trailing parameter delimiter
[\t\r\n ]* # optional trailing whitespace
>sx
/sx
PATTERN;
protected const TOKEN_PATTERN = '<^[A-Za-z0-9!#$%&\'*+\-\.\^_`|~]+$>s';
protected const BARE_VALUE_PATTERN = '<^[\t\x{20}-\x{7E}\x{80}-\x{FF}]+$>su';
protected const QUOTED_VALUE_PATTERN = '<^"((?:\\\"|[\t !\x{23}-\x{7E}\x{80}-\x{FF}])*)(?:"|$)>su';
protected const ESCAPE_PATTERN = '<\\\(.)>s';
protected const TOKEN_PATTERN = '/^[A-Za-z0-9!#$%&\'*+\-\.\^_`|~]+$/s';
protected const BARE_VALUE_PATTERN = '/^[\t\x{20}-\x{7E}\x{80}-\x{FF}]+$/su';
protected const QUOTED_VALUE_PATTERN = '/^"((?:\\\"|[\t !\x{23}-\x{7E}\x{80}-\x{FF}])*)(?:"|$)/su';
protected const ESCAPE_PATTERN = '/\\\(.)/s';
protected const CHAR_MAP = [0x80 => "\u{80}","\u{81}","\u{82}","\u{83}","\u{84}","\u{85}","\u{86}","\u{87}","\u{88}","\u{89}","\u{8a}","\u{8b}","\u{8c}","\u{8d}","\u{8e}","\u{8f}","\u{90}","\u{91}","\u{92}","\u{93}","\u{94}","\u{95}","\u{96}","\u{97}","\u{98}","\u{99}","\u{9a}","\u{9b}","\u{9c}","\u{9d}","\u{9e}","\u{9f}","\u{a0}","\u{a1}","\u{a2}","\u{a3}","\u{a4}","\u{a5}","\u{a6}","\u{a7}","\u{a8}","\u{a9}","\u{aa}","\u{ab}","\u{ac}","\u{ad}","\u{ae}","\u{af}","\u{b0}","\u{b1}","\u{b2}","\u{b3}","\u{b4}","\u{b5}","\u{b6}","\u{b7}","\u{b8}","\u{b9}","\u{ba}","\u{bb}","\u{bc}","\u{bd}","\u{be}","\u{bf}","\u{c0}","\u{c1}","\u{c2}","\u{c3}","\u{c4}","\u{c5}","\u{c6}","\u{c7}","\u{c8}","\u{c9}","\u{ca}","\u{cb}","\u{cc}","\u{cd}","\u{ce}","\u{cf}","\u{d0}","\u{d1}","\u{d2}","\u{d3}","\u{d4}","\u{d5}","\u{d6}","\u{d7}","\u{d8}","\u{d9}","\u{da}","\u{db}","\u{dc}","\u{dd}","\u{de}","\u{df}","\u{e0}","\u{e1}","\u{e2}","\u{e3}","\u{e4}","\u{e5}","\u{e6}","\u{e7}","\u{e8}","\u{e9}","\u{ea}","\u{eb}","\u{ec}","\u{ed}","\u{ee}","\u{ef}","\u{f0}","\u{f1}","\u{f2}","\u{f3}","\u{f4}","\u{f5}","\u{f6}","\u{f7}","\u{f8}","\u{f9}","\u{fa}","\u{fb}","\u{fc}","\u{fd}","\u{fe}","\u{ff}"];
protected const SNIFF_PATTERNS_IMAGE = [
'/^\x{00}\x{00}[\x{01}\x{02}]\x{00}/s' => "image/x-icon",
'/^BM/s' => "image/bmp",
'/^GIF8[79]a/s' => "image/gif",
'/^RIFF.{4}WEBPVP/s' => "image/webp",
'/^\x{89}PNG\r\n\x{1A}\n/s' => "image/png",
'/^\x{FF}\x{D8}\x{FF}/s' => "imaged/jpeg",
];
protected const SNIFF_PATTERNS_AUDIOVIDEO = [
'/^\.snd/s' => "audio/basic",
'/^FORM.{4}AIFF/s' => "audio/aiff",
'/^ID3/s' => "audi/mpeg",
'/^OggS\x{00}/s' => "application/ogg",
'/^MThd\x{00}{3}\x{06}/s' => "audio/midi",
'/^RIFF.{4}AVI /s' => "video/avi",
'/^RIFF.{4}WAVE/s' => "audio/wave",
];
protected const SNIFF_PATTERNS_FONT = [
'/^.{34}LP/s' => "application/vnd.ms-fontobject",
'/^\x{00}\x{01}\x{00}{2}/s' => "font/ttf",
'/^OTTO/s' => "font/otf",
'/^ttcf/s' => "font/collection",
'/^wOFF/s' => "font/woff",
'/^wOF2/s' => "font/woff2",
];
protected const SNIFF_PATTERNS_ARCHIVE = [
'/^\x{1F}\x{8B}\x{08}/s' => "application/x-gzip",
'/^PK\x{03}\x{04}/s' => "application/zip",
'/^Rar \x{1A}\x{07}\x{00}/s' => "application/x-rar-compressed",
];
protected const SNIFF_PATTERNS_UNKNWON_SCRIPTABLE = [
'/^\s*<(?:!DOCTYPE HTML|HTML|HEAD|SCRIPT|IFRAME|H1|DIV|FONT|TABLE|A|B|STYLE|TITLE|BODY|BR|P|!--)[ >]/si' => "text/html",
'/^\s*<\?xml/s' => "text/xml",
'/^%PDF-/s' => "application/pdf",
];
protected const SNIFF_PATTERN_UNKNWON_SAFE = [
'/^%!PS-Adobe-/s' => "application/postscript",
'/^(?:(?:\x{FE}\x{FF}|\x{FF}\x{FE})..|\x{EF}\x{BB}\x{BF}.)/s' => "text/plain",
];
protected $type = "";
protected $subtype = "";
@ -265,4 +304,52 @@ PATTERN;
}
return null;
}
public static function interpretHttpMessage(\Psr\Http\Message\MessageInterface $msg, bool $sniff = true): ?self {
$checkForApacheBug = false;
// Use the last Content-Type header-field
$type = array_pop($msg->getHeader("Content-Type"));
if (!is_null($type)) {
if ($msg instanceof \Psr\Http\Message\ResponseInterface) {
$checkForApacheBug = (bool) preg_match("<^text/plain(?:; charset=(?:UTF-8|(?:ISO|iso)-8859-1))?$>", $type);
}
$type = static::decode($type);
}
# stub
return null;
}
public static function sniffImage(string $resource): ?self {
foreach (self::SNIFF_PATTERNS_IMAGE as $pattern => $type) {
if (preg_match($pattern, $resource)) {
return static::parse($type);
}
}
return null;
}
public static function sniffAudioVideo(string $resource): ?self {
foreach (self::SNIFF_PATTERNS_AUDIOVIDEO as $pattern => $type) {
if (preg_match($pattern, $resource)) {
return static::parse($type);
}
}
return static::sniffMp4($resource) ?? static::sniffWebm($resource) ?? static::sniffMp3($resource);
}
protected static function sniffMp4(string $d): ?self {
if (strlen($d) < 12) {
return null;
}
$boxSize = hexdec(bin2hex(substr($d, 0, 4)));
return null;
}
protected static function sniffWebm(string $d): ?self {
return null;
}
protected static function sniffMp3(string $d): ?self {
return null;
}
}

34
vendor-bin/phpunit/composer.lock

@ -493,16 +493,16 @@
},
{
"name": "phpunit/php-file-iterator",
"version": "3.0.0",
"version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
"reference": "354d4a5faa7449a377a18b94a2026ca3415e3d7a"
"reference": "4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/354d4a5faa7449a377a18b94a2026ca3415e3d7a",
"reference": "354d4a5faa7449a377a18b94a2026ca3415e3d7a",
"url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4",
"reference": "4ac5b3e13df14829daa60a2eb4fdd2f2b7d33cf4",
"shasum": ""
},
"require": {
@ -539,7 +539,7 @@
"filesystem",
"iterator"
],
"time": "2020-02-07T06:05:22+00:00"
"time": "2020-04-18T05:02:12+00:00"
},
{
"name": "phpunit/php-invoker",
@ -642,16 +642,16 @@
},
{
"name": "phpunit/php-timer",
"version": "3.0.0",
"version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
"reference": "4118013a4d0f97356eae8e7fb2f6c6472575d1df"
"reference": "35e732ff964693cb91ef4690f1f6016833b68f9d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/4118013a4d0f97356eae8e7fb2f6c6472575d1df",
"reference": "4118013a4d0f97356eae8e7fb2f6c6472575d1df",
"url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/35e732ff964693cb91ef4690f1f6016833b68f9d",
"reference": "35e732ff964693cb91ef4690f1f6016833b68f9d",
"shasum": ""
},
"require": {
@ -663,7 +663,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
"dev-master": "3.1-dev"
}
},
"autoload": {
@ -687,7 +687,7 @@
"keywords": [
"timer"
],
"time": "2020-02-07T06:08:11+00:00"
"time": "2020-04-17T15:08:36+00:00"
},
{
"name": "phpunit/php-token-stream",
@ -1662,16 +1662,16 @@
},
{
"name": "webmozart/assert",
"version": "1.7.0",
"version": "1.8.0",
"source": {
"type": "git",
"url": "https://github.com/webmozart/assert.git",
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598"
"reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/webmozart/assert/zipball/aed98a490f9a8f78468232db345ab9cf606cf598",
"reference": "aed98a490f9a8f78468232db345ab9cf606cf598",
"url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
"reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6",
"shasum": ""
},
"require": {
@ -1679,7 +1679,7 @@
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"vimeo/psalm": "<3.6.0"
"vimeo/psalm": "<3.9.1"
},
"require-dev": {
"phpunit/phpunit": "^4.8.36 || ^7.5.13"
@ -1706,7 +1706,7 @@
"check",
"validate"
],
"time": "2020-02-14T12:15:55+00:00"
"time": "2020-04-18T12:12:48+00:00"
}
],
"aliases": [],

Loading…
Cancel
Save