diff --git a/ripe/atlas/tools/renderers/http.py b/ripe/atlas/tools/renderers/http.py
index 92bea39..427dbc1 100644
--- a/ripe/atlas/tools/renderers/http.py
+++ b/ripe/atlas/tools/renderers/http.py
@@ -13,12 +13,54 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
+from ..helpers.colours import colourise
+
from .base import Renderer as BaseRenderer
+from .base import Result
class Renderer(BaseRenderer):
+ """
+ We're abusing the Extended Log File Format here to render the result,
+ amending it to include a few things not originally specified in the W3C
+ Working Draft: http://www.w3.org/TR/WD-logfile.html Namely:
+ http-version, header-bytes, and body-bytes
+ """
RENDERS = [BaseRenderer.TYPE_HTTP]
+ COLOURS = {
+ "2": "green",
+ "3": "blue",
+ "4": "yellow",
+ "5": "red"
+ }
def on_result(self, result, probes=None):
- print("Not ready yet\n")
+ r = "#Version: 1.0\n#Date: {}\n#Fields: {}\n".format(
+ result.created.strftime("%Y-%m-%d %H:%M:%S"),
+ "cs-method cs-uri c-ip s-ip sc-status time-taken http-version "
+ "header-bytes body-bytes"
+ )
+ for response in result.responses:
+ r += self._colourise_by_status(
+ "{} {} {} {} {} {} {} {} {}\n".format(
+ result.method,
+ result.uri,
+ response.source_address,
+ response.destination_address,
+ response.code,
+ response.response_time,
+ response.version,
+ response.head_size,
+ response.body_size
+ ),
+ response.code
+ )
+
+ return Result(r + "\n", result.probe_id)
+
+ def _colourise_by_status(self, output, status):
+ try:
+ return colourise(output, self.COLOURS[str(status)[0]])
+ except (IndexError, KeyError):
+ return colourise(output, "red")
diff --git a/ripe/atlas/tools/renderers/ntp.py b/ripe/atlas/tools/renderers/ntp.py
index 7d9a891..54ba339 100644
--- a/ripe/atlas/tools/renderers/ntp.py
+++ b/ripe/atlas/tools/renderers/ntp.py
@@ -14,6 +14,7 @@
# along with this program. If not, see .
from .base import Renderer as BaseRenderer
+from .base import Result
class Renderer(BaseRenderer):
@@ -21,4 +22,4 @@ class Renderer(BaseRenderer):
RENDERS = [BaseRenderer.TYPE_NTP]
def on_result(self, result, probes=None):
- print("Not ready yet\n")
+ return Result("Not ready yet\n", result.probe_id)
diff --git a/tests/__init__.py b/tests/__init__.py
index 7f98f57..76bab3e 100644
--- a/tests/__init__.py
+++ b/tests/__init__.py
@@ -23,6 +23,7 @@
from .helpers import TestArgumentTypeHelper
from .renderers import (
TestPingRenderer,
+ TestHttpRenderer,
TestSSLConsistency,
TestAggregatePing,
TestRawRenderer,
@@ -37,6 +38,7 @@
TestReportCommand,
TestArgumentTypeHelper,
TestPingRenderer,
+ TestHttpRenderer,
TestSSLConsistency,
TestAggregatePing,
TestRawRenderer,
diff --git a/tests/renderers/__init__.py b/tests/renderers/__init__.py
index 27d49f8..0e63ac1 100644
--- a/tests/renderers/__init__.py
+++ b/tests/renderers/__init__.py
@@ -14,12 +14,14 @@
# along with this program. If not, see .
from .ping import TestPingRenderer
+from .http import TestHttpRenderer
from .aggregate_ping import TestAggregatePing
from .ssl_consistency import TestSSLConsistency
from .raw import TestRawRenderer
__all__ = [
TestPingRenderer,
+ TestHttpRenderer,
TestAggregatePing,
TestSSLConsistency
]
diff --git a/tests/renderers/http.py b/tests/renderers/http.py
new file mode 100644
index 0000000..31a2048
--- /dev/null
+++ b/tests/renderers/http.py
@@ -0,0 +1,48 @@
+# Copyright (c) 2015 RIPE NCC
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see .
+
+import unittest
+
+from ripe.atlas.sagan import Result
+from ripe.atlas.tools.renderers.http import Renderer
+
+
+class TestHttpRenderer(unittest.TestCase):
+
+ def __init__(self, *args, **kwargs):
+ unittest.TestCase.__init__(self, *args, **kwargs)
+ self.basic = Result.get('{"lts":64,"from":"217.13.64.36","msm_id":2841267,"fw":4720,"timestamp":1450185727,"uri":"http://at-vie-as1120.anchors.atlas.ripe.net:80/4096","prb_id":1,"result":[{"rt":45.953289,"src_addr":"217.13.64.36","hsize":131,"af":4,"bsize":1668618,"res":200,"method":"GET","ver":"1.1","dst_addr":"193.171.255.2"}],"group_id":2841267,"type":"http","msm_name":"HTTPGet"}')
+ self.multiple = Result.get('{"lts":64,"from":"217.13.64.36","msm_id":2841267,"fw":4720,"timestamp":1450185727,"uri":"http://at-vie-as1120.anchors.atlas.ripe.net:80/4096","prb_id":1,"result":[{"rt":45.953289,"src_addr":"217.13.64.36","hsize":131,"af":4,"bsize":1668618,"res":200,"method":"GET","ver":"1.1","dst_addr":"193.171.255.2"},{"rt":45.953289,"src_addr":"217.13.64.36","hsize":131,"af":4,"bsize":1668618,"res":200,"method":"GET","ver":"1.1","dst_addr":"193.171.255.2"}],"group_id":2841267,"type":"http","msm_name":"HTTPGet"}')
+
+ def test_basic(self):
+ expected = (
+ '#Version: 1.0\n'
+ '#Date: 2015-12-15 13:22:07\n'
+ '#Fields: cs-method cs-uri c-ip s-ip sc-status time-taken http-version header-bytes body-bytes\n'
+ 'GET http://at-vie-as1120.anchors.atlas.ripe.net:80/4096 217.13.64.36 193.171.255.2 200 45.953289 1.1 131 1668618\n\n'
+ )
+ self.assertEqual(Renderer().on_result(self.basic), expected)
+ self.assertEqual(Renderer().on_result(self.basic).probe_id, 1)
+
+ def test_multiple(self):
+ expected = (
+ '#Version: 1.0\n'
+ '#Date: 2015-12-15 13:22:07\n'
+ '#Fields: cs-method cs-uri c-ip s-ip sc-status time-taken http-version header-bytes body-bytes\n'
+ 'GET http://at-vie-as1120.anchors.atlas.ripe.net:80/4096 217.13.64.36 193.171.255.2 200 45.953289 1.1 131 1668618\n'
+ 'GET http://at-vie-as1120.anchors.atlas.ripe.net:80/4096 217.13.64.36 193.171.255.2 200 45.953289 1.1 131 1668618\n\n'
+ )
+ self.assertEqual(Renderer().on_result(self.multiple), expected)
+ self.assertEqual(Renderer().on_result(self.basic).probe_id, 1)