From 477b0806b0c2b7d0c96186aa51b2e77cdd4b0bd1 Mon Sep 17 00:00:00 2001
From: JackDandy <JackDandy@users.noreply.github.com>
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)
-- 
GitLab