From 934ea4bd5f9b76cd88ded3aa09cac06c2f77d8a0 Mon Sep 17 00:00:00 2001 From: Jarrod Johnson Date: Wed, 30 Apr 2014 15:54:22 -0400 Subject: [PATCH] Preserve file extensions when client requests data by extension Previously, following links in the output would not work correctly. Have caller preference for extension denoted type propogate into link targets. --- confluent/httpapi.py | 35 ++++++++++++++++++++--------------- confluent/messages.py | 24 ++++++++++++++---------- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/confluent/httpapi.py b/confluent/httpapi.py index 46418788..cb432303 100644 --- a/confluent/httpapi.py +++ b/confluent/httpapi.py @@ -215,13 +215,13 @@ def _pick_mimetype(env): if the '.json' scheme doesn't cut it. """ if env['PATH_INFO'].endswith('.json'): - return 'application/json; charset=utf-8' + return 'application/json; charset=utf-8', '.json' elif env['PATH_INFO'].endswith('.html'): - return 'text/html' + return 'text/html', '.html' elif 'application/json' in env['HTTP_ACCEPT']: - return 'application/json; charset=utf-8' + return 'application/json; charset=utf-8', '' else: - return 'text/html' + return 'text/html', '' def _assign_consessionid(consolesession): @@ -248,7 +248,7 @@ def resourcehandler(env, start_response): def resourcehandler_backend(env, start_response): """Function to handle new wsgi requests """ - mimetype = _pick_mimetype(env) + mimetype, extension = _pick_mimetype(env) reqbody = None reqtype = None if 'CONTENT_LENGTH' in env and int(env['CONTENT_LENGTH']) > 0: @@ -362,16 +362,17 @@ def resourcehandler_backend(env, start_response): return pagecontent = "" if mimetype == 'text/html': - for datum in _assemble_html(hdlr, resource, lquerydict, url): + for datum in _assemble_html(hdlr, resource, lquerydict, url, + extension): pagecontent += datum else: - for datum in _assemble_json(hdlr, resource, url): + for datum in _assemble_json(hdlr, resource, url, extension): pagecontent += datum start_response('200 OK', headers) yield pagecontent -def _assemble_html(responses, resource, querydict, url): +def _assemble_html(responses, resource, querydict, url, extension): yield '' \ 'Confluent REST Explorer: ' + url + '' \ '
../
' + yield '../{0}
'.format( + extension) else: iscollection = False - yield './
' + yield './{0}
'.format( + extension) pendingrsp = [] for rsp in responses: if isinstance(rsp, confluent.messages.LinkRelation): - yield rsp.html() + "
" + yield rsp.html(extension) + "
" else: pendingrsp.append(rsp) for rsp in pendingrsp: @@ -420,26 +423,28 @@ def _assemble_html(responses, resource, querydict, url): '
') -def _assemble_json(responses, resource, url): +def _assemble_json(responses, resource, url, extension): #NOTE(jbjohnso) I'm considering giving up on yielding bit by bit #in json case over http. Notably, duplicate key values from plugin #overwrite, but we'd want to preserve them into an array instead. #the downside is that http would just always blurt it ll out at #once and hold on to all the data in memory links = { - 'self': {"href": resource}, + 'self': {"href": resource + extension}, } if url == '/': pass elif resource[-1] == '/': - links['collection'] = {"href": "../"} + links['collection'] = {"href": "../" + extension} else: - links['collection'] = {"href": "./"} + links['collection'] = {"href": "./" + extension} rspdata = {} for rsp in responses: if isinstance(rsp, confluent.messages.LinkRelation): haldata = rsp.raw() for hk in haldata.iterkeys(): + if 'href' in haldata[hk]: + haldata[hk]['href'] += extension if hk in links: if isinstance(links[hk], list): links[hk].append(haldata[hk]) diff --git a/confluent/messages.py b/confluent/messages.py index fb6b0dc0..929f2440 100644 --- a/confluent/messages.py +++ b/confluent/messages.py @@ -63,7 +63,7 @@ class ConfluentMessage(object): def strip_node(self, node): self.kvpairs = self.kvpairs[node] - def html(self): + def html(self, extension=''): #this is used to facilitate the api explorer feature snippet = "" for key in self.kvpairs.iterkeys(): @@ -134,7 +134,7 @@ class DeletedResource(ConfluentMessage): class ConfluentChoiceMessage(ConfluentMessage): valid_values = set() - def html(self): + def html(self, extension=''): snippet = "" for key in self.kvpairs.iterkeys(): val = self.kvpairs[key] @@ -171,11 +171,13 @@ class LinkRelation(ConfluentMessage): """ return {self.rel: {"href": self.href}} - def html(self): + def html(self, extension=''): """Provide an html representation of the link relation. This is used by the API explorer aspect of httpapi""" - return '{0}'.format(self.href, self.rel) + return '{0}{2}'.format(self.href, + self.rel, + extension) # return '%s{0} . . . . . . . . . . . . ' - '').format(self.href, self.rel) + return ( + '{0}{2} . . . . . . . . . . . . ' + '').format(self.href, self.rel, extension) else: - return '{0}'.format(self.href) + return '{0}{1}'.format(self.href, + extension) def get_input_message(path, operation, inputdata, nodes=None):