Browse Source

Add binary support to nilmdb.server; enforce content-type

tags/nilmdb-1.5.0
Jim Paris 10 years ago
parent
commit
cc211542f8
3 changed files with 37 additions and 4 deletions
  1. +6
    -2
      nilmdb/client/httpclient.py
  2. +15
    -2
      nilmdb/server/server.py
  3. +16
    -0
      tests/test_client.py

+ 6
- 2
nilmdb/client/httpclient.py View File

@@ -105,9 +105,13 @@ class HTTPClient(object):
else:
return self._req("POST", url, None, params)

def put(self, url, data, params = None):
def put(self, url, data, params = None, binary = False):
"""Simple PUT (parameters in URL, data in body)"""
return self._req("PUT", url, params, data)
if binary:
h = { 'Content-type': 'application/octet-stream' }
else:
h = { 'Content-type': 'text/plain; charset=utf-8' }
return self._req("PUT", url, query = params, body = data, headers = h)

# Generator versions that return data one line at a time.
def _req_gen(self, method, url, query = None, body = None,


+ 15
- 2
nilmdb/server/server.py View File

@@ -305,10 +305,15 @@ class Stream(NilmApp):
@cherrypy.tools.json_out()
@exception_to_httperror(NilmDBError, ValueError)
@cherrypy.tools.CORS_allow(methods = ["PUT"])
def insert(self, path, start, end):
def insert(self, path, start, end, binary = False):
"""
Insert new data into the database. Provide textual data
(matching the path's layout) as a HTTP PUT.

If 'binary' is True, expect raw binary data, rather than lines
of ASCII-formatted data. Raw binary data is always
little-endian and matches the database types (including an
int64 timestamp).
"""
# Important that we always read the input before throwing any
# errors, to keep lengths happy for persistent connections.
@@ -316,6 +321,14 @@ class Stream(NilmApp):
# requests, if we ever want to handle those (issue #1134)
body = cherrypy.request.body.read()

# Verify content type for binary data
content_type = cherrypy.request.headers.get('content-type')
if binary and content_type:
if content_type != "application/octet-stream":
raise cherrypy.HTTPError("400", "Content type must be "
"application/octet-stream for "
"binary data, not " + content_type)

# Check path and get layout
if len(self.db.stream_list(path = path)) != 1:
raise cherrypy.HTTPError("404", "No such stream: " + path)
@@ -325,7 +338,7 @@ class Stream(NilmApp):

# Pass the data directly to nilmdb, which will parse it and
# raise a ValueError if there are any problems.
self.db.stream_insert(path, start, end, body)
self.db.stream_insert(path, start, end, body, binary)

# Done
return


+ 16
- 0
tests/test_client.py View File

@@ -239,6 +239,22 @@ class TestClient(object):
in_("400 Bad Request", str(e.exception))
in_("start must precede end", str(e.exception))

# Good content type
with assert_raises(ClientError) as e:
client.http.put("stream/insert", "",
{ "path": "xxxx", "start": 0, "end": 1,
"binary": 1 },
binary = True)
in_("No such stream", str(e.exception))

# Bad content type
with assert_raises(ClientError) as e:
client.http.put("stream/insert", "",
{ "path": "xxxx", "start": 0, "end": 1,
"binary": 1 },
binary = False)
in_("Content type must be application/octet-stream", str(e.exception))

# Specify start/end (starts too late)
data = timestamper.TimestamperRate(testfile, start, 120)
with assert_raises(ClientError) as e:


Loading…
Cancel
Save