Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Http status codes #84

Merged
merged 2 commits into from
Jul 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ Unreleased
==========

New Features:

* Adds route `/info` which returns contents of `twitcher.__version__`.
* Adds route `/versions` which returns version details such as `Twitcher` app version and employed adapter version.

Changes:

* Updated `README.rst` to match recent development, reference and docker image link.
* Adds URI of `/info` and `/versions` routes in the frontpage response.
* Corresponding HTTP status codes are returned for raised ``OWSException``.

Fixes:

Expand Down
2 changes: 1 addition & 1 deletion tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
WMS_CAPS_NCWMS2_111_XML = os.path.join(RESOURCES_PATH, 'wms_caps_ncwms2_111.xml')
WMS_CAPS_NCWMS2_130_XML = os.path.join(RESOURCES_PATH, 'wms_caps_ncwms2_130.xml')

WPS_TEST_SERVICE = 'http://localhost:5000/wps'
WPS_TEST_SERVICE = os.getenv("TWITCHER_TEST_WPS", "http://localhost:5000/wps")


def dummy_request(dbsession):
Expand Down
4 changes: 2 additions & 2 deletions tests/test_owsproxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ def tearDown(self):
def test_badrequest_url(self):
request = DummyRequest(scheme='http')
response = owsproxy_view(request)
assert isinstance(response, OWSAccessFailed) is True
assert isinstance(response, OWSAccessFailed)

def test_badrequest_netloc(self):
request = DummyRequest(scheme='http',
params={'url': 'http://'})
response = owsproxy_view(request)
assert isinstance(response, OWSAccessFailed) is True
assert isinstance(response, OWSAccessFailed)
37 changes: 32 additions & 5 deletions twitcher/owsexceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,21 @@

from pyramid.interfaces import IExceptionResponse
from pyramid.response import Response
from pyramid.httpexceptions import (
HTTPException,
HTTPUnauthorized,
HTTPBadRequest,
HTTPInternalServerError,
HTTPNotImplemented,
status_map,
)

import inspect


@implementer(IExceptionResponse)
class OWSException(Response, Exception):

status_base = HTTPNotImplemented
code = 'NoApplicableCode'
value = None
locator = 'NoApplicableCode'
Expand All @@ -34,16 +44,29 @@ class OWSException(Response, Exception):
</Exception>
</ExceptionReport>''')

def __init__(self, detail=None, value=None, **kw):
Response.__init__(self, status='200 OK', **kw)
def __init__(self, detail=None, value=None, status_base=None, **kw):
if status_base is not None:
self.status_base = status_base
Response.__init__(self, status=self._get_status_string(), **kw)
Exception.__init__(self, detail)
self.message = detail or self.explanation
if value:
self.locator = value

def __str__(self):
def __str__(self, skip_body=False):
return self.message

def _get_status_string(self):
if inspect.isclass(self.status_base) and issubclass(self.status_base, HTTPException):
status = self.status_base().status
elif isinstance(self.status_base, HTTPException):
status = self.status_base.status
elif isinstance(self.status_base, int):
status = status_map[self.status_base]().status
else:
raise ValueError("Invalid status base configuration.")
return status

def prepare(self, environ):
if not self.body:
self.content_type = 'text/xml'
Expand Down Expand Up @@ -77,28 +100,32 @@ def __call__(self, environ, start_response):


class OWSAccessForbidden(OWSException):
status_base = HTTPUnauthorized
locator = "AccessForbidden"
explanation = "Access to this service is forbidden"


class OWSAccessFailed(OWSException):
status_base = HTTPBadRequest
locator = "NotAcceptable"
explanation = "Access to this service failed"


class OWSNoApplicableCode(OWSException):
pass
status_base = HTTPInternalServerError


class OWSMissingParameterValue(OWSException):
"""MissingParameterValue WPS Exception"""
status_base = HTTPBadRequest
code = "MissingParameterValue"
locator = ""
explanation = "Parameter value is missing"


class OWSInvalidParameterValue(OWSException):
"""InvalidParameterValue WPS Exception"""
status_base = HTTPBadRequest
code = "InvalidParameterValue"
locator = ""
explanation = "Parameter value is invalid"
3 changes: 2 additions & 1 deletion twitcher/owssecurity.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from twitcher.owsexceptions import OWSAccessForbidden, OWSInvalidParameterValue
from twitcher.utils import path_elements, parse_service_name
from twitcher.owsrequest import OWSRequest
from pyramid.httpexceptions import HTTPNotFound

import logging
LOGGER = logging.getLogger("TWITCHER")
Expand Down Expand Up @@ -71,7 +72,7 @@ def check_request(self, request):
LOGGER.warning('public access for service %s', service_name)
except ServiceNotFound:
raise OWSInvalidParameterValue(
"Service not found", value="service")
"Service not found", value="service", status_base=HTTPNotFound)
ows_request = OWSRequest(request)
if not ows_request.service_allowed():
raise OWSInvalidParameterValue(
Expand Down