Exemple #1
0
    def do_POST(self):
        """
        Handles HTTP-POST-Request
        """

        # Read, analyze and parse request
        content_length = int(self.headers.get("Content-Length", 0))
        content_encoding = self.headers.get("Content-Encoding", "")
        accept_encoding = self.headers.get("Accept-Encoding", "")

        if "gzip" in content_encoding and not google_app_engine:
            # Decompress
            with tools.SpooledFile() as gzipped_file:
                # ToDo: read chunks
                # if content_length <= CHUNK_SIZE:
                #     gzipped_file.write(self.rfile.read(content_length))
                # else:
                #     chunks_quantity = content_length % CHUNK_SIZE
                # ...
                gzipped_file.write(self.rfile.read(content_length))
                gzipped_file.seek(0)
                with gzip.GzipFile(filename="",
                                   mode="rb",
                                   fileobj=gzipped_file) as gz:
                    request_json = gz.read()
        else:
            request_json = self.rfile.read(content_length)

        # Call
        response_json = self.call(request_json) or ""

        # Return result
        self.send_response(code=httplib.OK)
        self.set_content_type(self.content_type)
        self.set_no_cache()

        if "gzip" in accept_encoding:
            # Gzipped
            content = tools.SpooledFile()
            with gzip.GzipFile(filename="", mode="wb", fileobj=content) as gz:
                gz.write(response_json)
            content.seek(0)

            # Send compressed
            self.set_content_encoding("gzip")
            self.set_content_length(len(content))
            self.end_headers()
            self.wfile.write(content.read())
        else:
            # Send uncompressed
            self.set_content_length(len(response_json))
            self.end_headers()
            self.wfile.write(response_json)

        return
Exemple #2
0
    def request_handler(self, *args, **kwargs):
        """
        Json-RPC Handler
        """

        if cherrypy.request.method == "GET":
            # GET

            # Arguments
            jsonrpc = kwargs.get("jsonrpc")
            id = kwargs.get("id")
            method = kwargs.get("method")
            if not method:
                # Bad Request
                raise cherrypy.HTTPError(httplib.BAD_REQUEST)

            # params
            _args = []
            _kwargs = {}
            params = kwargs.get("params")
            if params:
                params = rpcjson.loads(params)
                if isinstance(params, list):
                    _args = params
                    _kwargs = {}
                elif isinstance(params, dict):
                    _args = []
                    _kwargs = params

            # Create JSON request string
            request_dict = rpcrequest.create_request_dict(method, *_args, **_kwargs)
            request_dict["jsonrpc"] = jsonrpc
            request_dict["id"] = id
            request_json = rpcjson.dumps(request_dict)
        else:
            content_length = int(cherrypy.request.headers.get("Content-Length", 0))
            # POST
            if (
                ("gzip" in cherrypy.request.headers.get("Content-Encoding", "")) and
                not google_app_engine
            ):
                spooled_file = tools.SpooledFile(source_file = cherrypy.request.body)
                request_json = tools.gunzip_file(spooled_file)
            else:
                request_json = cherrypy.request.body.read(content_length)

        # Call method
        result_string = self.call(request_json) or ""

        # Return JSON-String
        cherrypy.response.headers["Cache-Control"] = "no-cache"
        cherrypy.response.headers["Pragma"] = "no-cache"
        cherrypy.response.headers["Content-Type"] = "application/json"
        if (
            ("gzip" in cherrypy.request.headers.get("Accept-Encoding", "")) and
            not google_app_engine
        ):
            # Gzip-compressed
            cherrypy.response.headers["Content-Encoding"] = "gzip"
            return compress(result_string, compress_level = 5)
        else:
            # uncompressed
            return result_string
Exemple #3
0
def http_request(url,
                 json_string,
                 username=None,
                 password=None,
                 timeout=None,
                 additional_headers=None,
                 content_type=None,
                 cookies=None,
                 gzipped=None,
                 ssl_context=None,
                 debug=None):
    """
    Fetch data from webserver (POST request)

    :param json_string: JSON-String

    :param username: If *username* is given, BASE authentication will be used.

    :param timeout: Specifies a timeout in seconds for blocking operations
        like the connection attempt (if not specified, the global default
        timeout setting will be used).
        See: https://github.com/gerold-penz/python-jsonrpc/pull/6

    :param additional_headers: Dictionary with additional headers
        See: https://github.com/gerold-penz/python-jsonrpc/issues/5

    :param content_type: Possibility to change the content-type header.

    :param cookies: Possibility to add simple cookie-items as key-value pairs.
        The key and the value of each cookie-item must be a bytestring.
        Unicode is not allowed here.

    :param gzipped: If `True`, the JSON-String will be gzip-compressed.

    :param ssl_context: Specifies custom TLS/SSL settings for connection.
        Python > 2.7.9
        See: https://docs.python.org/2/library/ssl.html#client-side-operation

    :param debug: If `True` --> *logging.debug*
    """

    # Debug
    if debug:
        logging.debug(u"Client-->Server: {json_string}".format(
            json_string=repr(json_string)))

    # Create request and add data
    request = urllib2.Request(url)

    if gzipped:
        # Compress content (SpooledTemporaryFile to reduce memory usage)
        spooled_file = tools.SpooledFile()
        tools.gzip_str_to_file(json_string, spooled_file)
        del json_string
        request.add_header("Content-Encoding", "gzip")
        request.add_header("Accept-Encoding", "gzip")
        spooled_file.seek(0)
        request.add_data(spooled_file)
    else:
        request.add_data(json_string)

    # Content Type
    request.add_header("Content-Type", content_type or "application/json")

    # Authorization
    if username:
        base64string = base64.b64encode("%s:%s" % (username, password)).strip()
        request.add_unredirected_header("Authorization",
                                        "Basic %s" % base64string)

    # Cookies
    if cookies:
        cookie = Cookie.SimpleCookie(cookies)
        request.add_header("Cookie", cookie.output(header="", sep=";"))

    # Additional headers (overrides other headers)
    if additional_headers:
        for key, val in additional_headers.items():
            request.add_header(key, val)

    # Send request to server
    try:
        if ssl_context:
            try:
                response = urllib2.urlopen(request,
                                           timeout=timeout,
                                           context=ssl_context)
            except TypeError as err:
                if u"context" in unicode(err):
                    raise NotImplementedError(
                        u"SSL-Context needs Python >= 2.7.9")
                else:
                    raise
        else:
            response = urllib2.urlopen(request, timeout=timeout)
    except urllib2.HTTPError as err:
        if debug:
            retval = err.read()
            logging.debug(
                u"Client<--Server: {retval}".format(retval=repr(retval)))
        raise

    # Analyze response and return result
    try:
        if "gzip" in response.headers.get("Content-Encoding", ""):
            response_file = tools.SpooledFile(source_file=response)
            if debug:
                retval = tools.gunzip_file(response_file)
                logging.debug(
                    u"Client<--Server: {retval}".format(retval=repr(retval)))
                return retval
            return tools.gunzip_file(response_file)
        else:
            if debug:
                retval = response.read()
                logging.debug(
                    u"Client<--Server: {retval}".format(retval=repr(retval)))
                return retval
            return response.read()
    finally:
        response.close()