mimetype.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # -*- coding: utf-8 -*-
  2. from __future__ import absolute_import, unicode_literals
  3. import logging
  4. import mimetypes
  5. import kitchen.text.converters as ktc
  6. import six
  7. import pagure.lib.encoding_utils
  8. _log = logging.getLogger(__name__)
  9. def guess_type(filename, data):
  10. """
  11. Guess the type of a file based on its filename and data.
  12. Return value is a tuple (type, encoding) where type or encoding is None
  13. if it can't be guessed.
  14. :param filename: file name string
  15. :param data: file data string
  16. """
  17. mimetype = None
  18. encoding = None
  19. if filename:
  20. mimetype, encoding = mimetypes.guess_type(filename)
  21. if data:
  22. if not mimetype:
  23. if not isinstance(data, six.text_type) and b"\0" in data:
  24. mimetype = "application/octet-stream"
  25. else:
  26. mimetype = "text/plain"
  27. if mimetype.startswith("text/") and not encoding:
  28. try:
  29. encoding = pagure.lib.encoding_utils.guess_encoding(
  30. ktc.to_bytes(data)
  31. )
  32. except pagure.exceptions.PagureException: # pragma: no cover
  33. # We cannot decode the file, so bail but warn the admins
  34. _log.exception("File could not be decoded")
  35. return mimetype, encoding
  36. def get_type_headers(filename, data):
  37. """
  38. Get the HTTP headers used for downloading or previewing the file.
  39. If the file is html, it will return headers which make browser start
  40. downloading.
  41. :param filename: file name string
  42. :param data: file data string
  43. """
  44. mimetype, encoding = guess_type(filename, data)
  45. if not mimetype:
  46. return None
  47. headers = {str("X-Content-Type-Options"): "nosniff"}
  48. if "html" in mimetype or "javascript" in mimetype or "svg" in mimetype:
  49. mimetype = "application/octet-stream"
  50. headers[str("Content-Disposition")] = "attachment"
  51. if encoding:
  52. mimetype += "; charset={encoding}".format(encoding=encoding)
  53. headers[str("Content-Type")] = mimetype
  54. return headers