From 9f92df2be8725e67f2a36f6503c737be54bc9347 Mon Sep 17 00:00:00 2001 From: Sepalani Date: Sat, 20 Feb 2016 18:25:00 +0100 Subject: [PATCH] [WIP] NAS: Moved qs methods in utils --- nas_server.py | 48 +++++------------------------------------------- other/utils.py | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/nas_server.py b/nas_server.py index 9ab231e..b3eed04 100644 --- a/nas_server.py +++ b/nas_server.py @@ -88,7 +88,7 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): try: length = int(self.headers['content-length']) - post = self.str_to_dict(self.rfile.read(length)) + post = utils.qs_to_dict(self.rfile.read(length)) if self.client_address[0] == '127.0.0.1': client_address = ( self.headers.get('x-forwarded-for', @@ -136,7 +136,7 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): client_address) logger.log(logging.DEBUG, "%s", ret) - ret = self.dict_to_str(ret) + ret = utils.dict_to_qs(ret) elif action == "login": if self.server.db.is_banned(post): @@ -191,7 +191,7 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): client_address) logger.log(logging.DEBUG, "%s", ret) - ret = self.dict_to_str(ret) + ret = utils.dict_to_qs(ret) elif action == "SVCLOC" or action == "svcloc": # Get service based on service id number @@ -231,7 +231,7 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): client_address) logger.log(logging.DEBUG, "%s", ret) - ret = self.dict_to_str(ret) + ret = utils.dict_to_qs(ret) else: logger.log(logging.WARNING, "Unknown action request %s from %s!", @@ -259,7 +259,7 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): logger.log(logging.DEBUG, "pr response to %s", client_address) logger.log(logging.DEBUG, "%s", ret) - ret = self.dict_to_str(ret) + ret = utils.dict_to_qs(ret) elif self.path == "/download": logger.log(logging.DEBUG, "Request to %s from %s", @@ -402,44 +402,6 @@ class NasHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): logger.log(logging.ERROR, "Unknown exception: %s", traceback.format_exc()) - def str_to_dict(self, s): - # Enable keep_blank_values, skipped otherwise. - # TODO: Move this in utils module? - ret = urlparse.parse_qs(s, True) - - for k, v in ret.iteritems(): - try: - # I'm not sure about the replacement for '-', but it'll at - # least let it be decoded. - # For the most part it's not important since it's mostly - # used for the devname/ingamesn fields. - ret[k] = base64.b64decode(urlparse.unquote(v[0]) - .replace("*", "=") - .replace("?", "/") - .replace(">", "+") - .replace("-", "/")) - except TypeError: - print "Could not decode following string: ret[%s] = %s" \ - % (k, v[0]) - print "url: %s" % s - # If you don't assign it like this it'll be a list, which - # breaks other code. - ret[k] = v[0] - - return ret - - def dict_to_str(self, dict): - """Convert dict to str. - - nas(wii).nintendowifi.net has a URL query-like format but does not - use encoding for special characters. - """ - for k, v in dict.iteritems(): - dict[k] = base64.b64encode(v).replace("=", "*") - - return "&".join("{!s}={!s}".format(k, v) for k, v in dict.items()) + \ - "\r\n" - def filter_list_g5_mystery_gift(self, data, rhgamecd): """Custom selection for generation 5 mystery gifts, so that the random or data-based selection still works properly.""" diff --git a/other/utils.py b/other/utils.py index 3e3c94d..41e5dc4 100644 --- a/other/utils.py +++ b/other/utils.py @@ -18,11 +18,13 @@ along with this program. If not, see . """ +import base64 import logging import logging.handlers import random import string import struct +import urlparse import ctypes import os @@ -327,3 +329,43 @@ def pretty_print_hex(orig_data, cols=16, sep=' '): # output += "\n" # # return output + + +def qs_to_dict(s): + """Convert query string to dict.""" + ret = urlparse.parse_qs(s, True) + + for k, v in ret.items(): + try: + # I'm not sure about the replacement for '-', but it'll at + # least let it be decoded. + # For the most part it's not important since it's mostly + # used for the devname/ingamesn fields. + ret[k] = base64.b64decode(urlparse.unquote(v[0]) + .replace("*", "=") + .replace("?", "/") + .replace(">", "+") + .replace("-", "/")) + except TypeError: + """ + print("Could not decode following string: ret[%s] = %s" + % (k, v[0])) + print("url: %s" % s) + """ + # If you don't assign it like this it'll be a list, which + # breaks other code. + ret[k] = v[0] + + return ret + + +def dict_to_qs(d): + """Convert dict to query string. + + nas(wii).nintendowifi.net has a URL query-like format but does not + use encoding for special characters. + """ + # Dictionary comprehension is used to not modify the original + ret = {k: base64.b64encode(v).replace("=", "*") for k, v in d.items()} + + return "&".join("{!s}={!s}".format(k, v) for k, v in ret.items()) + "\r\n"