From de3acafef9bf4011d6dfee0d9e226c0d22b4c477 Mon Sep 17 00:00:00 2001 From: Chris Caron Date: Sat, 1 Jun 2024 21:43:38 -0400 Subject: [PATCH] Turn large ntfy messages into a attachments (#1136) --- apprise/apprise_attachment.py | 9 +- apprise/attachment/base.py | 44 +- apprise/attachment/file.py | 3 +- apprise/attachment/http.py | 2 +- apprise/attachment/memory.py | 212 ++ apprise/plugins/ntfy.py | 48 +- ...pprise-pytest-session_mocker-removal.patch | 19 +- test/conftest.py | 11 + test/test_apprise_attachments.py | 30 +- test/test_attach_base.py | 9 - test/test_attach_file.py | 3 +- test/test_attach_http.py | 2 +- test/test_attach_memory.py | 205 ++ test/test_plugin_ntfy.py | 45 + test/var/mime.types | 2264 +++++++++++++++++ 15 files changed, 2864 insertions(+), 42 deletions(-) create mode 100644 apprise/attachment/memory.py create mode 100644 test/test_attach_memory.py create mode 100644 test/var/mime.types diff --git a/apprise/apprise_attachment.py b/apprise/apprise_attachment.py index 3c33f9e7..ecf415ec 100644 --- a/apprise/apprise_attachment.py +++ b/apprise/apprise_attachment.py @@ -142,13 +142,8 @@ class AppriseAttachment: # prepare default asset asset = self.asset - if isinstance(attachments, AttachBase): - # Go ahead and just add our attachments into our list - self.attachments.append(attachments) - return True - - elif isinstance(attachments, str): - # Save our path + if isinstance(attachments, (AttachBase, str)): + # store our instance attachments = (attachments, ) elif not isinstance(attachments, (tuple, set, list)): diff --git a/apprise/attachment/base.py b/apprise/attachment/base.py index 71e3a4d0..6ae9d3aa 100644 --- a/apprise/attachment/base.py +++ b/apprise/attachment/base.py @@ -148,6 +148,9 @@ class AttachBase(URLBase): # Absolute path to attachment self.download_path = None + # Track open file pointers + self.__pointers = set() + # Set our cache flag; it can be True, False, None, or a (positive) # integer... nothing else if cache is not None: @@ -226,15 +229,14 @@ class AttachBase(URLBase): Content is cached once determied to prevent overhead of future calls. """ + if not self.exists(): + # we could not obtain our attachment + return None if self._mimetype: # return our pre-calculated cached content return self._mimetype - if not self.exists(): - # we could not obtain our attachment - return None - if not self.detected_mimetype: # guess_type() returns: (type, encoding) and sets type to None # if it can't otherwise determine it. @@ -258,6 +260,9 @@ class AttachBase(URLBase): Simply returns true if the object has downloaded and stored the attachment AND the attachment has not expired. """ + if self.location == ContentLocation.INACCESSIBLE: + # our content is inaccessible + return False cache = self.template_args['cache']['default'] \ if self.cache is None else self.cache @@ -295,6 +300,11 @@ class AttachBase(URLBase): - download_path: Must contain a absolute path to content - detected_mimetype: Should identify mimetype of content """ + + # Remove all open pointers + while self.__pointers: + self.__pointers.pop().close() + self.detected_name = None self.download_path = None self.detected_mimetype = None @@ -314,6 +324,26 @@ class AttachBase(URLBase): raise NotImplementedError( "download() is implimented by the child class.") + def open(self, mode='rb'): + """ + return our file pointer and track it (we'll auto close later + """ + pointer = open(self.path, mode=mode) + self.__pointers.add(pointer) + return pointer + + def __enter__(self): + """ + support with keyword + """ + return self.open() + + def __exit__(self, value_type, value, traceback): + """ + stub to do nothing; but support exit of with statement gracefully + """ + return + @staticmethod def parse_url(url, verify_host=True, mimetype_db=None, sanitize=True): """Parses the URL and returns it broken apart into a dictionary. @@ -376,3 +406,9 @@ class AttachBase(URLBase): True is returned if our content was downloaded correctly. """ return True if self.path else False + + def __del__(self): + """ + Perform any house cleaning + """ + self.invalidate() diff --git a/apprise/attachment/file.py b/apprise/attachment/file.py index c48a707a..88d8f6e1 100644 --- a/apprise/attachment/file.py +++ b/apprise/attachment/file.py @@ -78,7 +78,8 @@ class AttachFile(AttachBase): return 'file://{path}{params}'.format( path=self.quote(self.dirty_path), - params='?{}'.format(self.urlencode(params)) if params else '', + params='?{}'.format(self.urlencode(params, safe='/')) + if params else '', ) def download(self, **kwargs): diff --git a/apprise/attachment/http.py b/apprise/attachment/http.py index aa075d67..870f7cc2 100644 --- a/apprise/attachment/http.py +++ b/apprise/attachment/http.py @@ -352,7 +352,7 @@ class AttachHTTP(AttachBase): port='' if self.port is None or self.port == default_port else ':{}'.format(self.port), fullpath=self.quote(self.fullpath, safe='/'), - params=self.urlencode(params), + params=self.urlencode(params, safe='/'), ) @staticmethod diff --git a/apprise/attachment/memory.py b/apprise/attachment/memory.py new file mode 100644 index 00000000..94645f26 --- /dev/null +++ b/apprise/attachment/memory.py @@ -0,0 +1,212 @@ +# -*- coding: utf-8 -*- +# BSD 2-Clause License +# +# Apprise - Push Notification Library. +# Copyright (c) 2024, Chris Caron +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import re +import os +import io +from .base import AttachBase +from ..common import ContentLocation +from ..locale import gettext_lazy as _ +import uuid + + +class AttachMemory(AttachBase): + """ + A wrapper for Memory based attachment sources + """ + + # The default descriptive name associated with the service + service_name = _('Memory') + + # The default protocol + protocol = 'memory' + + # Content is local to the same location as the apprise instance + # being called (server-side) + location = ContentLocation.LOCAL + + def __init__(self, content=None, name=None, mimetype=None, + encoding='utf-8', **kwargs): + """ + Initialize Memory Based Attachment Object + + """ + # Create our BytesIO object + self._data = io.BytesIO() + + if content is None: + # Empty; do nothing + pass + + elif isinstance(content, str): + content = content.encode(encoding) + if mimetype is None: + mimetype = 'text/plain' + + if not name: + # Generate a unique filename + name = str(uuid.uuid4()) + '.txt' + + elif not isinstance(content, bytes): + raise TypeError( + 'Provided content for memory attachment is invalid') + + # Store our content + if content: + self._data.write(content) + + if mimetype is None: + # Default mimetype + mimetype = 'application/octet-stream' + + if not name: + # Generate a unique filename + name = str(uuid.uuid4()) + '.dat' + + # Initialize our base object + super().__init__(name=name, mimetype=mimetype, **kwargs) + + return + + def url(self, privacy=False, *args, **kwargs): + """ + Returns the URL built dynamically based on specified arguments. + """ + + # Define any URL parameters + params = { + 'mime': self._mimetype, + } + + return 'memory://{name}?{params}'.format( + name=self.quote(self._name), + params=self.urlencode(params, safe='/') + ) + + def open(self, *args, **kwargs): + """ + return our memory object + """ + # Return our object + self._data.seek(0, 0) + return self._data + + def __enter__(self): + """ + support with clause + """ + # Return our object + self._data.seek(0, 0) + return self._data + + def download(self, **kwargs): + """ + Handle memory download() call + """ + + if self.location == ContentLocation.INACCESSIBLE: + # our content is inaccessible + return False + + if self.max_file_size > 0 and len(self) > self.max_file_size: + # The content to attach is to large + self.logger.error( + 'Content exceeds allowable maximum memory size ' + '({}KB): {}'.format( + int(self.max_file_size / 1024), self.url(privacy=True))) + + # Return False (signifying a failure) + return False + + return True + + def invalidate(self): + """ + Removes data + """ + self._data.truncate(0) + return + + def exists(self): + """ + over-ride exists() call + """ + size = len(self) + return True if self.location != ContentLocation.INACCESSIBLE \ + and size > 0 and ( + self.max_file_size <= 0 or + (self.max_file_size > 0 and size <= self.max_file_size)) \ + else False + + @staticmethod + def parse_url(url): + """ + Parses the URL so that we can handle all different file paths + and return it as our path object + + """ + + results = AttachBase.parse_url(url, verify_host=False) + if not results: + # We're done early; it's not a good URL + return results + + if 'name' not in results: + # Allow fall-back to be from URL + match = re.match(r'memory://(?P[^?]+)(\?.*)?', url, re.I) + if match: + # Store our filename only (ignore any defined paths) + results['name'] = \ + os.path.basename(AttachMemory.unquote(match.group('path'))) + return results + + @property + def path(self): + """ + return the filename + """ + if not self.exists(): + # we could not obtain our path + return None + + return self._name + + def __len__(self): + """ + Returns the size of he memory attachment + + """ + return self._data.getbuffer().nbytes + + def __bool__(self): + """ + Allows the Apprise object to be wrapped in an based 'if statement'. + True is returned if our content was downloaded correctly. + """ + + return self.exists() diff --git a/apprise/plugins/ntfy.py b/apprise/plugins/ntfy.py index 805b8726..4814c9aa 100644 --- a/apprise/plugins/ntfy.py +++ b/apprise/plugins/ntfy.py @@ -53,6 +53,7 @@ from ..utils import is_ipaddr from ..utils import validate_regex from ..url import PrivacyMode from ..attachment.base import AttachBase +from ..attachment.memory import AttachMemory class NtfyMode: @@ -172,6 +173,20 @@ class NotifyNtfy(NotifyBase): # Support attachments attachment_support = True + # Maximum title length + title_maxlen = 200 + + # Maximum body length + body_maxlen = 7800 + + # Message size calculates title and body together + overflow_amalgamate_title = True + + # Defines the number of bytes our JSON object can not exceed in size or we + # know the upstream server will reject it. We convert these into + # attachments + ntfy_json_upstream_size_limit = 8000 + # Allows the user to specify the NotifyImageSize object image_size = NotifyImageSize.XY_256 @@ -504,7 +519,7 @@ class NotifyNtfy(NotifyBase): # Prepare our Header virt_payload['filename'] = attach.name - with open(attach.path, 'rb') as fp: + with attach as fp: data = fp.read() if image_url: @@ -538,18 +553,39 @@ class NotifyNtfy(NotifyBase): self.logger.debug('ntfy POST URL: %s (cert_verify=%r)' % ( notify_url, self.verify_certificate, )) - self.logger.debug('ntfy Payload: %s' % str(virt_payload)) - self.logger.debug('ntfy Headers: %s' % str(headers)) - - # Always call throttle before any remote server i/o is made - self.throttle() # Default response type response = None if not attach: data = dumps(data) + if len(data) > self.ntfy_json_upstream_size_limit: + # Convert to an attachment + + if self.notify_format == NotifyFormat.MARKDOWN: + mimetype = 'text/markdown' + elif self.notify_format == NotifyFormat.TEXT: + mimetype = 'text/plain' + + else: # self.notify_format == NotifyFormat.HTML: + mimetype = 'text/html' + + attach = AttachMemory( + mimetype=mimetype, + content='{title}{body}'.format( + title=title + '\n' if title else '', body=body)) + + # Recursively send the message body as an attachment instead + return self._send( + topic=topic, body='', title='', attach=attach, + image_url=image_url, **kwargs) + + self.logger.debug('ntfy Payload: %s' % str(virt_payload)) + self.logger.debug('ntfy Headers: %s' % str(headers)) + + # Always call throttle before any remote server i/o is made + self.throttle() try: r = requests.post( notify_url, diff --git a/packaging/redhat/apprise-pytest-session_mocker-removal.patch b/packaging/redhat/apprise-pytest-session_mocker-removal.patch index b7ec99bd..60557e27 100644 --- a/packaging/redhat/apprise-pytest-session_mocker-removal.patch +++ b/packaging/redhat/apprise-pytest-session_mocker-removal.patch @@ -1,10 +1,19 @@ -diff -Naur apprise-1.6.0/test/conftest.py apprise-1.6.0-patched/test/conftest.py ---- apprise-1.6.0/test/conftest.py 2023-12-27 11:20:40.000000000 -0500 -+++ apprise-1.6.0-patched/test/conftest.py 2023-12-27 13:43:22.583100037 -0500 -@@ -45,8 +45,8 @@ +diff -Naur apprise-1.8.0/test/conftest.py apprise-1.8.0-patched/test/conftest.py +--- apprise-1.8.0/test/conftest.py 2024-06-01 21:28:32.102470720 -0400 ++++ apprise-1.8.0-patched/test/conftest.py 2024-06-01 21:29:32.363754277 -0400 +@@ -46,7 +46,7 @@ A_MGR = AttachmentManager() +-@pytest.fixture(scope="function", autouse=True) ++@pytest.fixture(autouse=True) + def mimetypes_always_available(): + """ + A pytest session fixture which ensures mimetypes is set correctly +@@ -56,8 +56,8 @@ + mimetypes.init(files=files) + + -@pytest.fixture(scope="function", autouse=True) -def no_throttling_everywhere(session_mocker): +@pytest.fixture(autouse=True) @@ -12,7 +21,7 @@ diff -Naur apprise-1.6.0/test/conftest.py apprise-1.6.0-patched/test/conftest.py """ A pytest session fixture which disables throttling on all notifiers. It is automatically enabled. -@@ -57,4 +57,4 @@ +@@ -68,4 +68,4 @@ A_MGR.unload_modules() for plugin in N_MGR.plugins(): diff --git a/test/conftest.py b/test/conftest.py index 50236cc9..34a2d9da 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -30,6 +30,7 @@ import sys import os import pytest +import mimetypes from apprise import NotificationManager from apprise import ConfigurationManager @@ -45,6 +46,16 @@ C_MGR = ConfigurationManager() A_MGR = AttachmentManager() +@pytest.fixture(scope="function", autouse=True) +def mimetypes_always_available(): + """ + A pytest session fixture which ensures mimetypes is set correctly + pointing to our temporary mime.types file + """ + files = (os.path.join(os.path.dirname(__file__), 'var', 'mime.types'), ) + mimetypes.init(files=files) + + @pytest.fixture(scope="function", autouse=True) def no_throttling_everywhere(session_mocker): """ diff --git a/test/test_apprise_attachments.py b/test/test_apprise_attachments.py index 847531ad..27813d37 100644 --- a/test/test_apprise_attachments.py +++ b/test/test_apprise_attachments.py @@ -284,9 +284,6 @@ def test_apprise_attachment_truncate(mock_get): # Add ourselves an object set to truncate ap_obj.add('json://localhost/?method=GET&overflow=truncate') - # Add ourselves a second object without truncate - ap_obj.add('json://localhost/?method=GET&overflow=upstream') - # Create ourselves an attachment object aa = AppriseAttachment() @@ -304,15 +301,36 @@ def test_apprise_attachment_truncate(mock_get): assert mock_get.call_count == 0 assert ap_obj.notify(body='body', title='title', attach=aa) - assert mock_get.call_count == 2 + assert mock_get.call_count == 1 # Our first item was truncated, so only 1 attachment details = mock_get.call_args_list[0] dataset = json.loads(details[1]['data']) assert len(dataset['attachments']) == 1 - # Our second item was not truncated, so all attachments - details = mock_get.call_args_list[1] + # Reset our object + mock_get.reset_mock() + + # our Apprise Object + ap_obj = Apprise() + + # Add ourselves an object set to upstream + ap_obj.add('json://localhost/?method=GET&overflow=upstream') + + # Create ourselves an attachment object + aa = AppriseAttachment() + + # Add 2 attachments + assert aa.add(join(TEST_VAR_DIR, 'apprise-test.gif')) + assert aa.add(join(TEST_VAR_DIR, 'apprise-test.png')) + + assert mock_get.call_count == 0 + assert ap_obj.notify(body='body', title='title', attach=aa) + + assert mock_get.call_count == 1 + + # Our item was not truncated, so all attachments + details = mock_get.call_args_list[0] dataset = json.loads(details[1]['data']) assert len(dataset['attachments']) == 2 diff --git a/test/test_attach_base.py b/test/test_attach_base.py index 8defd79b..26b32055 100644 --- a/test/test_attach_base.py +++ b/test/test_attach_base.py @@ -73,15 +73,6 @@ def test_attach_base(): with pytest.raises(NotImplementedError): obj.download() - with pytest.raises(NotImplementedError): - obj.name - - with pytest.raises(NotImplementedError): - obj.path - - with pytest.raises(NotImplementedError): - obj.mimetype - # Unsupported URLs are not parsed assert AttachBase.parse_url(url='invalid://') is None diff --git a/test/test_attach_file.py b/test/test_attach_file.py index 4f4fadee..d0734832 100644 --- a/test/test_attach_file.py +++ b/test/test_attach_file.py @@ -204,8 +204,7 @@ def test_attach_file(): assert response.path == path assert response.name == 'test.jpeg' assert response.mimetype == 'image/jpeg' - # We will match on mime type now (%2F = /) - assert re.search(r'[?&]mime=image%2Fjpeg', response.url(), re.I) + assert re.search(r'[?&]mime=image/jpeg', response.url(), re.I) assert re.search(r'[?&]name=test\.jpeg', response.url(), re.I) # Test hosted configuration and that we can't add a valid file diff --git a/test/test_attach_http.py b/test/test_attach_http.py index 217ed78f..ad58ed91 100644 --- a/test/test_attach_http.py +++ b/test/test_attach_http.py @@ -229,7 +229,7 @@ def test_attach_http(mock_get, mock_post): attachment = AttachHTTP(**results) assert isinstance(attachment.url(), str) is True # both mime and name over-ridden - assert re.search(r'[?&]mime=image%2Fjpeg', attachment.url()) + assert re.search(r'[?&]mime=image/jpeg', attachment.url()) assert re.search(r'[?&]name=usethis.jpg', attachment.url()) # No Content-Disposition; so we use filename from path assert attachment.name == 'usethis.jpg' diff --git a/test/test_attach_memory.py b/test/test_attach_memory.py new file mode 100644 index 00000000..a4bec417 --- /dev/null +++ b/test/test_attach_memory.py @@ -0,0 +1,205 @@ +# -*- coding: utf-8 -*- +# BSD 2-Clause License +# +# Apprise - Push Notification Library. +# Copyright (c) 2024, Chris Caron +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import re +import urllib +import pytest + +from apprise.attachment.base import AttachBase +from apprise.attachment.memory import AttachMemory +from apprise import AppriseAttachment +from apprise.common import ContentLocation + +# Disable logging for a cleaner testing output +import logging +logging.disable(logging.CRITICAL) + + +def test_attach_memory_parse_url(): + """ + API: AttachMemory().parse_url() + + """ + + # Bad Entry + assert AttachMemory.parse_url(object) is None + + # Our filename is detected automatically + assert AttachMemory.parse_url('memory://') + + # pass our content in as a string + mem = AttachMemory(content='string') + # it loads a string type by default + mem.mimetype == 'text/plain' + # Our filename is automatically generated (with .txt) + assert re.match(r'^[a-z0-9-]+\.txt$', mem.name, re.I) + + # open our file + with mem as fp: + assert fp.getbuffer().nbytes == len(mem) + + # pass our content in as a string + mem = AttachMemory( + content='', name='test.html', mimetype='text/html') + # it loads a string type by default + mem.mimetype == 'text/html' + mem.name == 'test.html' + + # Stub function + assert mem.download() + + with pytest.raises(TypeError): + # garbage in, garbage out + AttachMemory(content=3) + + # pointer to our data + pointer = mem.open() + assert pointer.read() == b'' + + # pass our content in as a string + mem = AttachMemory(content=b'binary-data', name='raw.dat') + # it loads a string type by default + assert mem.mimetype == 'application/octet-stream' + mem.name == 'raw' + + # pass our content in as a string + mem = AttachMemory(content=b'binary-data') + # it loads a string type by default + assert mem.mimetype == 'application/octet-stream' + # Our filename is automatically generated (with .dat) + assert re.match(r'^[a-z0-9-]+\.dat$', mem.name, re.I) + + +def test_attach_memory(): + """ + API: AttachMemory() + + """ + # A url we can test with + fname = 'testfile' + url = 'memory:///ignored/path/{fname}'.format(fname=fname) + + # Simple gif test + response = AppriseAttachment.instantiate(url) + assert isinstance(response, AttachMemory) + + # There is no path yet as we haven't written anything to our memory object + # yet + assert response.path is None + assert bool(response) is False + + with response as memobj: + memobj.write(b'content') + + # Memory object defaults + assert response.name == fname + assert response.path == response.name + assert response.mimetype == 'application/octet-stream' + assert bool(response) is True + + # + fname_in_url = urllib.parse.quote(response.name) + assert response.url().startswith('memory://{}'.format(fname_in_url)) + + # Mime is always part of url + assert re.search(r'[?&]mime=', response.url()) is not None + + # Test case where location is simply set to INACCESSIBLE + # Below is a bad example, but it proves the section of code properly works. + # Ideally a server admin may wish to just disable all File based + # attachments entirely. In this case, they simply just need to change the + # global singleton at the start of their program like: + # + # import apprise + # apprise.attachment.AttachMemory.location = \ + # apprise.ContentLocation.INACCESSIBLE + # + response = AppriseAttachment.instantiate(url) + assert isinstance(response, AttachMemory) + with response as memobj: + memobj.write(b'content') + + response.location = ContentLocation.INACCESSIBLE + assert response.path is None + # Downloads just don't work period + assert response.download() is False + + # File handling (even if image is set to maxium allowable) + response = AppriseAttachment.instantiate(url) + assert isinstance(response, AttachMemory) + with response as memobj: + memobj.write(b'content') + + # Memory handling when size is to large + response = AppriseAttachment.instantiate(url) + assert isinstance(response, AttachMemory) + with response as memobj: + memobj.write(b'content') + + # Test case where we exceed our defined max_file_size in memory + prev_value = AttachBase.max_file_size + AttachBase.max_file_size = len(response) - 1 + # We can't work in this case + assert response.path is None + assert response.download() is False + + # Restore our file_size + AttachBase.max_file_size = prev_value + + response = AppriseAttachment.instantiate( + 'memory://apprise-file.gif?mime=image/gif') + assert isinstance(response, AttachMemory) + with response as memobj: + memobj.write(b'content') + + assert response.name == 'apprise-file.gif' + assert response.path == response.name + assert response.mimetype == 'image/gif' + # No mime-type and/or filename over-ride was specified, so therefore it + # won't show up in the generated URL + assert re.search(r'[?&]mime=', response.url()) is not None + assert 'image/gif' in response.url() + + # Force a mime-type and new name + response = AppriseAttachment.instantiate( + 'memory://{}?mime={}&name={}'.format( + 'ignored.gif', 'image/jpeg', 'test.jpeg')) + assert isinstance(response, AttachMemory) + with response as memobj: + memobj.write(b'content') + + assert response.name == 'test.jpeg' + assert response.path == response.name + assert response.mimetype == 'image/jpeg' + # We will match on mime type now (%2F = /) + assert re.search(r'[?&]mime=image/jpeg', response.url(), re.I) + assert response.url().startswith('memory://test.jpeg') + + # Test hosted configuration and that we can't add a valid memory file + aa = AppriseAttachment(location=ContentLocation.HOSTED) + assert aa.add(response) is False diff --git a/test/test_plugin_ntfy.py b/test/test_plugin_ntfy.py index e976a29c..30d0eacb 100644 --- a/test/test_plugin_ntfy.py +++ b/test/test_plugin_ntfy.py @@ -26,6 +26,7 @@ # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. +import re import os import json from unittest import mock @@ -571,3 +572,47 @@ def test_plugin_ntfy_config_files(mock_post, mock_get): assert len([x for x in aobj.find(tag='ntfy_invalid')]) == 1 assert next(aobj.find(tag='ntfy_invalid')).priority == \ NtfyPriority.NORMAL + + +@mock.patch('requests.post') +def test_plugin_ntfy_message_to_attach(mock_post): + """ + NotifyNtfy() large messages converted into attachments + + """ + + # Prepare Mock return object + response = mock.Mock() + response.content = GOOD_RESPONSE_TEXT + response.status_code = requests.codes.ok + mock_post.return_value = response + + # Create a very, very big message + title = 'My Title' + body = 'b' * NotifyNtfy.ntfy_json_upstream_size_limit + + for fmt in apprise.NOTIFY_FORMATS: + + # Prepare our object + obj = apprise.Apprise.instantiate( + 'ntfy://user:pass@localhost:8080/topic?format={}'.format(fmt)) + + # Our content will actually transfer as an attachment + assert obj.notify(title=title, body=body) + assert mock_post.call_count == 1 + + assert mock_post.call_args_list[0][0][0] == \ + 'http://localhost:8080/topic' + + response = mock_post.call_args_list[0][1] + assert 'data' in response + assert response['data'].decode('utf-8').startswith(title) + assert response['data'].decode('utf-8').endswith(body) + assert 'params' in response + assert 'filename' in response['params'] + # Our filename is automatically generated (with .txt) + assert re.match( + r'^[a-z0-9-]+\.txt$', response['params']['filename'], re.I) + + # Reset our mock object + mock_post.reset_mock() diff --git a/test/var/mime.types b/test/var/mime.types new file mode 100644 index 00000000..4ee74991 --- /dev/null +++ b/test/var/mime.types @@ -0,0 +1,2264 @@ +# This is a comment. I love comments. -*- indent-tabs-mode: t -*- + +# This file controls what Internet media types are sent to the client for +# given file extension(s). Sending the correct media type to the client +# is important so they know how to handle the content of the file. +# Extra types can either be added here or by using an AddType directive +# in your config files. For more information about Internet media types, +# please read RFC 2045, 2046, 2047, 2048, and 2077. The Internet media type +# registry is at . + +# Even types without defined extensions are listed here for completeness. +# Compound extensions like cwl.json are allowed. + +# IANA types + +# MIME type Extensions +application/1d-interleaved-parityfec +application/3gpdash-qoe-report+xml +application/3gppHal+json +application/3gppHalForms+json +application/3gpp-ims+xml +application/A2L a2l +application/ace+cbor +application/ace+json +application/activemessage +application/activity+json +application/aif+cbor +application/aif+json +application/alto-cdni+json +application/alto-cdnifilter+json +application/alto-costmap+json +application/alto-costmapfilter+json +application/alto-directory+json +application/alto-endpointcost+json +application/alto-endpointcostparams+json +application/alto-endpointprop+json +application/alto-endpointpropparams+json +application/alto-error+json +application/alto-networkmap+json +application/alto-propmap+json +application/alto-propmapparams+json +application/alto-updatestreamcontrol+json +application/alto-updatestreamparams+json +application/alto-networkmapfilter+json +application/AML aml +application/andrew-inset ez +application/applefile +application/at+jwt +application/ATF atf +application/ATFX atfx +application/ATXML atxml +application/atom+xml atom +application/atomcat+xml atomcat +application/atomdeleted+xml atomdeleted +application/atomicmail +application/atomsvc+xml atomsvc +application/atsc-dwd+xml dwd +application/atsc-dynamic-event-message +application/atsc-held+xml held +application/atsc-rdt+json +application/atsc-rsat+xml rsat +application/auth-policy+xml apxml +application/automationml-aml+xml +application/automationml-amlx+zip amlx +application/bacnet-xdd+zip xdd +application/batch-SMTP +application/beep+xml +application/calendar+json +application/calendar+xml xcs +application/call-completion +application/CALS-1840 +application/captive+json +application/cap+xml +application/cbor cbor +application/cbor-seq +application/cccex c3ex +application/ccmp+xml ccmp +application/ccxml+xml ccxml +application/cda+xml +application/CDFX+XML cdfx +application/cdmi-capability cdmia +application/cdmi-container cdmic +application/cdmi-domain cdmid +application/cdmi-object cdmio +application/cdmi-queue cdmiq +application/cdni +application/CEA cea +application/cea-2018+xml +application/cellml+xml cellml cml +application/cfw +application/city+json +application/clr 1clr +application/clue_info+xml clue +application/clue+xml +application/cms cmsc +application/cnrp+xml +application/coap-group+json +application/coap-payload +application/commonground +application/concise-problem-details+cbor +application/conference-info+xml +application/cpl+xml cpl +application/cose +application/cose-key +application/cose-key-set +application/cose-x509 +application/csrattrs csrattrs +application/csta+xml +application/CSTAdata+xml +application/csvm+json +application/cwl cwl +application/cwl+json cwl.json +application/cwt +application/cybercash +application/dash+xml mpd +application/dash-patch+xml +application/dashdelta mpdd +application/davmount+xml davmount +application/dca-rft +application/DCD dcd +application/dec-dx +application/dialog-info+xml +application/dicom dcm +application/dicom+json +application/dicom+xml +application/DII dii +application/DIT dit +application/dns +application/dns+json +application/dns-message +application/dots+cbor +application/dpop+jwt +application/dskpp+xml xmls +application/dssc+der dssc +application/dssc+xml xdssc +application/dvcs dvc +application/ecmascript es +application/EDI-consent +application/EDI-X12 +application/EDIFACT +application/efi efi +application/elm+json +application/elm+xml +application/EmergencyCallData.cap+xml +application/EmergencyCallData.Comment+xml +application/EmergencyCallData.Control+xml +application/EmergencyCallData.DeviceInfo+xml +application/EmergencyCallData.eCall.MSD +application/EmergencyCallData.LegacyESN+json +application/EmergencyCallData.ProviderInfo+xml +application/EmergencyCallData.ServiceInfo+xml +application/EmergencyCallData.SubscriberInfo+xml +application/EmergencyCallData.VEDS+xml +application/emma+xml emma +application/emotionml+xml emotionml +application/encaprtp +application/epp+xml +application/epub+zip epub +application/eshop +application/exi exi +application/expect-ct-report+json +application/express exp +application/fastinfoset finf +application/fastsoap +application/fdf +application/fdt+xml fdt +application/fhir+json +application/fhir+xml +# fits, fit, fts: image/fits +application/fits +application/flexfec +# application/font-sfnt deprecated in favor of font/sfnt +application/font-tdpfr pfr +# application/font-woff deprecated in favor of font/woff +application/framework-attributes+xml +application/geo+json geojson +application/geo+json-seq +application/geopackage+sqlite3 gpkg +application/geoxacml+xml +application/gltf-buffer glbin glbuf +application/gml+xml gml +application/gzip gz tgz +application/H224 +application/held+xml +application/hl7v2+xml +application/http +application/hyperstudio stk +application/ibe-key-request+xml +application/ibe-pkg-reply+xml +application/ibe-pp-data +application/iges +application/im-iscomposing+xml +application/index +application/index.cmd +application/index.obj +application/index.response +application/index.vnd +application/inkml+xml ink inkml +application/IOTP +application/ipfix ipfix +application/ipp +application/ISUP +application/its+xml its +application/java-archive jar +# application/javascript obsoleted by text/javascript +application/jf2feed+json +application/jose +application/jose+json +application/jrd+json jrd +application/jscalendar+json +application/json json +application/json-patch+json json-patch +application/json-seq +application/jwk+json +application/jwk-set+json +application/jwt +application/kpml-request+xml +application/kpml-response+xml +application/ld+json jsonld +application/lgr+xml lgr +application/link-format wlnk +application/linkset +application/linkset+json +application/load-control+xml +application/logout+jwt +application/lost+xml lostxml +application/lostsync+xml lostsyncxml +application/lpf+zip lpf +application/LXF lxf +application/mac-binhex40 hqx +application/macwriteii +application/mads+xml mads +application/manifest+json webmanifest +application/marc mrc +application/marcxml+xml mrcx +application/mathematica nb ma mb +application/mathml-content+xml +application/mathml-presentation+xml +application/mathml+xml mml +application/mbms-associated-procedure-description+xml +application/mbms-deregister+xml +application/mbms-envelope+xml +application/mbms-msk-response+xml +application/mbms-msk+xml +application/mbms-protection-description+xml +application/mbms-reception-report+xml +application/mbms-register-response+xml +application/mbms-register+xml +application/mbms-schedule+xml +application/mbms-user-service-description+xml +application/mbox mbox +application/media_control+xml +# mpf: text/vnd.ms-mediapackage +application/media-policy-dataset+xml +application/mediaservercontrol+xml +application/merge-patch+json +application/metalink4+xml meta4 +application/mets+xml mets +application/MF4 mf4 +application/mikey +application/mipc h5 +application/missing-blocks+cbor-seq +application/mmt-aei+xml maei +application/mmt-usd+xml musd +application/mods+xml mods +application/moss-keys +application/moss-signature +application/mosskey-data +application/mosskey-request +application/mp21 m21 mp21 +# mp4, mpg4: video/mp4, see RFC 4337 +application/mp4 +application/mpeg4-generic +application/mpeg4-iod +application/mpeg4-iod-xmt +# xdf: application/xcap-diff+xml +application/mrb-consumer+xml +application/mrb-publish+xml +application/msc-ivr+xml +application/msc-mixer+xml +application/msword doc +application/mud+json +application/multipart-core +application/mxf mxf +application/n-quads nq +application/n-triples nt +application/nasdata +application/news-checkgroups +application/news-groupinfo +application/news-transmission +application/nlsml+xml +application/node +application/nss +application/oauth-authz-req+jwt +application/oblivious-dns-message +application/ocsp-request orq +application/ocsp-response ors +application/octet-stream bin lha lzh exe class so dll img iso +application/ODA oda +application/odm+xml +application/ODX odx +application/oebps-package+xml opf +application/ogg ogx +application/ohttp-keys +application/opc-nodeset+xml +application/oscore +application/oxps oxps +application/p21 p21 stp step stpnc 210 ifc +application/p21+zip stpz +application/p2p-overlay+xml relo +application/parityfec +application/passport +# xer: application/xcap-error+xml +application/patch-ops-error+xml +application/pdf pdf +application/PDX pdx +application/pem-certificate-chain pem +application/pgp-encrypted pgp +application/pgp-keys +application/pgp-signature sig +application/pidf-diff+xml +application/pidf+xml +application/pkcs10 p10 +application/pkcs12 p12 pfx +application/pkcs7-mime p7m p7c +application/pkcs7-signature p7s +application/pkcs8 p8 +application/pkcs8-encrypted p8e +# ac: application/vnd.nokia.n-gage.ac+xml +application/pkix-attr-cert +application/pkix-cert cer +application/pkix-crl crl +application/pkix-pkipath pkipath +application/pkixcmp pki +application/pls+xml pls +application/poc-settings+xml +application/postscript ps eps ai +application/ppsp-tracker+json +application/problem+json +application/problem+xml +application/provenance+xml provx +application/prs.alvestrand.titrax-sheet +application/prs.cww cw cww +application/prs.cyn +application/prs.hpub+zip hpub +application/prs.implied-document+xml +application/prs.implied-executable +application/prs.implied-structure +application/prs.nprend rnd rct +application/prs.plucker +application/prs.rdf-xml-crypt rdf-crypt +application/prs.xsf+xml xsf +application/pskc+xml pskcxml +application/pvd+json +application/QSIG +application/raptorfec +application/rdap+json +application/rdf+xml rdf +application/route-apd+xml rapd +application/route-s-tsid+xml sls +application/route-usd+xml rusd +application/reginfo+xml rif +application/relax-ng-compact-syntax rnc +application/remote-printing +application/reputon+json +application/resource-lists-diff+xml rld +application/resource-lists+xml rl +application/rfc+xml rfcxml +application/riscos +application/rlmi+xml +application/rls-services+xml rs +application/rpki-checklist +application/rpki-ghostbusters gbr +application/rpki-manifest mft +application/rpki-publication +application/rpki-roa roa +application/rpki-updown +application/rtf rtf +application/rtploopback +application/rtx +application/samlassertion+xml +application/samlmetadata+xml +application/sarif-external-properties+json sarif-external-properties sarif-external-properties.json +application/sarif+json sarif sarif.json +application/sbe +application/sbml+xml +application/scaip+xml +# scm: application/vnd.lotus-screencam +application/scim+json scim +application/scvp-cv-request scq +application/scvp-cv-response scs +application/scvp-vp-request spq +application/scvp-vp-response spp +application/sdp sdp +application/secevent+jwt +application/senml-etch+cbor senml-etchc +application/senml-etch+json senml-etchj +application/senml+cbor senmlc +application/senml+json senml +application/senml+xml senmlx +application/senml-exi senmle +application/sensml+cbor sensmlc +application/sensml+json sensml +application/sensml+xml sensmlx +application/sensml-exi sensmle +application/sep+xml +application/sep-exi +application/session-info +application/set-payment +application/set-payment-initiation +application/set-registration +application/set-registration-initiation +application/SGML +application/sgml-open-catalog soc +application/shf+xml shf +application/sieve siv sieve +application/simple-filter+xml cl +application/simple-message-summary +application/simpleSymbolContainer +# h5: application/mipc +application/sipc +application/slate +# application/smil obsoleted by application/smil+xml +application/smil+xml smil smi sml +application/smpte336m +application/soap+fastinfoset +application/soap+xml +application/sparql-query rq +application/spdx+json spdx.json +application/sparql-results+xml srx +application/spirits-event+xml +application/sql sql +application/srgs gram +application/srgs+xml grxml +application/sru+xml sru +application/ssml+xml ssml +application/stix+json stix +application/swid+cbor coswid +application/swid+xml swidtag +application/tamp-apex-update tau +application/tamp-apex-update-confirm auc +application/tamp-community-update tcu +application/tamp-community-update-confirm cuc +application/taxii+json +application/td+json jsontd +application/tamp-error ter +application/tamp-sequence-adjust tsa +application/tamp-sequence-adjust-confirm sac +# tsq: application/timestamp-query +application/tamp-status-query +# tsr: application/timestamp-reply +application/tamp-status-response +application/tamp-update tur +application/tamp-update-confirm tuc +application/tei+xml tei teiCorpus odd +application/TETRA_ISI +application/thraud+xml tfi +application/timestamp-query tsq +application/timestamp-reply tsr +application/timestamped-data tsd +application/tlsrpt+gzip +application/tlsrpt+json +application/tm+json jsontm tm.json tm.jsonld +application/tnauthlist +application/token-introspection+jwt +application/trickle-ice-sdpfrag +application/trig trig +application/ttml+xml ttml +application/tve-trigger +application/tzif +application/tzif-leap +application/ulpfec +application/urc-grpsheet+xml gsheet +application/urc-ressheet+xml rsheet +application/urc-targetdesc+xml td +application/urc-uisocketdesc+xml uis +application/vcard+json +application/vcard+xml +application/vemmi +application/vnd.1000minds.decision-model+xml 1km +application/vnd.1ob ob +application/vnd.3gpp.5gnas +application/vnd.3gpp.access-transfer-events+xml +application/vnd.3gpp.bsf+xml +application/vnd.3gpp.crs+xml +application/vnd.3gpp.current-location-discovery+xml +application/vnd.3gpp.GMOP+xml +application/vnd.3gpp.gtpc +application/vnd.3gpp.interworking-data +application/vnd.3gpp.lpp +application/vnd.3gpp.mc-signalling-ear +application/vnd.3gpp.mcdata-affiliation-command+xml +application/vnd.3gpp.mcdata-info+xml +application/vnd.3gpp.mcdata-msgstore-ctrl-request+xml +application/vnd.3gpp.mcdata-payload +application/vnd.3gpp.mcdata-regroup+xml +application/vnd.3gpp.mcdata-service-config+xml +application/vnd.3gpp.mcdata-signalling +application/vnd.3gpp.mcdata-ue-config+xml +application/vnd.3gpp.mcdata-user-profile+xml +application/vnd.3gpp.mcptt-affiliation-command+xml +application/vnd.3gpp.mcptt-floor-request+xml +application/vnd.3gpp.mcptt-info+xml +application/vnd.3gpp.mcptt-location-info+xml +application/vnd.3gpp.mcptt-mbms-usage-info+xml +application/vnd.3gpp.mcptt-regroup+xml +application/vnd.3gpp.mcptt-service-config+xml +application/vnd.3gpp.mcptt-signed+xml +application/vnd.3gpp.mcptt-ue-config+xml +application/vnd.3gpp.mcptt-ue-init-config+xml +application/vnd.3gpp.mcptt-user-profile+xml +application/vnd.3gpp.mcvideo-affiliation-command+xml +application/vnd.3gpp.mcvideo-info+xml +application/vnd.3gpp.mcvideo-location-info+xml +application/vnd.3gpp.mcvideo-mbms-usage-info+xml +application/vnd.3gpp.mcvideo-regroup+xml +application/vnd.3gpp.mcvideo-service-config+xml +application/vnd.3gpp.mcvideo-transmission-request+xml +application/vnd.3gpp.mcvideo-ue-config+xml +application/vnd.3gpp.mcvideo-user-profile+xml +application/vnd.3gpp.mid-call+xml +application/vnd.3gpp.ngap +application/vnd.3gpp.pfcp +application/vnd.3gpp.pic-bw-large plb +application/vnd.3gpp.pic-bw-small psb +application/vnd.3gpp.pic-bw-var pvb +application/vnd.3gpp-prose-pc3a+xml +application/vnd.3gpp-prose-pc3ach+xml +application/vnd.3gpp-prose+xml +application/vnd.3gpp.s1ap +application/vnd.3gpp.seal-group-doc+xml +application/vnd.3gpp.seal-info+xml +application/vnd.3gpp.seal-location-info+xml +application/vnd.3gpp.seal-mbms-usage-info+xml +application/vnd.3gpp.seal-network-QoS-management-info+xml +application/vnd.3gpp.seal-ue-config-info+xml +application/vnd.3gpp.seal-unicast-info+xml +application/vnd.3gpp.seal-user-profile-info+xml +application/vnd.3gpp-prose-pc3ch+xml +application/vnd.3gpp-prose-pc8+xml +# sms: application/vnd.3gpp2.sms +application/vnd.3gpp.sms +application/vnd.3gpp.sms+xml +application/vnd.3gpp.srvcc-ext+xml +application/vnd.3gpp.SRVCC-info+xml +application/vnd.3gpp.state-and-event-info+xml +application/vnd.3gpp.ussd+xml +application/vnd.3gpp.vae-info+xml +application/vnd.3gpp-v2x-local-service-information +application/vnd.3gpp2.bcmcsinfo+xml +application/vnd.3gpp2.sms sms +application/vnd.3gpp2.tcap tcap +application/vnd.3gpp.v2x +application/vnd.3lightssoftware.imagescal imgcal +application/vnd.3M.Post-it-Notes pwn +application/vnd.accpac.simply.aso aso +application/vnd.accpac.simply.imp imp +application/vnd.acm.addressxfer+json +application/vnd.acucobol acu +application/vnd.acucorp atc acutc +application/vnd.adobe.flash.movie swf +application/vnd.adobe.formscentral.fcdt fcdt +application/vnd.adobe.fxp fxp fxpl +application/vnd.adobe.partial-upload +application/vnd.adobe.xdp+xml xdp +application/vnd.aether.imp +application/vnd.afpc.afplinedata +application/vnd.afpc.afplinedata-pagedef +application/vnd.afpc.cmoca-cmresource +application/vnd.afpc.foca-charset +application/vnd.afpc.foca-codedfont +application/vnd.afpc.foca-codepage +application/vnd.afpc.modca list3820 listafp afp pseg3820 +application/vnd.afpc.modca-cmtable +application/vnd.afpc.modca-formdef +application/vnd.afpc.modca-mediummap +application/vnd.afpc.modca-objectcontainer +application/vnd.afpc.modca-overlay ovl +application/vnd.afpc.modca-pagesegment psg +application/vnd.age age +application/vnd.ah-barcode +application/vnd.ahead.space ahead +application/vnd.airzip.filesecure.azf azf +application/vnd.airzip.filesecure.azs azs +application/vnd.amadeus+json +application/vnd.amazon.mobi8-ebook azw3 +application/vnd.americandynamics.acc acc +application/vnd.amiga.ami ami +application/vnd.amundsen.maze+xml +application/vnd.android.ota ota +application/vnd.anki apkg +application/vnd.anser-web-certificate-issue-initiation cii +# Not in IANA listing, but is on FTP site? +application/vnd.anser-web-funds-transfer-initiation fti +# atx: audio/ATRAC-X +application/vnd.antix.game-component +application/vnd.apache.arrow.file arrow +application/vnd.apache.arrow.stream arrows +application/vnd.apache.thrift.binary +application/vnd.apache.thrift.compact +application/vnd.apache.thrift.json +application/vnd.apexlang apexland apex axdl +application/vnd.api+json +application/vnd.aplextor.warrp+json +application/vnd.apothekende.reservation+json +application/vnd.apple.installer+xml dist distz pkg mpkg +application/vnd.apple.keynote keynote +# m3u: audio/x-mpegurl for now +application/vnd.apple.mpegurl m3u8 +application/vnd.apple.numbers numbers +application/vnd.apple.pages pages +# application/vnd.arastra.swi obsoleted by application/vnd.aristanetworks.swi +application/vnd.aristanetworks.swi swi +application/vnd.artisan+json artisan +application/vnd.artsquare +application/vnd.astraea-software.iota iota +application/vnd.audiograph aep +application/vnd.autopackage package +application/vnd.avalon+json +application/vnd.avistar+xml +application/vnd.balsamiq.bmml+xml bmml +application/vnd.banana-accounting ac2 +application/vnd.bbf.usp.error +application/vnd.balsamiq.bmpr bmpr +application/vnd.bbf.usp.msg +application/vnd.bbf.usp.msg+json +application/vnd.bekitzur-stech+json +application/vnd.belightsoft.lhzd+zip lhzd +application/vnd.belightsoft.lhzl+zip lhzl +application/vnd.bint.med-content +application/vnd.biopax.rdf+xml +application/vnd.blink-idb-value-wrapper +application/vnd.blueice.multipass mpm +application/vnd.bluetooth.ep.oob ep +application/vnd.bluetooth.le.oob le +application/vnd.bmi bmi +application/vnd.bpf +application/vnd.bpf3 +application/vnd.businessobjects rep +application/vnd.byu.uapi+json +application/vnd.cab-jscript +application/vnd.canon-cpdl +application/vnd.canon-lips +application/vnd.capasystems-pg+json +application/vnd.cendio.thinlinc.clientconf tlclient +application/vnd.century-systems.tcp_stream +application/vnd.chemdraw+xml cdxml +application/vnd.chess-pgn pgn +application/vnd.chipnuts.karaoke-mmd mmd +application/vnd.ciedi +application/vnd.cinderella cdy +application/vnd.cirpack.isdn-ext +application/vnd.citationstyles.style+xml csl +application/vnd.claymore cla +application/vnd.cloanto.rp9 rp9 +application/vnd.clonk.c4group c4g c4d c4f c4p c4u +application/vnd.cluetrust.cartomobile-config c11amc +application/vnd.cluetrust.cartomobile-config-pkg c11amz +application/vnd.cncf.helm.chart.content.v1.tar+gzip +application/vnd.cncf.helm.chart.provenance.v1.prov +application/vnd.cncf.helm.config.v1+json +application/vnd.coffeescript coffee +application/vnd.collabio.xodocuments.document xodt +application/vnd.collabio.xodocuments.document-template xott +application/vnd.collabio.xodocuments.presentation xodp +application/vnd.collabio.xodocuments.presentation-template xotp +application/vnd.collabio.xodocuments.spreadsheet xods +application/vnd.collabio.xodocuments.spreadsheet-template xots +application/vnd.collection+json +application/vnd.collection.doc+json +application/vnd.collection.next+json +application/vnd.comicbook-rar cbr +application/vnd.comicbook+zip cbz +# icc: application/vnd.iccprofile +application/vnd.commerce-battelle ica icf icd ic0 ic1 ic2 ic3 ic4 ic5 ic6 ic7 ic8 +application/vnd.commonspace csp cst +application/vnd.contact.cmsg cdbcmsg +application/vnd.coreos.ignition+json ign ignition +application/vnd.cosmocaller cmc +application/vnd.crick.clicker clkx +application/vnd.crick.clicker.keyboard clkk +application/vnd.crick.clicker.palette clkp +application/vnd.crick.clicker.template clkt +application/vnd.crick.clicker.wordbank clkw +application/vnd.criticaltools.wbs+xml wbs +application/vnd.cryptii.pipe+json +application/vnd.crypto-shade-file ssvc +application/vnd.cryptomator.encrypted c9r c9s +application/vnd.cryptomator.vault cryptomator +application/vnd.ctc-posml pml +application/vnd.ctct.ws+xml +application/vnd.cups-pdf +application/vnd.cups-postscript +application/vnd.cups-ppd ppd +application/vnd.cups-raster +application/vnd.cups-raw +application/vnd.curl curl +application/vnd.cyan.dean.root+xml +application/vnd.cybank +# json: application/json +application/vnd.cyclonedx+json +# xml: text/xml +application/vnd.cyclonedx+xml +application/vnd.d2l.coursepackage1p0+zip +# json: application/json +application/vnd.d3m-dataset +# json: application/json +application/vnd.d3m-problem +application/vnd.dart dart +application/vnd.data-vision.rdz rdz +application/vnd.datalog dl +application/vnd.datapackage+json +application/vnd.dataresource+json +application/vnd.dbf dbf +application/vnd.debian.binary-package deb udeb +application/vnd.dece.data uvf uvvf uvd uvvd +application/vnd.dece.ttml+xml uvt uvvt +application/vnd.dece.unspecified uvx uvvx +application/vnd.dece.zip uvz uvvz +application/vnd.denovo.fcselayout-link fe_launch +application/vnd.desmume.movie dsm +application/vnd.dir-bi.plate-dl-nosuffix +application/vnd.dm.delegation+xml +application/vnd.dna dna +application/vnd.document+json docjson +application/vnd.dolby.mobile.1 +application/vnd.dolby.mobile.2 +application/vnd.doremir.scorecloud-binary-document scld +application/vnd.dpgraph dpg mwc dpgraph +application/vnd.dreamfactory dfac +application/vnd.drive+json +application/vnd.dtg.local +application/vnd.dtg.local.flash fla +application/vnd.dtg.local.html +application/vnd.dvb.ait ait +application/vnd.dvb.dvbisl+xml +# class: application/octet-stream +application/vnd.dvb.dvbj +application/vnd.dvb.esgcontainer +application/vnd.dvb.ipdcdftnotifaccess +application/vnd.dvb.ipdcesgaccess +application/vnd.dvb.ipdcesgaccess2 +application/vnd.dvb.ipdcesgpdd +application/vnd.dvb.ipdcroaming +application/vnd.dvb.iptv.alfec-base +application/vnd.dvb.iptv.alfec-enhancement +application/vnd.dvb.notif-aggregate-root+xml +application/vnd.dvb.notif-container+xml +application/vnd.dvb.notif-generic+xml +application/vnd.dvb.notif-ia-msglist+xml +application/vnd.dvb.notif-ia-registration-request+xml +application/vnd.dvb.notif-ia-registration-response+xml +application/vnd.dvb.notif-init+xml +# pfr: application/font-tdpfr +application/vnd.dvb.pfr +application/vnd.dvb.service svc +# dxr: application/x-director +application/vnd.dxr +application/vnd.dynageo geo +application/vnd.dzr dzr +application/vnd.easykaraoke.cdgdownload +application/vnd.ecdis-update +application/vnd.ecip.rlp +application/vnd.eclipse.ditto+json +application/vnd.ecowin.chart mag +application/vnd.ecowin.filerequest +application/vnd.ecowin.fileupdate +application/vnd.ecowin.series +application/vnd.ecowin.seriesrequest +application/vnd.ecowin.seriesupdate +# img: application/octet-stream +application/vnd.efi.img +# iso: application/octet-stream +application/vnd.efi.iso +application/vnd.eln+zip eln +application/vnd.emclient.accessrequest+xml +application/vnd.enliven nml +application/vnd.enphase.envoy +application/vnd.eprints.data+xml +application/vnd.epson.esf esf +application/vnd.epson.msf msf +application/vnd.epson.quickanime qam +application/vnd.epson.salt slt +application/vnd.epson.ssf ssf +application/vnd.ericsson.quickcall qcall qca +application/vnd.espass-espass+zip espass +application/vnd.eszigno3+xml es3 et3 +application/vnd.etsi.aoc+xml +application/vnd.etsi.asic-e+zip asice sce +# scs: application/scvp-cv-response +application/vnd.etsi.asic-s+zip asics +application/vnd.etsi.cug+xml +application/vnd.etsi.iptvcommand+xml +application/vnd.etsi.iptvdiscovery+xml +application/vnd.etsi.iptvprofile+xml +application/vnd.etsi.iptvsad-bc+xml +application/vnd.etsi.iptvsad-cod+xml +application/vnd.etsi.iptvsad-npvr+xml +application/vnd.etsi.iptvservice+xml +application/vnd.etsi.iptvsync+xml +application/vnd.etsi.iptvueprofile+xml +application/vnd.etsi.mcid+xml +application/vnd.etsi.mheg5 +application/vnd.etsi.overload-control-policy-dataset+xml +application/vnd.etsi.pstn+xml +application/vnd.etsi.sci+xml +application/vnd.etsi.simservs+xml +application/vnd.etsi.timestamp-token tst +application/vnd.etsi.tsl.der +application/vnd.eu.kasparian.car+json carjson +application/vnd.etsi.tsl+xml +application/vnd.eudora.data +application/vnd.exstream-empower+zip mpw +application/vnd.exstream-package pub +application/vnd.evolv.ecig.profile ecigprofile +application/vnd.evolv.ecig.settings ecig +application/vnd.evolv.ecig.theme ecigtheme +application/vnd.ezpix-album ez2 +application/vnd.ezpix-package ez3 +application/vnd.f-secure.mobile +application/vnd.fastcopy-disk-image dim +application/vnd.familysearch.gedcom+zip gdz +application/vnd.fdf fdf +application/vnd.fdsn.mseed msd mseed +application/vnd.fdsn.seed seed dataless +application/vnd.ffsns +application/vnd.ficlab.flb+zip flb +application/vnd.filmit.zfc zfc +# all extensions: application/vnd.hbci +application/vnd.fints +application/vnd.firemonkeys.cloudcell +application/vnd.FloGraphIt gph +application/vnd.fluxtime.clip ftc +application/vnd.font-fontforge-sfd sfd +application/vnd.framemaker fm +application/vnd.frogans.fnc fnc +application/vnd.frogans.ltf ltf +application/vnd.fsc.weblaunch fsc +# xdw: application/vnd.fujixerox.docuworks +application/vnd.fujifilm.fb.docuworks +# xbd: application/vnd.fujixerox.docuworks.binder +application/vnd.fujifilm.fb.docuworks.binder +# xct: application/vnd.fujixerox.docuworks.container +application/vnd.fujifilm.fb.docuworks.container +application/vnd.fujifilm.fb.jfi+xml +application/vnd.fujitsu.oasys oas +application/vnd.fujitsu.oasys2 oa2 +application/vnd.fujitsu.oasys3 oa3 +application/vnd.fujitsu.oasysgp fg5 +application/vnd.fujitsu.oasysprs bh2 +application/vnd.fujixerox.ART-EX +application/vnd.fujixerox.ART4 +application/vnd.fujixerox.ddd ddd +application/vnd.fujixerox.docuworks xdw +application/vnd.fujixerox.docuworks.binder xbd +application/vnd.fujixerox.docuworks.container xct +application/vnd.fujixerox.HBPL +application/vnd.fut-misnet +application/vnd.futoin+cbor +application/vnd.futoin+json +application/vnd.fuzzysheet fzs +application/vnd.genomatix.tuxedo txd +application/vnd.genozip genozip +application/vnd.gentics.grd+json +application/vnd.gentoo.catmetadata+xml +application/vnd.gentoo.ebuild ebuild +application/vnd.gentoo.eclass eclass +application/vnd.gentoo.gpkg gpkg.tar +application/vnd.gentoo.manifest +application/vnd.gentoo.xpak tbz2 xpak +application/vnd.gentoo.pkgmetadata+xml +# application/vnd.geo+json obsoleted by application/geo+json +application/vnd.geocube+xml g3 g³ +application/vnd.geogebra.file ggb +application/vnd.geogebra.slides ggs +application/vnd.geogebra.tool ggt +application/vnd.geometry-explorer gex gre +application/vnd.geonext gxt +application/vnd.geoplan g2w +application/vnd.geospace g3w +# gbr: application/rpki-ghostbusters +application/vnd.gerber +application/vnd.globalplatform.card-content-mgt +application/vnd.globalplatform.card-content-mgt-response +application/vnd.gmx gmx +application/vnd.gnu.taler.exchange+json +application/vnd.gnu.taler.merchant+json +application/vnd.google-earth.kml+xml kml +application/vnd.google-earth.kmz kmz +application/vnd.gov.sk.e-form+xml +application/vnd.gov.sk.e-form+zip +application/vnd.gov.sk.xmldatacontainer+xml +application/vnd.gpxsee.map+xml +application/vnd.grafeq gqf gqs +application/vnd.gridmp +application/vnd.groove-account gac +application/vnd.groove-help ghf +application/vnd.groove-identity-message gim +application/vnd.groove-injector grv +application/vnd.groove-tool-message gtm +application/vnd.groove-tool-template tpl +application/vnd.groove-vcard vcg +application/vnd.hal+json +application/vnd.hal+xml hal +application/vnd.HandHeld-Entertainment+xml zmm +application/vnd.hbci hbci hbc kom upa pkd bpd +application/vnd.hc+json +# rep: application/vnd.businessobjects +application/vnd.hcl-bireports +application/vnd.hdt hdt +application/vnd.heroku+json +application/vnd.hhe.lesson-player les +application/vnd.hp-HPGL hpgl +application/vnd.hp-hpid hpi hpid +application/vnd.hp-hps hps +application/vnd.hp-jlyt jlt +application/vnd.hp-PCL pcl +application/vnd.hp-PCLXL +application/vnd.hsl hsl +application/vnd.httphone +application/vnd.hydrostatix.sof-data sfd-hdstx +application/vnd.hyper+json +application/vnd.hyper-item+json +application/vnd.hyperdrive+json +application/vnd.hzn-3d-crossword x3d +# application/vnd.ibm.afplinedata obsoleted by application/vnd.afpc.afplinedata +application/vnd.ibm.electronic-media emm +application/vnd.ibm.MiniPay mpy +# application/vnd.ibm.modcap obsoleted by application/vnd.afpc.modca +application/vnd.ibm.rights-management irm +application/vnd.ibm.secure-container sc +application/vnd.iccprofile icc icm +application/vnd.ieee.1905 1905.1 +application/vnd.igloader igl +application/vnd.imagemeter.folder+zip imf +application/vnd.imagemeter.image+zip imi +application/vnd.immervision-ivp ivp +application/vnd.immervision-ivu ivu +application/vnd.ims.imsccv1p1 imscc +application/vnd.ims.imsccv1p2 +application/vnd.ims.imsccv1p3 +application/vnd.ims.lis.v2.result+json +application/vnd.ims.lti.v2.toolconsumerprofile+json +application/vnd.ims.lti.v2.toolproxy.id+json +application/vnd.ims.lti.v2.toolproxy+json +application/vnd.ims.lti.v2.toolsettings+json +application/vnd.ims.lti.v2.toolsettings.simple+json +application/vnd.informedcontrol.rms+xml +# application/vnd.informix-visionary obsoleted by application/vnd.visionary +application/vnd.infotech.project +application/vnd.infotech.project+xml +application/vnd.innopath.wamp.notification +application/vnd.insors.igm igm +application/vnd.intercon.formnet xpw xpx +application/vnd.intergeo i2g +application/vnd.intertrust.digibox +application/vnd.intertrust.nncp +application/vnd.intu.qbo qbo +application/vnd.intu.qfx qfx +application/vnd.ipld.car car +application/vnd.ipld.dag-cbor +application/vnd.ipld.dag-json +application/vnd.ipld.raw +application/vnd.iptc.g2.catalogitem+xml +application/vnd.iptc.g2.conceptitem+xml +application/vnd.iptc.g2.knowledgeitem+xml +application/vnd.iptc.g2.newsitem+xml +application/vnd.iptc.g2.newsmessage+xml +application/vnd.iptc.g2.packageitem+xml +application/vnd.iptc.g2.planningitem+xml +application/vnd.ipunplugged.rcprofile rcprofile +application/vnd.irepository.package+xml irp +application/vnd.is-xpr xpr +application/vnd.isac.fcs fcs +application/vnd.jam jam +application/vnd.iso11783-10+zip +application/vnd.japannet-directory-service +application/vnd.japannet-jpnstore-wakeup +application/vnd.japannet-payment-wakeup +application/vnd.japannet-registration +application/vnd.japannet-registration-wakeup +application/vnd.japannet-setstore-wakeup +application/vnd.japannet-verification +application/vnd.japannet-verification-wakeup +application/vnd.jcp.javame.midlet-rms rms +application/vnd.jisp jisp +application/vnd.joost.joda-archive joda +application/vnd.jsk.isdn-ngn +application/vnd.kahootz ktz ktr +application/vnd.kde.karbon karbon +application/vnd.kde.kchart chrt +application/vnd.kde.kformula kfo +application/vnd.kde.kivio flw +application/vnd.kde.kontour kon +application/vnd.kde.kpresenter kpr kpt +application/vnd.kde.kspread ksp +application/vnd.kde.kword kwd kwt +application/vnd.kenameaapp htke +application/vnd.kidspiration kia +application/vnd.Kinar kne knp sdf +application/vnd.koan skp skd skm skt +application/vnd.kodak-descriptor sse +application/vnd.las las +application/vnd.las.las+json lasjson +application/vnd.las.las+xml lasxml +application/vnd.laszip +application/vnd.leap+json +application/vnd.liberty-request+xml +application/vnd.llamagraphics.life-balance.desktop lbd +application/vnd.llamagraphics.life-balance.exchange+xml lbe +application/vnd.logipipe.circuit+zip lcs lca +application/vnd.loom loom +application/vnd.lotus-1-2-3 123 wk4 wk3 wk1 +application/vnd.lotus-approach apr vew +application/vnd.lotus-freelance prz pre +application/vnd.lotus-notes nsf ntf ndl ns4 ns3 ns2 nsh nsg +application/vnd.lotus-organizer or3 or2 org +application/vnd.lotus-screencam scm +application/vnd.lotus-wordpro lwp sam +application/vnd.macports.portpkg portpkg +application/vnd.mapbox-vector-tile mvt +application/vnd.marlin.drm.actiontoken+xml +application/vnd.marlin.drm.conftoken+xml +application/vnd.marlin.drm.license+xml +application/vnd.marlin.drm.mdcf mdc +application/vnd.mason+json +application/vnd.maxar.archive.3tz+zip 3tz +application/vnd.maxmind.maxmind-db mmdb +application/vnd.mcd mcd +application/vnd.mdl mdl +application/vnd.mdl-mbsdf mbsdf +application/vnd.medcalcdata mc1 +application/vnd.mediastation.cdkey cdkey +application/vnd.medicalholodeck.recordxr rxr +application/vnd.meridian-slingshot +application/vnd.MFER mwf +application/vnd.mfmp mfm +application/vnd.micro+json +application/vnd.micrografx.flo flo +application/vnd.micrografx.igx igx +application/vnd.microsoft.portable-executable +application/vnd.microsoft.windows.thumbnail-cache +application/vnd.miele+json +application/vnd.mif mif +application/vnd.minisoft-hp3000-save +application/vnd.mitsubishi.misty-guard.trustweb +application/vnd.Mobius.DAF daf +application/vnd.Mobius.DIS dis +application/vnd.Mobius.MBK mbk +application/vnd.Mobius.MQY mqy +application/vnd.Mobius.MSL msl +application/vnd.Mobius.PLC plc +application/vnd.Mobius.TXF txf +application/vnd.modl modl +application/vnd.mophun.application mpn +application/vnd.mophun.certificate mpc +application/vnd.motorola.flexsuite +application/vnd.motorola.flexsuite.adsi +application/vnd.motorola.flexsuite.fis +application/vnd.motorola.flexsuite.gotap +application/vnd.motorola.flexsuite.kmr +application/vnd.motorola.flexsuite.ttc +application/vnd.motorola.flexsuite.wem +application/vnd.motorola.iprm +application/vnd.mozilla.xul+xml xul +application/vnd.ms-3mfdocument 3mf +application/vnd.ms-artgalry cil +application/vnd.ms-asf asf +application/vnd.ms-cab-compressed cab +application/vnd.ms-excel xls xlm xla xlc xlt xlw +application/vnd.ms-excel.template.macroEnabled.12 xltm +application/vnd.ms-excel.addin.macroEnabled.12 xlam +application/vnd.ms-excel.sheet.binary.macroEnabled.12 xlsb +application/vnd.ms-excel.sheet.macroEnabled.12 xlsm +application/vnd.ms-fontobject eot +application/vnd.ms-htmlhelp chm +application/vnd.ms-ims ims +application/vnd.ms-lrm lrm +application/vnd.ms-office.activeX+xml +application/vnd.ms-officetheme thmx +application/vnd.ms-playready.initiator+xml +application/vnd.ms-powerpoint ppt pps pot +application/vnd.ms-powerpoint.addin.macroEnabled.12 ppam +application/vnd.ms-powerpoint.presentation.macroEnabled.12 pptm +application/vnd.ms-powerpoint.slide.macroEnabled.12 sldm +application/vnd.ms-powerpoint.slideshow.macroEnabled.12 ppsm +application/vnd.ms-powerpoint.template.macroEnabled.12 potm +application/vnd.ms-PrintDeviceCapabilities+xml +application/vnd.ms-PrintSchemaTicket+xml +application/vnd.ms-project mpp mpt +application/vnd.ms-tnef tnef tnf +application/vnd.ms-windows.devicepairing +application/vnd.ms-windows.nwprinting.oob +application/vnd.ms-windows.printerpairing +application/vnd.ms-windows.wsd.oob +application/vnd.ms-wmdrm.lic-chlg-req +application/vnd.ms-wmdrm.lic-resp +application/vnd.ms-wmdrm.meter-chlg-req +application/vnd.ms-wmdrm.meter-resp +application/vnd.ms-word.document.macroEnabled.12 docm +application/vnd.ms-word.template.macroEnabled.12 dotm +application/vnd.ms-works wcm wdb wks wps +application/vnd.ms-wpl wpl +application/vnd.ms-xpsdocument xps +application/vnd.msa-disk-image msa +application/vnd.mseq mseq +application/vnd.msign +application/vnd.multiad.creator crtr +application/vnd.multiad.creator.cif cif +application/vnd.music-niff +application/vnd.musician mus +application/vnd.muvee.style msty +application/vnd.mynfc taglet +application/vnd.nacamar.ybrid+json +application/vnd.ncd.control +application/vnd.ncd.reference +application/vnd.nearst.inv+json +application/vnd.nebumind.line nebul line +application/vnd.nervana entity request bkm kcm +application/vnd.netfpx +application/vnd.nimn nimn +# ntf: application/vnd.lotus-notes +application/vnd.nitf nitf +application/vnd.neurolanguage.nlu nlu +application/vnd.nintendo.nitro.rom nds +application/vnd.nintendo.snes.rom sfc smc +application/vnd.noblenet-directory nnd +application/vnd.noblenet-sealer nns +application/vnd.noblenet-web nnw +application/vnd.nokia.catalogs +application/vnd.nokia.conml+wbxml +application/vnd.nokia.conml+xml +application/vnd.nokia.iptv.config+xml +application/vnd.nokia.iSDS-radio-presets +application/vnd.nokia.landmark+wbxml +application/vnd.nokia.landmark+xml +application/vnd.nokia.landmarkcollection+xml +application/vnd.nokia.n-gage.ac+xml ac +application/vnd.nokia.n-gage.data ngdat +application/vnd.nokia.n-gage.symbian.install n-gage +application/vnd.nokia.ncd +application/vnd.nokia.pcd+wbxml +application/vnd.nokia.pcd+xml +application/vnd.nokia.radio-preset rpst +application/vnd.nokia.radio-presets rpss +application/vnd.novadigm.EDM edm +application/vnd.novadigm.EDX edx +application/vnd.novadigm.EXT ext +application/vnd.ntt-local.content-share +application/vnd.ntt-local.file-transfer +application/vnd.ntt-local.ogw_remote-access +application/vnd.ntt-local.sip-ta_remote +application/vnd.ntt-local.sip-ta_tcp_stream +application/vnd.oasis.opendocument.base odb +application/vnd.oasis.opendocument.chart odc +application/vnd.oasis.opendocument.chart-template otc +# application/vnd.oasis.opendocument.database obsoleted by application/vnd.oasis.opendocument.base +application/vnd.oasis.opendocument.formula odf +# otf: font/otf +application/vnd.oasis.opendocument.formula-template +application/vnd.oasis.opendocument.graphics odg +application/vnd.oasis.opendocument.graphics-template otg +application/vnd.oasis.opendocument.image odi +application/vnd.oasis.opendocument.image-template oti +application/vnd.oasis.opendocument.presentation odp +application/vnd.oasis.opendocument.presentation-template otp +application/vnd.oasis.opendocument.spreadsheet ods +application/vnd.oasis.opendocument.spreadsheet-template ots +application/vnd.oasis.opendocument.text odt +application/vnd.oasis.opendocument.text-master odm +application/vnd.oasis.opendocument.text-master-template otm +application/vnd.oasis.opendocument.text-template ott +application/vnd.oasis.opendocument.text-web oth +application/vnd.obn +application/vnd.ocf+cbor +application/vnd.oci.image.manifest.v1+json +application/vnd.oftn.l10n+json +application/vnd.oipf.contentaccessdownload+xml +application/vnd.oipf.contentaccessstreaming+xml +application/vnd.oipf.cspg-hexbinary +application/vnd.oipf.dae.svg+xml +application/vnd.oipf.dae.xhtml+xml +application/vnd.oipf.mippvcontrolmessage+xml +application/vnd.oipf.pae.gem +application/vnd.oipf.spdiscovery+xml +application/vnd.oipf.spdlist+xml +application/vnd.oipf.ueprofile+xml +application/vnd.oipf.userprofile+xml +application/vnd.olpc-sugar xo +application/vnd.oma.bcast.associated-procedure-parameter+xml +application/vnd.oma.bcast.drm-trigger+xml +application/vnd.oma.bcast.imd+xml +application/vnd.oma.bcast.ltkm +application/vnd.oma.bcast.notification+xml +application/vnd.oma.bcast.provisioningtrigger +application/vnd.oma.bcast.sgboot +application/vnd.oma.bcast.sgdd+xml +application/vnd.oma.bcast.sgdu +application/vnd.oma.bcast.simple-symbol-container +application/vnd.oma.bcast.smartcard-trigger+xml +application/vnd.oma.bcast.sprov+xml +application/vnd.oma.bcast.stkm +application/vnd.oma.cab-address-book+xml +application/vnd.oma.cab-feature-handler+xml +application/vnd.oma.cab-pcc+xml +application/vnd.oma.cab-subs-invite+xml +application/vnd.oma.cab-user-prefs+xml +application/vnd.oma.dcd +application/vnd.oma.dcdc +application/vnd.oma.dd2+xml dd2 +application/vnd.oma.drm.risd+xml +application/vnd.oma.group-usage-list+xml +application/vnd.oma.lwm2m+cbor +application/vnd.oma.lwm2m+json +application/vnd.oma.lwm2m+tlv +application/vnd.oma.pal+xml +application/vnd.oma.poc.detailed-progress-report+xml +application/vnd.oma.poc.final-report+xml +application/vnd.oma.poc.groups+xml +application/vnd.oma.poc.invocation-descriptor+xml +application/vnd.oma.poc.optimized-progress-report+xml +application/vnd.oma.push +application/vnd.oma.scidm.messages+xml +application/vnd.oma.xcap-directory+xml +application/vnd.oma-scws-config +application/vnd.oma-scws-http-request +application/vnd.oma-scws-http-response +application/vnd.omads-email+xml +application/vnd.omads-file+xml +application/vnd.omads-folder+xml +application/vnd.omaloc-supl-init +application/vnd.onepager tam +application/vnd.onepagertamp tamp +application/vnd.onepagertamx tamx +application/vnd.onepagertat tat +application/vnd.onepagertatp tatp +application/vnd.onepagertatx tatx +application/vnd.onvif.metadata +application/vnd.openblox.game+xml obgx +application/vnd.openblox.game-binary obg +application/vnd.openeye.oeb oeb +application/vnd.openofficeorg.extension oxt +application/vnd.openstreetmap.data+xml osm +application/vnd.opentimestamps.ots +application/vnd.openxmlformats-officedocument.custom-properties+xml +application/vnd.openxmlformats-officedocument.customXmlProperties+xml +application/vnd.openxmlformats-officedocument.drawing+xml +application/vnd.openxmlformats-officedocument.drawingml.chart+xml +application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml +application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml +application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml +application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml +application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml +application/vnd.openxmlformats-officedocument.extended-properties+xml +application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml +application/vnd.openxmlformats-officedocument.presentationml.comments+xml +application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml +application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml +application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml +application/vnd.openxmlformats-officedocument.presentationml.presProps+xml +application/vnd.openxmlformats-officedocument.presentationml.presentation pptx +application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml +application/vnd.openxmlformats-officedocument.presentationml.slide sldx +application/vnd.openxmlformats-officedocument.presentationml.slide+xml +application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml +application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml +application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml +application/vnd.openxmlformats-officedocument.presentationml.slideshow ppsx +application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml +application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml +application/vnd.openxmlformats-officedocument.presentationml.tags+xml +application/vnd.openxmlformats-officedocument.presentationml.template potx +application/vnd.openxmlformats-officedocument.presentationml.template.main+xml +application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet xlsx +application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.template xltx +application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml +application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml +application/vnd.openxmlformats-officedocument.theme+xml +application/vnd.openxmlformats-officedocument.themeOverride+xml +application/vnd.openxmlformats-officedocument.vmlDrawing +application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document docx +application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.template dotx +application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml +application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml +application/vnd.openxmlformats-package.core-properties+xml +application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml +application/vnd.openxmlformats-package.relationships+xml +application/vnd.oracle.resource+json +application/vnd.orange.indata +application/vnd.osa.netdeploy ndc +application/vnd.osgeo.mapguide.package mgp +application/vnd.osgi.bundle +application/vnd.osgi.dp dp +application/vnd.osgi.subsystem esa +application/vnd.otps.ct-kip+xml +application/vnd.oxli.countgraph oxlicg +application/vnd.pagerduty+json +application/vnd.palm prc pdb pqa oprc +application/vnd.panoply plp +application/vnd.paos.xml +application/vnd.paos+xml +application/vnd.patentdive dive +application/vnd.patientecommsdoc +application/vnd.pawaafile paw +application/vnd.pcos +application/vnd.pg.format str +application/vnd.pg.osasli ei6 +application/vnd.piaccess.application-licence pil +application/vnd.picsel efif +application/vnd.pmi.widget wg +application/vnd.poc.group-advertisement+xml +application/vnd.pocketlearn plf +application/vnd.powerbuilder6 pbd +application/vnd.powerbuilder6-s +application/vnd.powerbuilder7 +application/vnd.powerbuilder7-s +application/vnd.powerbuilder75 +application/vnd.powerbuilder75-s +application/vnd.preminet preminet +application/vnd.previewsystems.box box vbox +application/vnd.proteus.magazine mgz +application/vnd.psfs psfs +application/vnd.pt.mundusmundi +application/vnd.publishare-delta-tree qps +# pti: image/prs.pti +application/vnd.pvi.ptid1 ptid +application/vnd.pwg-multiplexed +application/vnd.pwg-xhtml-print+xml +application/vnd.qualcomm.brew-app-res bar +application/vnd.quarantainenet +application/vnd.Quark.QuarkXPress qxd qxt qwd qwt qxl qxb +application/vnd.quobject-quoxdocument quox quiz +application/vnd.radisys.moml+xml +application/vnd.radisys.msml-audit-conf+xml +application/vnd.radisys.msml-audit-conn+xml +application/vnd.radisys.msml-audit-dialog+xml +application/vnd.radisys.msml-audit-stream+xml +application/vnd.radisys.msml-audit+xml +application/vnd.radisys.msml-conf+xml +application/vnd.radisys.msml-dialog-base+xml +application/vnd.radisys.msml-dialog-fax-detect+xml +application/vnd.radisys.msml-dialog-fax-sendrecv+xml +application/vnd.radisys.msml-dialog-group+xml +application/vnd.radisys.msml-dialog-speech+xml +application/vnd.radisys.msml-dialog-transform+xml +application/vnd.radisys.msml-dialog+xml +application/vnd.radisys.msml+xml +application/vnd.rainstor.data tree +application/vnd.rapid +application/vnd.rar rar +application/vnd.realvnc.bed bed +application/vnd.recordare.musicxml mxl +application/vnd.recordare.musicxml+xml +application/vnd.RenLearn.rlprint +application/vnd.resilient.logic rlm reload +application/vnd.restful+json +application/vnd.rig.cryptonote cryptonote +application/vnd.route66.link66+xml link66 +# gbr: application/rpki-ghostbusters +application/vnd.rs-274x +application/vnd.ruckus.download +application/vnd.s3sms +application/vnd.sailingtracker.track st +application/vnd.sar SAR +application/vnd.sbm.cid +application/vnd.sbm.mid2 +application/vnd.scribus scd sla slaz +application/vnd.sealed.3df s3df +application/vnd.sealed.csf scsf +application/vnd.sealed.doc sdoc sdo s1w +application/vnd.sealed.eml seml sem +application/vnd.sealed.mht smht smh +application/vnd.sealed.net +# spp: application/scvp-vp-response +application/vnd.sealed.ppt sppt s1p +application/vnd.sealed.tiff stif +application/vnd.sealed.xls sxls sxl s1e +# stm: audio/x-stm +application/vnd.sealedmedia.softseal.html stml s1h +application/vnd.sealedmedia.softseal.pdf spdf spd s1a +application/vnd.seemail see +# json: application/json +application/vnd.seis+json +application/vnd.sema sema +application/vnd.semd semd +application/vnd.semf semf +application/vnd.shade-save-file ssv +application/vnd.shana.informed.formdata ifm +application/vnd.shana.informed.formtemplate itp +application/vnd.shana.informed.interchange iif +application/vnd.shana.informed.package ipk +application/vnd.shootproof+json +application/vnd.shopkick+json +application/vnd.shp shp +application/vnd.shx shx +application/vnd.sigrok.session sr +application/vnd.SimTech-MindMapper twd twds +application/vnd.siren+json +application/vnd.smaf mmf +application/vnd.smart.notebook notebook +application/vnd.smart.teacher teacher +application/vnd.smintio.portals.archive sipa +application/vnd.snesdev-page-table ptrom pt +application/vnd.software602.filler.form+xml fo +application/vnd.software602.filler.form-xml-zip zfo +application/vnd.solent.sdkm+xml sdkm sdkd +application/vnd.spotfire.dxp dxp +application/vnd.spotfire.sfs sfs +# db: too generic +application/vnd.sqlite3 sqlite sqlite3 +application/vnd.sss-cod +application/vnd.sss-dtf +application/vnd.sss-ntf +application/vnd.stepmania.package smzip +application/vnd.stepmania.stepchart sm +application/vnd.street-stream +application/vnd.sun.wadl+xml wadl +application/vnd.sus-calendar sus susp +application/vnd.svd +application/vnd.swiftview-ics +application/vnd.sybyl.mol2 ml2 mol2 sy2 +application/vnd.sycle+xml scl +application/vnd.syft+json syft.json +application/vnd.syncml+xml xsm +application/vnd.syncml.dm+wbxml bdm +application/vnd.syncml.dm+xml xdm +application/vnd.syncml.dm.notification +application/vnd.syncml.dmddf+wbxml +application/vnd.syncml.dmddf+xml ddf +application/vnd.syncml.dmtnds+wbxml +application/vnd.syncml.dmtnds+xml +application/vnd.syncml.ds.notification +application/vnd.tableschema+json +application/vnd.tao.intent-module-archive tao +application/vnd.tcpdump.pcap pcap cap dmp +application/vnd.theqvd qvd +application/vnd.think-cell.ppttc+json ppttc +application/vnd.tmd.mediaflex.api+xml +application/vnd.tml vfr viaframe +application/vnd.tmobile-livetv tmo +application/vnd.tri.onesource +application/vnd.trid.tpt tpt +application/vnd.triscape.mxs mxs +application/vnd.trueapp tra +application/vnd.truedoc +# cab: application/vnd.ms-cab-compressed +application/vnd.ubisoft.webplayer +application/vnd.ufdl ufdl ufd frm +application/vnd.uiq.theme utz +application/vnd.umajin umj +application/vnd.unity unityweb +application/vnd.uoml+xml uoml uo +application/vnd.uplanet.alert +application/vnd.uplanet.alert-wbxml +application/vnd.uplanet.bearer-choice +application/vnd.uplanet.bearer-choice-wbxml +application/vnd.uplanet.cacheop +application/vnd.uplanet.cacheop-wbxml +application/vnd.uplanet.channel +application/vnd.uplanet.channel-wbxml +application/vnd.uplanet.list +application/vnd.uplanet.list-wbxml +application/vnd.uplanet.listcmd +application/vnd.uplanet.listcmd-wbxml +application/vnd.uplanet.signal +application/vnd.uri-map urim urimap +application/vnd.valve.source.material vmt +application/vnd.vcx vcx +# sxi: application/vnd.sun.xml.impress +application/vnd.vd-study mxi study-inter model-inter +# mcd: application/vnd.mcd +application/vnd.vectorworks vwx +application/vnd.vel+json +application/vnd.verimatrix.vcas +application/vnd.veritone.aion+json aion vtnstd +application/vnd.veryant.thin istc isws +application/vnd.ves.encrypted VES +application/vnd.vidsoft.vidconference vsc +application/vnd.visio vsd vst vsw vss +application/vnd.visionary vis +# vsc: application/vnd.vidsoft.vidconference +application/vnd.vividence.scriptfile +application/vnd.vsf vsf +application/vnd.wap.sic sic +application/vnd.wap.slc slc +application/vnd.wap.wbxml wbxml +application/vnd.wap.wmlc wmlc +application/vnd.wap.wmlscriptc wmlsc +application/vnd.wasmflow.wafl wafl +application/vnd.webturbo wtb +application/vnd.wfa.dpp +application/vnd.wfa.p2p p2p +application/vnd.wfa.wsc wsc +application/vnd.windows.devicepairing +application/vnd.wmc wmc +application/vnd.wmf.bootstrap +# nb: application/mathematica for now +application/vnd.wolfram.mathematica +application/vnd.wolfram.mathematica.package m +application/vnd.wolfram.player nbp +application/vnd.wordlift +application/vnd.wordperfect wpd +application/vnd.wqd wqd +application/vnd.wrq-hp3000-labelled +application/vnd.wt.stf stf +application/vnd.wv.csp+xml +application/vnd.wv.csp+wbxml wv +application/vnd.wv.ssp+xml +application/vnd.xacml+json +application/vnd.xara xar +application/vnd.xfdl xfdl xfd +application/vnd.xfdl.webform +application/vnd.xmi+xml +application/vnd.xmpie.cpkg cpkg +application/vnd.xmpie.dpkg dpkg +# dpkg: application/vnd.xmpie.dpkg +application/vnd.xmpie.plan +application/vnd.xmpie.ppkg ppkg +application/vnd.xmpie.xlim xlim +application/vnd.yamaha.hv-dic hvd +application/vnd.yamaha.hv-script hvs +application/vnd.yamaha.hv-voice hvp +application/vnd.yamaha.openscoreformat osf +application/vnd.yamaha.openscoreformat.osfpvg+xml +application/vnd.yamaha.remote-setup +application/vnd.yamaha.smaf-audio saf +application/vnd.yamaha.smaf-phrase spf +application/vnd.yamaha.through-ngn +application/vnd.yamaha.tunnel-udpencap +application/vnd.yaoweme yme +application/vnd.yellowriver-custom-menu cmp +# application/vnd.youtube.yt OBSOLETED in favor of video/vnd.youtube.yt +application/vnd.zul zir zirz +application/vnd.zzazz.deck+xml zaz +application/voicexml+xml vxml +application/voucher-cms+json vcj +application/vq-rtcpxr +application/wasm wasm +application/vq-rtcp-xr +application/watcherinfo+xml wif +application/webpush-options+json +application/whoispp-query +application/whoispp-response +application/widget wgt +application/wita +application/wordperfect5.1 +application/wsdl+xml wsdl +application/wspolicy+xml wspolicy +# yes, this *is* IANA registered despite of x- +application/x-pki-message +application/x-www-form-urlencoded +application/x-x509-ca-cert +application/x-x509-ca-ra-cert +application/x-x509-next-ca-cert +application/x400-bp +application/xacml+xml +application/xcap-att+xml xav +application/xcap-caps+xml xca +application/xcap-diff+xml xdf +application/xcap-el+xml xel +application/xcap-error+xml xer +application/xcap-ns+xml xns +application/xcon-conference-info-diff+xml +application/xcon-conference-info+xml +application/xenc+xml +application/xfdf xfdf +application/xhtml+xml xhtml xhtm xht +application/xliff+xml xlf +# xml, xsd, rng: text/xml +application/xml +# mod: audio/x-mod +application/xml-dtd dtd +# ent: text/xml-external-parsed-entity +application/xml-external-parsed-entity +application/xml-patch+xml +application/xmpp+xml +application/xop+xml xop +application/xslt+xml xsl xslt +application/xv+xml mxml xhvml xvml xvm +application/yang yang +application/yang-data+json +application/yang-data+xml +application/yang-data+cbor +application/yang-patch+json +application/yang-patch+xml +application/yin+xml yin +application/zip zip +application/zlib +application/zstd zst +audio/1d-interleaved-parityfec +audio/32kadpcm 726 +# 3gp, 3gpp: video/3gpp +audio/3gpp +# 3g2, 3gpp2: video/3gpp2 +audio/3gpp2 +# loas: audio/usac +audio/aac adts aac ass +audio/ac3 ac3 +audio/AMR amr +audio/AMR-WB awb +audio/amr-wb+ +audio/aptx +audio/asc acn +# aa3, omg: audio/ATRAC3 +audio/ATRAC-ADVANCED-LOSSLESS aal +# aa3, omg: audio/ATRAC3 +audio/ATRAC-X atx +audio/ATRAC3 at3 aa3 omg +audio/basic au snd +audio/BV16 +audio/BV32 +audio/clearmode +audio/CN +audio/DAT12 +audio/dls dls +audio/dsr-es201108 +audio/dsr-es202050 +audio/dsr-es202211 +audio/dsr-es202212 +audio/DV +audio/DVI4 +audio/eac3 +audio/encaprtp +audio/EVRC evc +# qcp: audio/qcelp +audio/EVRC-QCP +audio/EVRC0 +audio/EVRC1 +audio/EVRCB evb +audio/EVRCB0 +audio/EVRCB1 +audio/EVRCNW enw +audio/EVRCNW0 +audio/EVRCNW1 +audio/EVRCWB evw +audio/EVRCWB0 +audio/EVRCWB1 +audio/EVS +audio/example +audio/flexfec +audio/fwdred +audio/G711-0 +audio/G719 +audio/G722 +audio/G7221 +audio/G723 +audio/G726-16 +audio/G726-24 +audio/G726-32 +audio/G726-40 +audio/G728 +audio/G729 +audio/G7291 +audio/G729D +audio/G729E +audio/GSM +audio/GSM-EFR +audio/GSM-HR-08 +audio/iLBC lbc +audio/ip-mr_v2.5 +# wav: audio/x-wav +audio/L16 l16 +audio/L20 +audio/L24 +audio/L8 +audio/LPC +audio/MELP +audio/MELP600 +audio/MELP1200 +audio/MELP2400 +audio/mhas mhas +audio/mobile-xmf mxmf +# mp4, mpg4: video/mp4, see RFC 4337 +audio/mp4 m4a +audio/MP4A-LATM +audio/MPA +audio/mpa-robust +audio/mpeg mp3 mpga mp1 mp2 +audio/mpeg4-generic +audio/ogg oga ogg opus spx +audio/opus +audio/parityfec +audio/PCMA +audio/PCMA-WB +audio/PCMU +audio/PCMU-WB +audio/prs.sid sid psid +audio/QCELP qcp +audio/raptorfec +audio/RED +audio/rtp-enc-aescm128 +audio/rtp-midi +audio/rtploopback +audio/rtx +audio/scip +audio/SMV smv +# qcp: audio/qcelp, see RFC 3625 +audio/SMV-QCP +audio/sofa sofa +audio/SMV0 +# mid: audio/midi +audio/sp-midi +audio/speex +audio/t140c +audio/t38 +audio/telephone-event +audio/TETRA_ACELP +audio/TETRA_ACELP_BB +audio/tone +audio/TSVCIS +audio/UEMCLIP +audio/ulpfec +audio/usac loas xhe +audio/VDVI +audio/VMR-WB +audio/vnd.3gpp.iufp +audio/vnd.4SB +audio/vnd.audiokoz koz +audio/vnd.CELP +audio/vnd.cisco.nse +audio/vnd.cmles.radio-events +audio/vnd.cns.anp1 +audio/vnd.cns.inf1 +audio/vnd.dece.audio uva uvva +audio/vnd.digital-winds eol +audio/vnd.dlna.adts +audio/vnd.dolby.heaac.1 +audio/vnd.dolby.heaac.2 +audio/vnd.dolby.mlp mlp +audio/vnd.dolby.mps +audio/vnd.dolby.pl2 +audio/vnd.dolby.pl2x +audio/vnd.dolby.pl2z +audio/vnd.dolby.pulse.1 +audio/vnd.dra +# wav: audio/x-wav, cpt: application/mac-compactpro +audio/vnd.dts dts +audio/vnd.dts.hd dtshd +audio/vnd.dts.uhd +# dvb: video/vnd.dvb.file +audio/vnd.dvb.file +audio/vnd.everad.plj plj +# rm: audio/x-pn-realaudio +audio/vnd.hns.audio +audio/vnd.lucent.voice lvp +audio/vnd.ms-playready.media.pya pya +# mxmf: audio/mobile-xmf +audio/vnd.nokia.mobile-xmf +audio/vnd.nortel.vbk vbk +audio/vnd.nuera.ecelp4800 ecelp4800 +audio/vnd.nuera.ecelp7470 ecelp7470 +audio/vnd.nuera.ecelp9600 ecelp9600 +audio/vnd.octel.sbc +audio/vnd.presonus.multitrack multitrack +# audio/vnd.qcelp deprecated in favour of audio/qcelp +audio/vnd.rhetorex.32kadpcm +audio/vnd.rip rip +audio/vnd.sealedmedia.softseal.mpeg smp3 smp s1m +audio/vnd.vmx.cvsd +audio/vorbis +audio/vorbis-config +font/collection ttc +font/otf otf +font/sfnt +font/ttf ttf +font/woff woff +font/woff2 woff2 +image/aces exr +image/apng +image/avci avci +image/avcs avcs +# heif: image/heif +# heifs: images/heif-sequence +image/avif avif hif +image/bmp bmp dib +image/cgm cgm +image/dicom-rle drle +image/dpx dpx +image/emf emf +image/example +image/fits fits fit fts +image/g3fax +image/heic heic +image/heic-sequence heics +image/heif heif +image/heif-sequence heifs +image/hej2k hej2 +image/hsj2 hsj2 +image/gif gif +image/ief ief +image/jls jls +image/jp2 jp2 jpg2 +image/jph jph +image/jphc jhc +image/jpeg jpg jpeg jpe jfif +image/jpm jpm jpgm +image/jpx jpx jpf +image/jxl jxl +image/jxr jxr +image/jxrA jxra +image/jxrS jxrs +image/jxs jxs +image/jxsc jxsc +image/jxsi jxsi +image/jxss jxss +image/ktx ktx +image/ktx2 ktx2 +image/naplps +image/png png +image/prs.btif btif btf +image/prs.pti pti +image/pwg-raster +image/svg+xml svg svgz +image/t38 t38 +image/tiff tiff tif +image/tiff-fx tfx +image/vnd.adobe.photoshop psd +image/vnd.airzip.accelerator.azv azv +image/vnd.cns.inf2 +image/vnd.dece.graphic uvi uvvi uvg uvvg +image/vnd.djvu djvu djv +# sub: text/vnd.dvb.subtitle +image/vnd.dvb.subtitle +image/vnd.dwg dwg +image/vnd.dxf dxf +image/vnd.fastbidsheet fbs +image/vnd.fpx fpx +image/vnd.fst fst +image/vnd.fujixerox.edmics-mmr mmr +image/vnd.fujixerox.edmics-rlc rlc +image/vnd.globalgraphics.pgb pgb +image/vnd.microsoft.icon ico +image/vnd.mix +image/vnd.mozilla.apng apng +image/vnd.ms-modi mdi +image/vnd.net-fpx +image/vnd.pco.b16 b16 +image/vnd.radiance hdr rgbe xyze +image/vnd.sealed.png spng spn s1n +image/vnd.sealedmedia.softseal.gif sgif sgi s1g +image/vnd.sealedmedia.softseal.jpg sjpg sjp s1j +image/vnd.svf +image/vnd.tencent.tap tap +image/vnd.valve.source.texture vtf +image/vnd.wap.wbmp wbmp +image/vnd.xiff xif +image/vnd.zbrush.pcx pcx +image/wmf wmf +message/bhttp +message/CPIM +message/delivery-status +message/disposition-notification +message/example +message/external-body +message/feedback-report +message/global u8msg +message/global-delivery-status u8dsn +message/global-disposition-notification u8mdn +message/global-headers u8hdr +message/http +# cl: application/simple-filter+xml +message/imdn+xml +message/mls +# message/news obsoleted by message/rfc822 +message/ohttp-req +message/ohttp-res +message/partial +message/rfc822 eml mail art +message/s-http +message/sip +message/sipfrag +message/tracking-status +message/vnd.si.simp +# wsc: application/vnd.wfa.wsc +message/vnd.wfa.wsc +# 3mf: application/vnd.ms-3mfdocument +model/3mf +model/e57 +model/example +model/gltf-binary glb +model/gltf+json gltf +model/JT jt +model/iges igs iges +model/mesh msh mesh silo +model/mtl mtl +model/obj obj +model/prc +model/step +model/step+xml stpx +model/step+zip +model/step-xml+zip stpxz +model/stl stl +model/u3d u3d +model/vnd.bary bary +model/vnd.cld cld +model/vnd.collada+xml dae +model/vnd.dwf dwf +# 3dml, 3dm: text/vnd.in3d.3dml +model/vnd.flatland.3dml +model/vnd.gdl gdl gsm win dor lmp rsm msm ism +model/vnd.gs-gdl +model/vnd.gtw gtw +model/vnd.moml+xml moml +model/vnd.mts mts +model/vnd.opengex ogex +model/vnd.parasolid.transmit.binary x_b xmt_bin +model/vnd.parasolid.transmit.text x_t xmt_txt +model/vnd.pytha.pyox pyo pyox +model/vnd.rosette.annotated-data-model +model/vnd.sap.vds vds +model/vnd.usda usda +model/vnd.usdz+zip usdz +model/vnd.valve.source.compiled-map bsp +model/vnd.vtu vtu +model/vrml wrl vrml +# x3db: model/x3d+xml +model/x3d+fastinfoset +# x3d: application/vnd.hzn-3d-crossword +model/x3d+xml x3db +model/x3d-vrml x3dv x3dvz +multipart/alternative +multipart/appledouble +multipart/byteranges +multipart/digest +multipart/encrypted +multipart/form-data +multipart/header-set +multipart/mixed +multipart/multilingual +multipart/parallel +multipart/related +multipart/report +multipart/signed +multipart/vnd.bint.med-plus bmed +multipart/voice-message vpm +multipart/x-mixed-replace +text/1d-interleaved-parityfec +text/cache-manifest appcache manifest +text/calendar ics ifb +text/cql CQL +text/cql-expression +text/cql-identifier +text/css css +text/csv csv +text/csv-schema csvs +text/directory +text/dns soa zone +text/encaprtp +text/fhirpath +# text/ecmascript obsoleted by application/ecmascript +text/enriched +text/example +text/flexfec +text/fwdred +text/gff3 gff3 +text/grammar-ref-list +text/hl7v2 +text/html html htm +text/javascript js mjs +text/jcr-cnd cnd +text/markdown markdown md +text/mizar miz +text/n3 n3 +text/parameters +text/parityfec +text/plain txt asc text pm el c h cc hh cxx hxx f90 conf log +text/provenance-notation provn +text/prs.fallenstein.rst rst +text/prs.lines.tag tag dsc +text/prs.prop.logic +text/raptorfec +text/RED +text/rfc822-headers +text/richtext rtx +# rtf: application/rtf +text/rtf +text/rtp-enc-aescm128 +text/rtploopback +text/rtx +text/SGML sgml sgm +text/shaclc shaclc shc +text/shex shex +text/spdx spdx +text/strings +text/t140 +text/tab-separated-values tsv +text/troff t tr roff +text/turtle ttl +text/ulpfec +text/uri-list uris uri +text/vcard vcf vcard +text/vnd.a a +text/vnd.abc abc +text/vnd.ascii-art ascii +# curl: application/vnd.curl +text/vnd.curl +text/vnd.debian.copyright copyright +text/vnd.DMClientScript dms +text/vnd.dvb.subtitle sub +text/vnd.esmertec.theme-descriptor jtd +text/vnd.exchangeable vfk +text/vnd.familysearch.gedcom ged +text/vnd.ficlab.flt flt +text/vnd.fly fly +text/vnd.fmi.flexstor flx +# gml: application/gml+xml +text/vnd.gml +text/vnd.graphviz gv dot +text/vnd.hans hans +text/vnd.hgl hgl +text/vnd.in3d.3dml 3dml 3dm +text/vnd.in3d.spot spot spo +text/vnd.IPTC.NewsML +text/vnd.IPTC.NITF +text/vnd.latex-z +text/vnd.motorola.reflex +text/vnd.ms-mediapackage mpf +text/vnd.net2phone.commcenter.command ccc +text/vnd.radisys.msml-basic-layout +text/vnd.senx.warpscript mc2 +text/vnd.si.uricatalogue uric +text/vnd.sun.j2me.app-descriptor jad +text/vnd.sosi sos +text/vnd.trolltech.linguist ts +text/vnd.wap.si si +text/vnd.wap.sl sl +text/vnd.wap.wml wml +text/vnd.wap.wmlscript wmls +text/vtt vtt +text/wgsl wgsl +text/xml xml xsd rng +text/xml-external-parsed-entity ent +video/1d-interleaved-parityfec +video/3gpp 3gp 3gpp +video/3gpp2 3g2 3gpp2 +video/3gpp-tt +video/AV1 +video/BMPEG +video/BT656 +video/CelB +video/DV +video/encaprtp +video/FFV1 +video/example +video/flexfec +video/H261 +video/H263 +video/H263-1998 +video/H263-2000 +video/H264 +video/H264-RCDO +video/H264-SVC +video/H265 +video/H266 +video/iso.segment m4s +video/JPEG +video/jpeg2000 +video/jxsv +video/mj2 mj2 mjp2 +video/MP1S +video/MP2P +video/MP2T +video/mp4 mp4 mpg4 m4v +video/MP4V-ES +video/mpeg mpeg mpg mpe m1v m2v +video/mpeg4-generic +video/MPV +video/nv +video/ogg ogv +video/parityfec +video/pointer +video/quicktime mov qt +video/raptorfec +video/raw +video/rtp-enc-aescm128 +video/rtploopback +video/rtx +video/scip +video/smpte291 +video/SMPTE292M +video/ulpfec +video/vc1 +video/vc2 +video/vnd.CCTV +video/vnd.dece.hd uvh uvvh +video/vnd.dece.mobile uvm uvvm +video/vnd.dece.mp4 uvu uvvu +video/vnd.dece.pd uvp uvvp +video/vnd.dece.sd uvs uvvs +video/vnd.dece.video uvv uvvv +video/vnd.directv.mpeg +video/vnd.directv.mpeg-tts +video/vnd.dlna.mpeg-tts +video/vnd.dvb.file dvb +video/vnd.fvt fvt +# rm: audio/x-pn-realaudio +video/vnd.hns.video +video/vnd.iptvforum.1dparityfec-1010 +video/vnd.iptvforum.1dparityfec-2005 +video/vnd.iptvforum.2dparityfec-1010 +video/vnd.iptvforum.2dparityfec-2005 +video/vnd.iptvforum.ttsavc +video/vnd.iptvforum.ttsmpeg2 +video/vnd.motorola.video +video/vnd.motorola.videop +video/vnd.mpegurl mxu m4u +video/vnd.ms-playready.media.pyv pyv +video/vnd.nokia.interleaved-multimedia nim +video/vnd.nokia.mp4vr +video/vnd.nokia.videovoip +# mp4: video/mp4 +video/vnd.objectvideo +video/vnd.radgamettools.bink bik bk2 +video/vnd.radgamettools.smacker smk +video/vnd.sealed.mpeg1 smpg s11 +# smpg: video/vnd.sealed.mpeg1 +video/vnd.sealed.mpeg4 s14 +video/vnd.sealed.swf sswf ssw +video/vnd.sealedmedia.softseal.mov smov smo s1q +# uvu, uvvu: video/vnd.dece.mp4 +video/vnd.uvvu.mp4 +video/vnd.youtube.yt yt +video/vnd.vivo viv +video/VP8 +video/VP9 + +# Non-IANA types + +application/mac-compactpro cpt +application/metalink+xml metalink +application/owl+xml owx +application/rss+xml rss +application/vnd.android.package-archive apk +application/vnd.oma.dd+xml dd +application/vnd.oma.drm.content dcf +# odf: application/vnd.oasis.opendocument.formula +application/vnd.oma.drm.dcf o4a o4v +application/vnd.oma.drm.message dm +application/vnd.oma.drm.rights+wbxml drc +application/vnd.oma.drm.rights+xml dr +application/vnd.sun.xml.calc sxc +application/vnd.sun.xml.calc.template stc +application/vnd.sun.xml.draw sxd +application/vnd.sun.xml.draw.template std +application/vnd.sun.xml.impress sxi +application/vnd.sun.xml.impress.template sti +application/vnd.sun.xml.math sxm +application/vnd.sun.xml.writer sxw +application/vnd.sun.xml.writer.global sxg +application/vnd.sun.xml.writer.template stw +application/vnd.symbian.install sis +application/vnd.wap.mms-message mms +application/x-annodex anx +application/x-bcpio bcpio +application/x-bittorrent torrent +application/x-bzip2 bz2 +application/x-cdlink vcd +application/x-chrome-extension crx +application/x-cpio cpio +application/x-csh csh +application/x-director dcr dir dxr +application/x-dvi dvi +application/x-futuresplash spl +application/x-gtar gtar +application/x-hdf hdf +application/x-java-jnlp-file jnlp +application/x-java-pack200 pack +application/x-killustrator kil +application/x-latex latex +application/x-netcdf nc cdf +application/x-perl pl +application/x-rpm rpm +application/x-sh sh +application/x-shar shar +application/x-stuffit sit +application/x-sv4cpio sv4cpio +application/x-sv4crc sv4crc +application/x-tar tar +application/x-tcl tcl +application/x-tex tex +application/x-texinfo texinfo texi +application/x-troff-man man 1 2 3 4 5 6 7 8 +application/x-troff-me me +application/x-troff-ms ms +application/x-ustar ustar +application/x-wais-source src +application/x-xpinstall xpi +application/x-xspf+xml xspf +application/x-xz xz +audio/midi mid midi kar +audio/x-aiff aif aiff aifc +audio/x-annodex axa +audio/x-flac flac +audio/x-matroska mka +audio/x-mod mod ult uni m15 mtm 669 med +audio/x-mpegurl m3u +audio/x-ms-wax wax +audio/x-ms-wma wma +audio/x-pn-realaudio ram rm +audio/x-realaudio ra +audio/x-s3m s3m +audio/x-stm stm +audio/x-wav wav +chemical/x-xyz xyz +image/webp webp +image/x-cmu-raster ras +image/x-portable-anymap pnm +image/x-portable-bitmap pbm +image/x-portable-graymap pgm +image/x-portable-pixmap ppm +image/x-rgb rgb +image/x-targa tga +image/x-xbitmap xbm +image/x-xpixmap xpm +image/x-xwindowdump xwd +text/html-sandboxed sandboxed +text/x-pod pod +text/x-setext etx +video/webm webm +video/x-annodex axv +video/x-flv flv +video/x-javafx fxm +video/x-matroska mkv +video/x-matroska-3d mk3d +video/x-ms-asf asx +video/x-ms-wm wm +video/x-ms-wmv wmv +video/x-ms-wmx wmx +video/x-ms-wvx wvx +video/x-msvideo avi +video/x-sgi-movie movie +x-conference/x-cooltalk ice +x-epoc/x-sisx-app sisx