From 32be4cf9e56d72eaf64cb232f0d833ac546f8510 Mon Sep 17 00:00:00 2001 From: Bertrand Lemasle Date: Wed, 21 Mar 2018 16:37:32 +1300 Subject: [PATCH] Started some real work around a gps tracker postions server. --- GpsTrackerServer/GpsTrackerServer.pyproj | 12 ++++++++++ GpsTrackerServer/api.py | 16 ++++++++++++++ GpsTrackerServer/constants.py | 4 ++++ GpsTrackerServer/main.py | 28 +++--------------------- GpsTrackerServer/middlewares.py | 24 ++++++++++++++++++++ GpsTrackerServer/resources.py | 11 ++++++++++ 6 files changed, 70 insertions(+), 25 deletions(-) create mode 100644 GpsTrackerServer/api.py create mode 100644 GpsTrackerServer/constants.py create mode 100644 GpsTrackerServer/middlewares.py create mode 100644 GpsTrackerServer/resources.py diff --git a/GpsTrackerServer/GpsTrackerServer.pyproj b/GpsTrackerServer/GpsTrackerServer.pyproj index d12a86b..7082fa1 100644 --- a/GpsTrackerServer/GpsTrackerServer.pyproj +++ b/GpsTrackerServer/GpsTrackerServer.pyproj @@ -27,9 +27,21 @@ false + + Code + + + Code + Code + + Code + + + Code + diff --git a/GpsTrackerServer/api.py b/GpsTrackerServer/api.py new file mode 100644 index 0000000..b2fd90b --- /dev/null +++ b/GpsTrackerServer/api.py @@ -0,0 +1,16 @@ +import falcon +import middlewares +import resources +import constants + +#from constants import * + +def create(): + api = falcon.API(media_type=constants.MEDIA_CSV, middleware=[ + middlewares.AuthMiddleware(constants.USER_AGENT), + middlewares.RequireCSV() + ]) + + api.add_route(constants.ROUTES_POSITIONS, resources.PositionsResource()) + + return api \ No newline at end of file diff --git a/GpsTrackerServer/constants.py b/GpsTrackerServer/constants.py new file mode 100644 index 0000000..6cbbbba --- /dev/null +++ b/GpsTrackerServer/constants.py @@ -0,0 +1,4 @@ +USER_AGENT = 'SIMCOM_MODULE' +MEDIA_CSV = 'text/csv' + +ROUTES_POSITIONS = '/positions' diff --git a/GpsTrackerServer/main.py b/GpsTrackerServer/main.py index 3258d82..b559f47 100644 --- a/GpsTrackerServer/main.py +++ b/GpsTrackerServer/main.py @@ -2,34 +2,12 @@ Basic HTTP server to receive and save gps positions sent by Arduino GPS Tracker """ -import falcon - -class RequireCSV: - - def process_request(self, req, resp): - if req.method in ('POST', 'PUT'): - if 'text/csv' not in req.content_type: - raise falcon.HTTPUnsupportedMediaType('Only CSV is supported') - -class PositionsResource: - - def on_post(self, req, resp): - data = req.bounded_stream.read() - resp.body = data - resp.status = falcon.HTTP_201 - -positions = PositionsResource() - -api = falcon.API(middleware=[ - RequireCSV() -]) - -api.add_route('/positions', positions) +import api if __name__ == "__main__": # Use python built-in WSGI reference implemention to run a web server from wsgiref.simple_server import make_server print('Starting web server...') - srv = make_server('localhost', 8080, api) - srv.serve_forever() \ No newline at end of file + srv = make_server('localhost', 8080, api.create()) + srv.serve_forever() diff --git a/GpsTrackerServer/middlewares.py b/GpsTrackerServer/middlewares.py new file mode 100644 index 0000000..51d801a --- /dev/null +++ b/GpsTrackerServer/middlewares.py @@ -0,0 +1,24 @@ +import falcon +import constants + +class RequireCSV(object): + + def process_request(self, req, resp): + if req.method in ('POST', 'PUT'): + if constants.MEDIA_CSV not in req.content_type: + raise falcon.HTTPUnsupportedMediaType + +class AuthMiddleware(object): + + def __init__(self, userAgentRequired): + self._userAgentRequired = userAgentRequired + + def process_request(self, req, resp): + authorization = req.get_header('Authorization') + userAgent = req.get_header('User-Agent') + + if userAgent != self._userAgentRequired: + if authorization is None: #make clients believe that Authorization header is the issue + raise falcon.HTTPForbidden + else: + raise falcon.HTTPUnauthorized diff --git a/GpsTrackerServer/resources.py b/GpsTrackerServer/resources.py new file mode 100644 index 0000000..579bdf1 --- /dev/null +++ b/GpsTrackerServer/resources.py @@ -0,0 +1,11 @@ +import falcon + +class PositionsResource: + + def on_post(self, req, resp): + data = req.bounded_stream.read() + resp.body = data + resp.status = falcon.HTTP_201 + + def on_get(self, req, resp): + raise falcon.HTTPNotImplemented