aboutsummaryrefslogtreecommitdiffstats
path: root/mitmproxy/contentviews
diff options
context:
space:
mode:
authorSachin Kelkar <sachinkel19@gmail.com>2017-01-30 22:50:35 +0530
committerSachin Kelkar <sachinkel19@gmail.com>2017-02-03 14:12:54 +0530
commit6202958048dd73af55b55e879317d583851fc2e3 (patch)
treebec7ce4def4b7b82f20022ceace230e476984f4e /mitmproxy/contentviews
parent79aa99427550e738007e8b87d41e5c097cd06c46 (diff)
downloadmitmproxy-6202958048dd73af55b55e879317d583851fc2e3.tar.gz
mitmproxy-6202958048dd73af55b55e879317d583851fc2e3.tar.bz2
mitmproxy-6202958048dd73af55b55e879317d583851fc2e3.zip
Add png parser
Diffstat (limited to 'mitmproxy/contentviews')
-rw-r--r--mitmproxy/contentviews/__init__.py5
-rw-r--r--mitmproxy/contentviews/image/__init__.py0
-rw-r--r--mitmproxy/contentviews/image/image_parser.py34
-rw-r--r--mitmproxy/contentviews/image/pillow.py (renamed from mitmproxy/contentviews/image.py)12
-rw-r--r--mitmproxy/contentviews/image/png.py257
5 files changed, 304 insertions, 4 deletions
diff --git a/mitmproxy/contentviews/__init__.py b/mitmproxy/contentviews/__init__.py
index 357172e3..b28f9d8f 100644
--- a/mitmproxy/contentviews/__init__.py
+++ b/mitmproxy/contentviews/__init__.py
@@ -23,8 +23,9 @@ from mitmproxy.net import http
from mitmproxy.utils import strutils
from . import (
auto, raw, hex, json, xml_html, html_outline, wbxml, javascript, css,
- urlencoded, multipart, image, query, protobuf
+ urlencoded, multipart, query, protobuf
)
+from .image import pillow
from .base import View, VIEW_CUTOFF, KEY_MAX, format_text, format_dict
views = [] # type: List[View]
@@ -170,7 +171,7 @@ add(javascript.ViewJavaScript())
add(css.ViewCSS())
add(urlencoded.ViewURLEncoded())
add(multipart.ViewMultipart())
-add(image.ViewImage())
+add(pillow.ViewImage())
add(query.ViewQuery())
if protobuf.ViewProtobuf.is_available():
diff --git a/mitmproxy/contentviews/image/__init__.py b/mitmproxy/contentviews/image/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/mitmproxy/contentviews/image/__init__.py
diff --git a/mitmproxy/contentviews/image/image_parser.py b/mitmproxy/contentviews/image/image_parser.py
new file mode 100644
index 00000000..8e5762c9
--- /dev/null
+++ b/mitmproxy/contentviews/image/image_parser.py
@@ -0,0 +1,34 @@
+from kaitaistruct import KaitaiStream
+
+from . import png
+
+def get_png(data):
+ img = png.Png(KaitaiStream(data))
+ parts = {'format': 'Portable network graphics'}
+ f = 'PNG'
+ width = img.ihdr.width
+ height = img.ihdr.height
+ parts["width"] = width
+ parts["height"] = height
+ for i in range(0, len(img.chunks)):
+ chunk = img.chunks[i]
+ if chunk.type == 'gAMA':
+ gamma = chunk.gamma_int / 100000
+ parts['gamma'] = gamma
+ elif chunk.type == 'pHYs':
+ aspectx = chunk.pixels_per_unit_x
+ aspecty = chunk.pixels_per_unit_y
+ parts["aspectx"] = aspectx
+ parts["aspecty"] = aspecty
+ return f, parts
+
+def format_contentviews(parts):
+ ret = []
+ ret.append(tuple(['Format', parts["format"]]))
+ if "width" in parts:
+ ret.append(tuple(['Size', str(parts["width"]) + " x " + str(parts["height"]) + " px"]))
+ if "aspectx" in parts:
+ ret.append(tuple(['aspect', '(' + str(parts["aspectx"]) + ', ' + str(parts["aspecty"]) + ')']))
+ if "gamma" in parts:
+ ret.append(tuple(['gamma', str(parts["gamma"])]))
+ return ret
diff --git a/mitmproxy/contentviews/image.py b/mitmproxy/contentviews/image/pillow.py
index 57b1fffb..c48d665a 100644
--- a/mitmproxy/contentviews/image.py
+++ b/mitmproxy/contentviews/image/pillow.py
@@ -1,10 +1,13 @@
-import io
+import io, imghdr
from PIL import ExifTags
from PIL import Image
from mitmproxy.types import multidict
-from . import base
+from . import image_parser
+
+from mitmproxy.contentviews import base
+from kaitaistruct import KaitaiStream
class ViewImage(base.View):
@@ -19,6 +22,11 @@ class ViewImage(base.View):
]
def __call__(self, data, **metadata):
+ if imghdr.what('', h=data) == 'png':
+ f, parts = image_parser.get_png(io.BytesIO(data))
+ parts = image_parser.format_contentviews(parts)
+ fmt = base.format_dict(multidict.MultiDict(parts))
+ return "%s image" % f, fmt
try:
img = Image.open(io.BytesIO(data))
except IOError:
diff --git a/mitmproxy/contentviews/image/png.py b/mitmproxy/contentviews/image/png.py
new file mode 100644
index 00000000..5996e3ce
--- /dev/null
+++ b/mitmproxy/contentviews/image/png.py
@@ -0,0 +1,257 @@
+# This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild
+# The source was png.ksy from here - https://github.com/kaitai-io/kaitai_struct_formats/tree/master/image
+
+import array
+import struct
+import zlib
+from enum import Enum
+
+from kaitaistruct import KaitaiStruct, KaitaiStream, BytesIO
+
+
+class Png(KaitaiStruct):
+
+ class ColorType(Enum):
+ greyscale = 0
+ truecolor = 2
+ indexed = 3
+ greyscale_alpha = 4
+ truecolor_alpha = 6
+
+ class PhysUnit(Enum):
+ unknown = 0
+ meter = 1
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.magic = self._io.ensure_fixed_contents(8, struct.pack('8b', -119, 80, 78, 71, 13, 10, 26, 10))
+ self.ihdr_len = self._io.ensure_fixed_contents(4, struct.pack('4b', 0, 0, 0, 13))
+ self.ihdr_type = self._io.ensure_fixed_contents(4, struct.pack('4b', 73, 72, 68, 82))
+ self.ihdr = self._root.IhdrChunk(self._io, self, self._root)
+ self.ihdr_crc = self._io.read_bytes(4)
+ self.chunks = []
+ while not self._io.is_eof():
+ self.chunks.append(self._root.Chunk(self._io, self, self._root))
+
+
+ class Rgb(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.r = self._io.read_u1()
+ self.g = self._io.read_u1()
+ self.b = self._io.read_u1()
+
+
+ class Chunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.len = self._io.read_u4be()
+ self.type = self._io.read_str_byte_limit(4, "UTF-8")
+ _on = self.type
+ if _on == u"gAMA":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.GamaChunk(io, self, self._root)
+ elif _on == u"tIME":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.TimeChunk(io, self, self._root)
+ elif _on == u"PLTE":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.PlteChunk(io, self, self._root)
+ elif _on == u"bKGD":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.BkgdChunk(io, self, self._root)
+ elif _on == u"pHYs":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.PhysChunk(io, self, self._root)
+ elif _on == u"tEXt":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.TextChunk(io, self, self._root)
+ elif _on == u"cHRM":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.ChrmChunk(io, self, self._root)
+ elif _on == u"sRGB":
+ self._raw_body = self._io.read_bytes(self.len)
+ io = KaitaiStream(BytesIO(self._raw_body))
+ self.body = self._root.SrgbChunk(io, self, self._root)
+ else:
+ self.body = self._io.read_bytes(self.len)
+ self.crc = self._io.read_bytes(4)
+
+
+ class BkgdIndexed(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.palette_index = self._io.read_u1()
+
+
+ class Point(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.x_int = self._io.read_u4be()
+ self.y_int = self._io.read_u4be()
+
+ @property
+ def x(self):
+ if hasattr(self, '_m_x'):
+ return self._m_x
+
+ self._m_x = (self.x_int / 100000.0)
+ return self._m_x
+
+ @property
+ def y(self):
+ if hasattr(self, '_m_y'):
+ return self._m_y
+
+ self._m_y = (self.y_int / 100000.0)
+ return self._m_y
+
+
+ class BkgdGreyscale(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.value = self._io.read_u2be()
+
+
+ class ChrmChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.white_point = self._root.Point(self._io, self, self._root)
+ self.red = self._root.Point(self._io, self, self._root)
+ self.green = self._root.Point(self._io, self, self._root)
+ self.blue = self._root.Point(self._io, self, self._root)
+
+
+ class IhdrChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.width = self._io.read_u4be()
+ self.height = self._io.read_u4be()
+ self.bit_depth = self._io.read_u1()
+ self.color_type = self._root.ColorType(self._io.read_u1())
+ self.compression_method = self._io.read_u1()
+ self.filter_method = self._io.read_u1()
+ self.interlace_method = self._io.read_u1()
+
+
+ class PlteChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.entries = []
+ while not self._io.is_eof():
+ self.entries.append(self._root.Rgb(self._io, self, self._root))
+
+
+
+ class SrgbChunk(KaitaiStruct):
+
+ class Intent(Enum):
+ perceptual = 0
+ relative_colorimetric = 1
+ saturation = 2
+ absolute_colorimetric = 3
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.render_intent = self._root.Intent(self._io.read_u1())
+
+
+ class BkgdTruecolor(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.red = self._io.read_u2be()
+ self.green = self._io.read_u2be()
+ self.blue = self._io.read_u2be()
+
+
+ class GamaChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.gamma_int = self._io.read_u4be()
+
+ @property
+ def gamma_ratio(self):
+ if hasattr(self, '_m_gamma_ratio'):
+ return self._m_gamma_ratio
+
+ self._m_gamma_ratio = (100000.0 / self.gamma_int)
+ return self._m_gamma_ratio
+
+
+ class BkgdChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ _on = self._root.ihdr.color_type
+ if _on == self._root.ColorType.greyscale_alpha:
+ self.bkgd = self._root.BkgdGreyscale(self._io, self, self._root)
+ elif _on == self._root.ColorType.indexed:
+ self.bkgd = self._root.BkgdIndexed(self._io, self, self._root)
+ elif _on == self._root.ColorType.greyscale:
+ self.bkgd = self._root.BkgdGreyscale(self._io, self, self._root)
+ elif _on == self._root.ColorType.truecolor_alpha:
+ self.bkgd = self._root.BkgdTruecolor(self._io, self, self._root)
+ elif _on == self._root.ColorType.truecolor:
+ self.bkgd = self._root.BkgdTruecolor(self._io, self, self._root)
+
+
+ class PhysChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.pixels_per_unit_x = self._io.read_u4be()
+ self.pixels_per_unit_y = self._io.read_u4be()
+ self.unit = self._root.PhysUnit(self._io.read_u1())
+
+
+ class TextChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.keyword = self._io.read_strz("iso8859-1", 0, False, True, True)
+ self.text = self._io.read_str_eos("iso8859-1")
+
+
+ class TimeChunk(KaitaiStruct):
+ def __init__(self, _io, _parent=None, _root=None):
+ self._io = _io
+ self._parent = _parent
+ self._root = _root if _root else self
+ self.year = self._io.read_u2be()
+ self.month = self._io.read_u1()
+ self.day = self._io.read_u1()
+ self.hour = self._io.read_u1()
+ self.minute = self._io.read_u1()
+ self.second = self._io.read_u1()