From 477b0806b0c2b7d0c96186aa51b2e77cdd4b0bd1 Mon Sep 17 00:00:00 2001 From: JackDandy Date: Tue, 11 Nov 2014 03:19:08 +0000 Subject: [PATCH] Fix API response header for JSON content type and the return of JSONP data. The API should return application/json Content-Type for JSON data instead of application/html. Tornado expects a dict in order to JSON encode and send header "Content-Type:application/json". SR already encodes data plus it supports JSONP. So, the encoded string data is wrapped into a dict, and a test is added at Tornado def write() to unwrap and skip encoding, in order to set the correct content-header and also use JSONP. Added file HACKS.txt to serve as a reminder for anyone updating the library. --- CHANGES.md | 2 +- HACKS.txt | 3 +++ sickbeard/webapi.py | 10 ++++++---- tornado/web.py | 5 ++++- 4 files changed, 14 insertions(+), 6 deletions(-) create mode 100644 HACKS.txt diff --git a/CHANGES.md b/CHANGES.md index cfa98215..115da9a9 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -73,7 +73,7 @@ * Fix dropdown confirm dialogs for restart and shutdown * Fix parsing utf8 data from tvdb and tvrage * Fix display show status and subtitle searches to use new column class names - +* Fix API response header for JSON content type and the return of JSONP data ### 0.2.1 (2014-10-22 06:41:00 UTC) diff --git a/HACKS.txt b/HACKS.txt new file mode 100644 index 00000000..8750d457 --- /dev/null +++ b/HACKS.txt @@ -0,0 +1,3 @@ +Libs with customisations... + +/tornado diff --git a/sickbeard/webapi.py b/sickbeard/webapi.py index 2b4abd1e..68dd25a6 100644 --- a/sickbeard/webapi.py +++ b/sickbeard/webapi.py @@ -164,14 +164,16 @@ class Api(webserve.MainHandler): self.set_header("Content-Type", "application/json") try: out = json.dumps(dict, indent=self.intent, sort_keys=True) - callback = self.request.headers.get('callback', None) or self.request.headers.get('jsonp', None) - if callback != None: - out = callback + '(' + out + ');' # wrap with JSONP call if requested + if 'jsonp' in self.request.query_arguments: + out = self.request.arguments['jsonp'] + '(' + out + ');' # wrap with JSONP call if requested + except Exception, e: # if we fail to generate the output fake an error logger.log(u"API :: " + traceback.format_exc(), logger.DEBUG) out = '{"result":"' + result_type_map[RESULT_ERROR] + '", "message": "error while composing output: "' + ex( e) + '"}' - return out + + tornado_write_hack_dict = {'unwrap_json': out} + return tornado_write_hack_dict def _grand_access(self, realKey, args, kwargs): """ validate api key and log result """ diff --git a/tornado/web.py b/tornado/web.py index a038265f..9edd719a 100644 --- a/tornado/web.py +++ b/tornado/web.py @@ -652,7 +652,10 @@ class RequestHandler(object): if not isinstance(chunk, (bytes, unicode_type, dict)): raise TypeError("write() only accepts bytes, unicode, and dict objects") if isinstance(chunk, dict): - chunk = escape.json_encode(chunk) + if 'unwrap_json' in chunk: + chunk = chunk['unwrap_json'] + else: + chunk = escape.json_encode(chunk) self.set_header("Content-Type", "application/json; charset=UTF-8") chunk = utf8(chunk) self._write_buffer.append(chunk)