示例#1
0
    def requestReceived(self, command, path, version):
        """
        Called by channel when all data has been received.
        Overridden because Twisted merges GET and POST into one thing by default.
        """
        self.content.seek(0, 0)
        self.get = {}
        self.post = {}

        self.method, self.uri = command, path
        self.clientproto = version
        x = self.uri.split(b'?', 1)

        print self.method

        # URI and GET args assignment
        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.get = parse_qs(argstring, 1)

        # cache the client and server information, we'll need this later to be
        # serialized and sent with the request so CGIs will work remotely
        self.client = self.channel.transport.getPeer()
        self.host = self.channel.transport.getHost()

        # Argument processing
        ctype = self.requestHeaders.getRawHeaders(b'content-type')
        if ctype is not None:
            ctype = ctype[0]

        # Process POST data if present
        if self.method == b"POST" and ctype:
            mfd = b'multipart/form-data'
            key, pdict = _parseHeader(ctype)
            if key == b'application/x-www-form-urlencoded':
                self.post.update(parse_qs(self.content.read(), 1))
            elif key == mfd:
                try:
                    cgiArgs = cgi.parse_multipart(self.content, pdict)

                    if _PY3:
                        # parse_multipart on Python 3 decodes the header bytes
                        # as iso-8859-1 and returns a str key -- we want bytes
                        # so encode it back
                        self.post.update({
                            x.encode('iso-8859-1'): y
                            for x, y in cgiArgs.items()
                        })
                    else:
                        self.post.update(cgiArgs)
                except:
                    # It was a bad request.
                    _respondToBadRequestAndDisconnect(self.channel.transport)
                    return
            self.content.seek(0, 0)

        # Continue with rest of request handling
        self.process()
示例#2
0
    def requestReceived(self, command, path, version):
        """
        Called by channel when all data has been received.
        Overridden because Twisted merges GET and POST into one thing by default.
        """
        self.content.seek(0,0)
        self.get = {}
        self.post = {}

        self.method, self.uri = command, path
        self.clientproto = version
        x = self.uri.split(b'?', 1)

        print self.method

        # URI and GET args assignment
        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.get = parse_qs(argstring, 1)

        # cache the client and server information, we'll need this later to be
        # serialized and sent with the request so CGIs will work remotely
        self.client = self.channel.transport.getPeer()
        self.host = self.channel.transport.getHost()

        # Argument processing
        ctype = self.requestHeaders.getRawHeaders(b'content-type')
        if ctype is not None:
            ctype = ctype[0]

        # Process POST data if present
        if self.method == b"POST" and ctype:
            mfd = b'multipart/form-data'
            key, pdict = _parseHeader(ctype)
            if key == b'application/x-www-form-urlencoded':
                self.post.update(parse_qs(self.content.read(), 1))
            elif key == mfd:
                try:
                    cgiArgs = cgi.parse_multipart(self.content, pdict)

                    if _PY3:
                        # parse_multipart on Python 3 decodes the header bytes
                        # as iso-8859-1 and returns a str key -- we want bytes
                        # so encode it back
                        self.post.update({x.encode('iso-8859-1'): y
                                          for x, y in cgiArgs.items()})
                    else:
                        self.post.update(cgiArgs)
                except:
                    # It was a bad request.
                    _respondToBadRequestAndDisconnect(self.channel.transport)
                    return
            self.content.seek(0, 0)

        # Continue with rest of request handling
        self.process()
示例#3
0
 def testParseqs(self):
     self.failUnlessEqual(cgi.parse_qs("a=b&d=c;+=f"),
         http.parse_qs("a=b&d=c;+=f"))
     self.failUnlessRaises(ValueError, http.parse_qs, "blah",
         strict_parsing = 1)
     self.failUnlessEqual(cgi.parse_qs("a=&b=c", keep_blank_values = 1),
         http.parse_qs("a=&b=c", keep_blank_values = 1))
     self.failUnlessEqual(cgi.parse_qs("a=&b=c"),
         http.parse_qs("a=&b=c"))
示例#4
0
    def requestReceived(self, command, path, version):
        from twisted.web.http import parse_qs
        if self.do_log:
            print '%f Request Received' % time.time()

        self.content.seek(0,0)
        self.args = {}
        self.stack = []

        self.method, self.uri = command, path
        self.clientproto = version
        x = self.uri.split(b'?', 1)

        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.args = parse_qs(argstring, 1)

        # cache the client and server information, we'll need this later to be
        # serialized and sent with the request so CGIs will work remotely
        self.client = self.channel.transport.getPeer()
        self.host = self.channel.transport.getHost()

        # Argument processing
        args = self.args
        ctype = self.requestHeaders.getRawHeaders(b'content-type')
        if ctype is not None:
            ctype = ctype[0]

        if self.method == b"POST" and ctype:
            mfd = b'multipart/form-data'
            key, pdict = cgi.parse_header(ctype)
            if key == b'application/x-www-form-urlencoded':
                args.update(parse_qs(self.content.read(), 1))
            elif key == mfd:
                try:
                    self.content.seek(0,0)
                    args.update(self.parse_multipart(self.content, pdict))
                    #args.update(cgi.parse_multipart(self.content, pdict))

                except KeyError as e:
                    if e.args[0] == b'content-disposition':
                        # Parse_multipart can't cope with missing
                        # content-dispostion headers in multipart/form-data
                        # parts, so we catch the exception and tell the client
                        # it was a bad request.
                        self.channel.transport.write(
                                b"HTTP/1.1 400 Bad Request\r\n\r\n")
                        self.channel.transport.loseConnection()
                        return
                    raise

            self.content.seek(0, 0)

        self.process()
示例#5
0
    def requestReceived(self, command, path, version):
        from twisted.web.http import parse_qs
        if self.do_log:
            print '%f Request Received' % time.time()

        self.content.seek(0, 0)
        self.args = {}
        self.stack = []

        self.method, self.uri = command, path
        self.clientproto = version
        x = self.uri.split(b'?', 1)

        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.args = parse_qs(argstring, 1)

        # cache the client and server information, we'll need this later to be
        # serialized and sent with the request so CGIs will work remotely
        self.client = self.channel.transport.getPeer()
        self.host = self.channel.transport.getHost()

        # Argument processing
        args = self.args
        ctype = self.requestHeaders.getRawHeaders(b'content-type')
        if ctype is not None:
            ctype = ctype[0]

        if self.method == b"POST" and ctype:
            mfd = b'multipart/form-data'
            key, pdict = cgi.parse_header(ctype)
            if key == b'application/x-www-form-urlencoded':
                args.update(parse_qs(self.content.read(), 1))
            elif key == mfd:
                try:
                    self.content.seek(0, 0)
                    args.update(self.parse_multipart(self.content, pdict))
                    #args.update(cgi.parse_multipart(self.content, pdict))

                except KeyError as e:
                    if e.args[0] == b'content-disposition':
                        # Parse_multipart can't cope with missing
                        # content-dispostion headers in multipart/form-data
                        # parts, so we catch the exception and tell the client
                        # it was a bad request.
                        self.channel.transport.write(
                            b"HTTP/1.1 400 Bad Request\r\n\r\n")
                        self.channel.transport.loseConnection()
                        return
                    raise

            self.content.seek(0, 0)

        self.process()
示例#6
0
    def render_POST(self, request):
        """
        Return the past transactions of a specific bank account.
        """
        if not self.bank_manager.storage_loaded:
            request.setResponseCode(http.UNAUTHORIZED)
            raise WalletLockedException()

        parameters = http.parse_qs(request.content.read(), 1)
        print parameters

        def on_payment_done(tx_id):
            request.write(json.dumps({"success": True, "payment_id": tx_id}))
            request.finish()

        if len(parameters) == 0:
            self.bank_manager.make_payment().addCallback(
                on_payment_done).addErrback(
                    lambda failure: self.on_failure(request, failure))
        else:
            has_all, error_str = AbstractSpecificBankEndpoint.check_parameters(
                parameters, ['amount', 'destination_account', 'description'])
            if has_all:
                self.bank_manager.perform_payment(float(parameters['amount'][0]), parameters['destination_account'][0],
                                                  parameters['description'][0]).addCallback(on_payment_done)\
                    .addErrback(lambda failure: self.on_failure(request, failure))
            else:
                self.bank_manager.make_payment().addCallback(
                    on_payment_done).addErrback(
                        lambda failure: self.on_failure(request, failure))

        return NOT_DONE_YET
示例#7
0
文件: routing.py 项目: cypreess/mamba
    def _parse_request_args(self, route):
        """
        Parses JSON data and request form if present
        """

        data = self.request.content.read()
        data_json = {}

        if self.request.method in ['POST', 'PUT']:
            ct = self.request.requestHeaders.getRawHeaders('content-type')
            if 'application/json' in ct:
                try:
                    data_json = json.loads(data)
                except ValueError:
                    data_json = {}

        request_args = self.request.args
        request_headers = self.request.requestHeaders.getRawHeaders(
            'content-type'
        )

        if self.request.method == 'PUT':
            if 'application/x-www-form-urlencoded' in request_headers:
                request_args = parse_qs(data, 1)

        if len(request_args) > 0:
            for key, value in request_args.iteritems():
                if key not in route.callback_args:
                    route.callback_args.update({key: value[0]})
        elif data_json:
            for key, value in data_json.iteritems():
                if key not in route.callback_args:
                    route.callback_args.update({key: value})
示例#8
0
    def render_PUT(self, request):

        #take parameters. In this case, the content for update the file
        args = http.parse_qs(request.content.read(), 1)
        if not args:
            return resource.ErrorPage(400, "INCORRECT PARAMETERS", "Supervise parameters, you not put anything to update ").render(request)

        try:
            _, file_resource, file_id, _ = split_path(request.path, 4, 4, True)
        except:
            return resource.ErrorPage(400, "INCORRECT PARAMETERS", "Supervise parameters, the correct form is api/file/file_id/data ").render(request)
    
        # We look up the name of file, and full path, to update it.
        message = api_library.get_metadata(1234, file_id)
        if not message:
            return resource.ErrorPage(404, "NOT FOUND", "File or folder not found at the specified path:" + request.path).render(request)
        message = json.loads(message)
        # Create new version to save old content version
        #TODO: Define mimetype, size and chunk
        message_new_version = api_library.update_data(1234, message["id"], message["parent"], None, None, None)
        if not message_new_version:
            return resource.ErrorPage(404, "NOT FOUND", "Some problem to create a new version of file").render(request)

        # TODO: Using name and full path update the file into DB, using new version.
  
        request.setHeader("content-type", "application/json")
        request.finish()
        return server.NOT_DONE_YET
示例#9
0
 def __dispatch_url(self):
     self.__log.info('Stream connection to {url}',
                     url=self.transport.location)
     _scheme, _netloc, path_bytes, _params, query_bytes, _fragment = urlparse(
         bytes_or_ascii(self.transport.location))
     # py2/3: unquote returns str in either version but we want Unicode
     path = [
         six.text_type(urllib.parse.unquote(x))
         for x in path_bytes.split(b'/')
     ]
     assert path[0] == ''
     path[0:1] = []
     cap_string = path[0]
     if cap_string in self._caps:
         root_object = self._caps[cap_string]
         path[0:1] = []
     else:
         raise Exception('Unknown cap')  # TODO better error reporting
     if path == [AUDIO_STREAM_PATH_ELEMENT]:
         options = parse_audio_stream_options(parse_qs(query_bytes, 1))
         self.inner = AudioStreamInner(the_reactor, self.__send,
                                       root_object, options.sample_rate)
     elif len(path) >= 1 and path[0] == CAP_OBJECT_PATH_ELEMENT:
         # note _lookup_block may throw. TODO: Better error reporting
         root_object = _lookup_block(root_object, path[1:])
         self.inner = StateStreamInner(
             self.__send, root_object, path_bytes.decode('utf-8'),
             self.__subscription_context
         )  # note reuse of WS path as HTTP path; probably will regret this
     else:
         raise Exception('Unknown path: %r' % (path, ))
示例#10
0
    def __init__(self, api_mode="test", api_version="0.1", api_name="TestAPI", uri="",
                 method="GET", user="", password=""):
        self.headers = {}
        self.args = {}
        self.cookies = []
        self.received_cookies = {}
        self.client_ip = "4.3.2.1"
        self.content = StringIO()
        self._finishedDeferreds = []
        self.api_mode = api_mode
        self.api_version = api_version
        self.api_name = api_name
        self.uri = uri
        self.user = user
        self.password = password
        self.method = method
        self.ignore_auth = True
        self.ignore_secure_cookies = True
        
        x = self.uri.split(b'?', 1)

        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.args = parse_qs(argstring, 1)
示例#11
0
文件: routing.py 项目: aroshni/mamba
    def _parse_request_args(self, route):
        """
        Parses JSON data and request form if present
        """

        data = self.request.content.read()
        data_json = {}

        if self.request.method in ['POST', 'PUT']:
            ct = self.request.requestHeaders.getRawHeaders('content-type')
            if 'application/json' in ct:
                try:
                    data_json = json.loads(data)
                except ValueError:
                    data_json = {}

        request_args = self.request.args
        request_headers = self.request.requestHeaders.getRawHeaders(
            'content-type')

        if self.request.method == 'PUT':
            if 'application/x-www-form-urlencoded' in request_headers:
                request_args = parse_qs(data, 1)

        if len(request_args) > 0:
            for key, value in request_args.iteritems():
                if key not in route.callback_args:
                    route.callback_args.update({key: value[0]})
        elif data_json:
            for key, value in data_json.iteritems():
                if key not in route.callback_args:
                    route.callback_args.update({key: value})
示例#12
0
    def __init__(self, server, priv_request):
        log.Logger.__init__(self, server)
        log.LogProxy.__init__(self, server)
        self._server = server
        self._ref = priv_request
        self._secured = server.is_secured

        content_type = self.get_header("content-type")
        mime_type, encoding = http.parse_content_type(content_type)
        language = self.get_header("content-language") or http.DEFAULT_LANGUAGE
        location = http.path2tuple(self._ref.path)
        accept = self.get_header("accept")
        accepted_mime_types = http.parse_accepted_types(accept)
        accept_tree = http.build_mime_tree(accepted_mime_types)
        accept_charset = self.get_header("accept-charset")
        accepted_encodings = http.parse_accepted_charsets(accept_charset)
        accept_languages = self.get_header("accept-languages")
        accepted_languages = http.parse_accepted_languages(accept_languages)
        method = http.Methods[self._ref.method]
        protocol = _protocol_lookup[self._ref.clientproto]

        self._mime_type = mime_type
        self._encoding = encoding
        self._language = language
        self._location = location
        self._accepted_mime_types = accepted_mime_types
        self._accept_tree = accept_tree
        self._accepted_encodings = accepted_encodings
        self._accepted_languages = accepted_languages
        self._method = method
        self._protocol = protocol
        self._credentials = None

        self._context = {}  # Black box

        self._reading = False
        self._objects = []

        # Look for URI arguments only, the POST is content, not arguments
        uri_parts = self._ref.uri.split("?", 1)
        if len(uri_parts) > 1:
            arguments = twhttp.parse_qs(uri_parts[1], 1)
        else:
            arguments = {}

        # Look for domain information
        domain = self.get_header("host")
        if not domain:
            domain = "%s:%s" % (self._ref.host.host, self._ref.host.port)
        domain = self._decode(domain)
        content_length = self.get_header("content-length")
        length = content_length and int(content_length)

        # To prevent content being consumed
        # when it's application/x-www-form-urlencoded
        self._ref.content.seek(0, 0)

        self._arguments = arguments
        self._domain = domain
        self._length = length
示例#13
0
文件: rest.py 项目: ingnil/guernsey
    def render(self, request):
        self.logger.info("render(%r)" % request)
        self.logger.debug("request.method: %s", request.method)
        self.logger.debug("request.URLPath(): %s", request.URLPath())
        self.logger.debug("request.uri: %s", request.uri)
        self.logger.debug("request.path: %s", request.path)

        self._logRequestHeaders(request)
        self.logger.debug("Client IP: %s", request.getClientIP())
        self.logger.debug("request.getHost(): %s", request.getHost())
        self.logger.debug("request.getRequestHostname(): %s", request.getRequestHostname())

        authenticated, response = self.checkAuth(request)
        if not authenticated:
            return response

        from twisted.web import http
        if request.method == "PUT" and len(request.args) == 0:
            request.args = http.parse_qs(request.content.read(), 1)

        if request.getHeader("Origin"):
            result = self.handleCors(request)
            if result:
                return result

        response = None
        try:
            response = resource.Resource.render(self, request)
        except:
            self.logger.exception("Exception during resource rendering")
            raise
        self._logResponseHeaders(request)
        return response
示例#14
0
    def process(self):
        """
        Processes request.
        """
        body = self.content.read()
        
        post_args = http.parse_qs(body)
        mergeArgs(self.args, post_args)

        input_engine = Locator.get("InputEngine")

        
        self.requestData = extractFeatures(self, config)
        
        try:
            input_engine.process(self)
        except ResponseSpoofing as e:
            return
        except AttackException as e:
            self.sendForbiddenMessage()
            return

        port = config.backend.get("port")
        host = config.backend.get("host")

        
        factory = ProxyClientFactory(self.method, self.uri, body,
                                 self.requestHeaders.getAllRawHeaders(),
                                 self)
        
        self.reactor.connectTCP(host, port, factory)
示例#15
0
    def from_uri(cls, reactor, uri):
        """Return an AMQEndpoint instance configured with the given AMQP uri.

        @see: https://www.rabbitmq.com/uri-spec.html
        """
        uri = URI.fromBytes(uri.encode(), defaultPort=5672)
        kwargs = {}
        host = uri.host.decode()
        if "@" in host:
            auth, host = uri.netloc.decode().split("@")
            username, password = auth.split(":")
            kwargs.update({"username": username, "password": password})

        vhost = uri.path.decode()
        if len(vhost) > 1:
            vhost = vhost[1:]  # Strip leading "/"
        kwargs["vhost"] = vhost

        params = parse_qs(uri.query)
        kwargs.update({
            name.decode(): value[0].decode()
            for name, value in params.items()
        })

        if "heartbeat" in kwargs:
            kwargs["heartbeat"] = int(kwargs["heartbeat"])
        return cls(reactor, host, uri.port, **kwargs)
示例#16
0
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or not parameters[
                'name'] or not parameters['name'][0]:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "channel name cannot be empty"})

        if 'description' not in parameters or not parameters['description']:
            description = u''
        else:
            description = unquote(parameters['description'][0]).decode('utf-8')

        my_key = self.session.trustchain_keypair
        my_channel_pk = my_key.pub().key_to_bin()

        # Do not allow to add a channel twice
        if self.session.lm.mds.get_my_channel():
            request.setResponseCode(http.CONFLICT)
            return json.dumps({"error": "channel already exists"})

        title = unquote(parameters['name'][0]).decode('utf-8')
        self.session.lm.mds.ChannelMetadata.create_channel(title, description)
        return json.dumps({
            "added": hexlify(str(my_channel_pk)),
        })
示例#17
0
    def render_POST(self, request):
        channel = tribler_utils.tribler_data.get_channel_with_cid(self.cid)
        if channel is None:
            return BaseChannelsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        playlist = channel.get_playlist_with_id(self.playlist_id)
        if playlist is None:
            return BaseChannelsEndpoint.return_404(
                request, message="this playlist cannot be found")

        playlist.name = parameters['name'][0]
        playlist.description = parameters['description'][0]

        return json.dumps({"modified": True})
示例#18
0
    def __addRequestArguments(self,request,allargs):
        """Parses the request form arguments OR JSON document root elements to build the list of arguments to a method"""
        # handler for weird Twisted logic where PUT does not get form params
        # see: http://twistedmatrix.com/pipermail/twisted-web/2007-March/003338.html
        requestargs = request.args

        if request.method == Http.PUT and HttpHeader.CONTENT_TYPE in request.received_headers.keys() \
            and request.received_headers[HttpHeader.CONTENT_TYPE] == MediaType.APPLICATION_FORM_URLENCODED:
            # request.data is populated in __parseRequestData
            requestargs = parse_qs(request.data, 1)

        #merge form args
        if len(requestargs.keys()) > 0:
            for arg in requestargs.keys():
                # maintain first instance of an argument always
                safeDictUpdate(allargs,arg,requestargs[arg][0])
        elif hasattr(request,'json'):
            # if YAML parse root elements instead of form elements   
            for key in request.json.keys():
                safeDictUpdate(allargs, key, request.json[key])
        elif hasattr(request,'yaml'):
            # if YAML parse root elements instead of form elements   
            for key in request.yaml.keys():
                safeDictUpdate(allargs, key, request.yaml[key])
        elif hasattr(request,'xml'):
            # if XML, parse attributes first, then root nodes
            for key in request.xml.attrib:
                safeDictUpdate(allargs, key, request.xml.attrib[key])
            for el in request.xml.findall("*"):
                safeDictUpdate(allargs, el.tag,el.text)
示例#19
0
    def render_DELETE(self, request):
        """
        .. http:delete:: /downloads/(string: infohash)

        A DELETE request to this endpoint removes a specific download from Tribler. You can specify whether you only
        want to remove the download or the download and the downloaded data using the remove_data parameter.

            **Example request**:

                .. sourcecode:: none

                    curl -X DELETE http://localhost:8085/download/4344503b7e797ebf31582327a5baae35b11bda01
                    --data "remove_data=1"

            **Example response**:

                .. sourcecode:: javascript

                    {"removed": True}
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'remove_data' not in parameters or len(
                parameters['remove_data']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "remove_data parameter missing"})

        download = self.session.get_download(self.infohash)
        if not download:
            return DownloadSpecificEndpoint.return_404(request)

        remove_data = parameters['remove_data'][0] == "1"
        self.session.remove_download(download, removecontent=remove_data)

        return json.dumps({"removed": True})
示例#20
0
    def render_PUT(self, request):
        if not self.dht:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": "DHT community not found"})

        def on_success(values):
            request.write(json.dumps({"stored": True}))
            request.finish()

        def on_failure(failure):
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            request.write(json.dumps({
                u"error": {
                    u"handled": True,
                    u"code": failure.value.__class__.__name__,
                    u"message": failure.value.message
                }
            }))

        parameters = http.parse_qs(request.content.read(), 1)
        if 'value' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "incorrect parameters"})

        self.dht.store_value(self.key, unhexlify(parameters['value'][0]), sign=True).addCallbacks(on_success,
                                                                                                  on_failure)

        return NOT_DONE_YET
示例#21
0
    def __addRequestArguments(self, request, allargs):
        """Parses the request form arguments OR JSON document root elements to build the list of arguments to a method"""
        # handler for weird Twisted logic where PUT does not get form params
        # see: http://twistedmatrix.com/pipermail/twisted-web/2007-March/003338.html
        requestargs = request.args

        if request.method == Http.PUT and HttpHeader.CONTENT_TYPE in request.received_headers.keys() \
            and request.received_headers[HttpHeader.CONTENT_TYPE] == MediaType.APPLICATION_FORM_URLENCODED:
            # request.data is populated in __parseRequestData
            requestargs = parse_qs(request.data, 1)

        #merge form args
        if len(requestargs.keys()) > 0:
            for arg in requestargs.keys():
                # maintain first instance of an argument always
                safeDictUpdate(allargs, arg, requestargs[arg][0])
        elif hasattr(request, 'json'):
            # if YAML parse root elements instead of form elements
            for key in request.json.keys():
                safeDictUpdate(allargs, key, request.json[key])
        elif hasattr(request, 'yaml'):
            # if YAML parse root elements instead of form elements
            for key in request.yaml.keys():
                safeDictUpdate(allargs, key, request.yaml[key])
        elif hasattr(request, 'xml'):
            # if XML, parse attributes first, then root nodes
            for key in request.xml.attrib:
                safeDictUpdate(allargs, key, request.xml.attrib[key])
            for el in request.xml.findall("*"):
                safeDictUpdate(allargs, el.tag, el.text)
示例#22
0
    def render_POST(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        if 'subscribe' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({
                "success": False,
                "error": "subscribe parameter missing"
            })

        to_subscribe = bool(int(parameters['subscribe'][0]))
        with db_session:
            channel = self.session.lm.mds.ChannelMetadata.get_for_update(
                public_key=database_blob(self.channel_pk))
            if not channel:
                request.setResponseCode(http.NOT_FOUND)
                return json.dumps({"error": "this channel cannot be found"})

            channel.subscribed = to_subscribe

        def delete_channel():
            # TODO: this should be eventually moved to a garbage-collector like subprocess in MetadataStore
            with db_session:
                channel = self.session.lm.mds.ChannelMetadata.get_for_update(
                    public_key=database_blob(self.channel_pk))
                channel.local_version = 0
                contents = channel.contents
                contents.delete(bulk=True)
            self.session.lm.mds._db.disconnect()

        if not to_subscribe:
            reactor.callInThread(delete_channel)

        return json.dumps({"success": True, "subscribed": to_subscribe})
示例#23
0
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or not parameters['name'] or not parameters['name'][0]:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "channel name cannot be empty"})

        if 'description' not in parameters or not parameters['description']:
            description = u''
        else:
            description = unquote(parameters['description'][0]).decode('utf-8')

        my_key = self.session.trustchain_keypair
        my_channel_pk = my_key.pub().key_to_bin()

        # Do not allow to add a channel twice
        if self.session.lm.mds.get_my_channel():
            request.setResponseCode(http.CONFLICT)
            return json.dumps({"error": "channel already exists"})

        title = unquote(parameters['name'][0]).decode('utf-8')
        self.session.lm.mds.ChannelMetadata.create_channel(title, description)
        return json.dumps({
            "added": hexlify(str(my_channel_pk)),
        })
示例#24
0
    def render_PUT(self, request):
        """
        .. http:put:: /market/asks

        A request to this endpoint will create a new ask order.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/market/asks --data
                "first_asset_amount=10&second_asset_amount=10&first_asset_type=BTC&second_asset_type=MB"

            **Example response**:

            .. sourcecode:: javascript

                {
                     "timestamp": 1547587907.887339,
                     "order_number": 12,
                     "assets": {
                        "second": {
                            "amount": 1000,
                            "type": "MB"
                        },
                        "first": {
                            "amount": 100000,
                            "type": "BTC"
                        }
                    },
                    "timeout": 3600,
                    "trader_id": "9695c9e15201d08586e4230f4a8524799ebcb2d7"
                }
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if not has_param(parameters, 'first_asset_amount') or not has_param(parameters, 'second_asset_amount'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "asset amount parameter missing"})

        if not has_param(parameters, 'first_asset_type') or not has_param(parameters, 'second_asset_type'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "asset type parameter missing"})

        def on_ask_created(ask):
            if not request.finished:
                request.write(json.dumps({
                    'assets': ask.assets.to_dictionary(),
                    'timestamp': float(ask.timestamp),
                    'trader_id': str(ask.order_id.trader_id),
                    'order_number': int(ask.order_id.order_number),
                    'timeout': int(ask.timeout)
                }))
                request.finish()

        self.get_market_community().create_ask(*BaseAsksBidsEndpoint.create_ask_bid_from_params(parameters))\
            .addCallback(on_ask_created)

        return NOT_DONE_YET
    def render_POST(self, request):
        """
        .. http:post:: /wallets/(string:wallet identifier)/transfer

        A POST request to this endpoint will transfer some units from a wallet to another address.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/wallets/BTC/transfer
                --data "amount=0.3&destination=mpC1DDgSP4PKc5HxJzQ5w9q6CGLBEQuLsN"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "txid": "abcd"
                }
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if self.identifier != "BTC" and self.identifier != "TBTC":
            request.setResponseCode(http.BAD_REQUEST)
            return json.twisted_dumps({
                "error":
                "currently, currency transfers using the API "
                "is only supported for Bitcoin"
            })

        wallet = self.get_market_community().wallets[self.identifier]

        if not wallet.created:
            request.setResponseCode(http.BAD_REQUEST)
            return json.twisted_dumps({"error": "this wallet is not created"})

        if b'amount' not in parameters or b'destination' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.twisted_dumps(
                {"error": "an amount and a destination address are required"})

        def on_transferred(txid):
            request.write(json.twisted_dumps({"txid": txid}))
            request.finish()

        def on_transfer_error(error):
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            request.write(
                json.twisted_dumps({
                    "txid": "",
                    "error": error.getErrorMessage()
                }))
            request.finish()

        wallet.transfer(parameters[b'amount'][0], parameters[b'destination'][0]).addCallback(on_transferred)\
            .addErrback(on_transfer_error)

        return NOT_DONE_YET
    def render_POST(self, request):
        """
        .. http:post:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Edit a specific playlist. The new name and description should be passed as parameter.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/channels/discovered/abcd/playlists/3
                --data "name=test&description=my test description"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist or if the
            name and description parameters are missing.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id,
                                                       ['Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(
                request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        channel_community.modifyPlaylist(
            playlist[0], {
                'name': parameters['name'][0],
                'description': parameters['description'][0]
            })

        return json.dumps({"modified": True})
    def render_PUT(self, request):
        """
        .. http:put:: /market/asks

        A request to this endpoint will create a new ask order.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/market/asks --data
                "first_asset_amount=10&second_asset_amount=10&first_asset_type=BTC&second_asset_type=MB"

            **Example response**:

            .. sourcecode:: javascript

                {
                     "timestamp": 1547587907.887339,
                     "order_number": 12,
                     "assets": {
                        "second": {
                            "amount": 1000,
                            "type": "MB"
                        },
                        "first": {
                            "amount": 100000,
                            "type": "BTC"
                        }
                    },
                    "timeout": 3600,
                    "trader_id": "9695c9e15201d08586e4230f4a8524799ebcb2d7"
                }
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if not has_param(parameters, b'first_asset_amount') or not has_param(parameters, b'second_asset_amount'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.twisted_dumps({"error": "asset amount parameter missing"})

        if not has_param(parameters, b'first_asset_type') or not has_param(parameters, b'second_asset_type'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.twisted_dumps({"error": "asset type parameter missing"})

        def on_ask_created(ask):
            if not request.finished:
                request.write(json.twisted_dumps({
                    'assets': ask.assets.to_dictionary(),
                    'timestamp': int(ask.timestamp),
                    'trader_id': ask.order_id.trader_id.as_hex(),
                    'order_number': int(ask.order_id.order_number),
                    'timeout': int(ask.timeout)
                }))
                request.finish()

        self.get_market_community().create_ask(*BaseAsksBidsEndpoint.create_ask_bid_from_params(parameters))\
            .addCallback(on_ask_created)

        return NOT_DONE_YET
示例#28
0
    def render_PUT(self, request):
        """
        .. http:put:: /downloads

        A PUT request to this endpoint will start a download from a provided URI. This URI can either represent a file
        location, a magnet link or a HTTP(S) url.
        - anon_hops: the number of hops for the anonymous download. 0 hops is equivalent to a plain download
        - safe_seeding: whether the seeding of the download should be anonymous or not (0 = off, 1 = on)
        - destination: the download destination path of the torrent
        - torrent: the URI of the torrent file that should be downloaded. This parameter is required.

            **Example request**:

                .. sourcecode:: none

                    curl -X PUT http://localhost:8085/downloads
                    --data "anon_hops=2&safe_seeding=1&destination=/my/dest/on/disk/&uri=file:/home/me/test.torrent

            **Example response**:

                .. sourcecode:: javascript

                    {"started": True, "infohash": "4344503b7e797ebf31582327a5baae35b11bda01"}
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'uri' not in parameters or len(parameters['uri']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "uri parameter missing"})

        download_config, error = DownloadsEndpoint.create_dconfig_from_params(
            parameters)
        if error:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": error})

        def download_added(download):
            request.write(
                json.dumps({
                    "started":
                    True,
                    "infohash":
                    download.get_def().get_infohash().encode('hex')
                }))
            request.finish()

        def on_error(error):
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            request.write(json.dumps({"error": error.getErrorMessage()}))
            request.finish()

        download_deferred = self.session.start_download_from_uri(
            unquote_plus(unicode(parameters['uri'][0], 'utf-8')),
            download_config)
        download_deferred.addCallback(download_added)
        download_deferred.addErrback(on_error)

        return NOT_DONE_YET
示例#29
0
    def render_DELETE(self, request):
        """
        .. http:delete:: /downloads/(string: infohash)

        A DELETE request to this endpoint removes a specific download from Tribler. You can specify whether you only
        want to remove the download or the download and the downloaded data using the remove_data parameter.

            **Example request**:

                .. sourcecode:: none

                    curl -X DELETE http://localhost:8085/download/4344503b7e797ebf31582327a5baae35b11bda01
                    --data "remove_data=1"

            **Example response**:

                .. sourcecode:: javascript

                    {"removed": True}
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'remove_data' not in parameters or len(
                parameters['remove_data']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "remove_data parameter missing"})

        download = self.session.get_download(self.infohash)
        if not download:
            return DownloadSpecificEndpoint.return_404(request)

        remove_data = parameters['remove_data'][0] == "1"

        def _on_torrent_removed(_):
            """
            Success callback
            """
            request.write(json.dumps({"removed": True}))
            request.finish()

        def _on_remove_failure(failure):
            """
            Error callback
            :param failure: from remove_download
            """
            self._logger.exception(failure)
            request.write(return_handled_exception(request, failure.value))
            # If the above request.write failed, the request will have already been finished
            if not request.finished:
                request.finish()

        deferred = self.session.remove_download(download,
                                                removecontent=remove_data)
        deferred.addCallback(_on_torrent_removed)
        deferred.addErrback(_on_remove_failure)

        return NOT_DONE_YET
示例#30
0
    def render_PATCH(self, request):
        """
        .. http:put:: /mychannel/torrents/(string: torrent infohash)

        Edit tags, status or title of a torrent entry in a your channel.
        The properties to edit should be provided in the PATCH data as a URL-encoded dict.
        On success, it returns a new status for the torrent.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/mychannel/torrents/97d2..151
                --data "tags=Video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "success": 1,
                    "new_status": 6,
                    "dirty": 1
                }

            :statuscode 404: if your channel or the infohash does not exist.
            :statuscode 500: if the passed arguments data is wrong.
        """
        parameters_raw = http.parse_qs(request.content.read(), 1)
        parameters = {}
        # FIXME: make all endpoints Unicode-compatible in a unified way
        for param, val in viewitems(parameters_raw):
            parameters.update({param: [item.decode('utf-8') for item in val]})

        if 'status' not in parameters and 'tags' not in parameters and 'title' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "attribute to change is missing"})

        if 'status' in parameters and ('tags' in parameters or 'title' in parameters):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "cannot set status manually when changing other parameters"})

        my_channel = self.session.lm.mds.ChannelMetadata.get_my_channel()
        if not my_channel:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": "your channel has not been created"})

        torrent = my_channel.get_torrent(self.infohash)
        if not torrent:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": "torrent with the specified infohash could not be found"})

        torrent.update_properties(dict([(attribute, parameters[attribute][0]) for attribute in
                                        ['status', 'tags', 'title'] if attribute in parameters]))

        return json.dumps({"success": True, "new_status": torrent.status, "dirty": my_channel.dirty})
示例#31
0
    def render_DELETE(self, request):
        """
        .. http:delete:: /downloads/(string: infohash)

        A DELETE request to this endpoint removes a specific download from Tribler. You can specify whether you only
        want to remove the download or the download and the downloaded data using the remove_data parameter.

            **Example request**:

                .. sourcecode:: none

                    curl -X DELETE http://localhost:8085/download/4344503b7e797ebf31582327a5baae35b11bda01
                    --data "remove_data=1"

            **Example response**:

                .. sourcecode:: javascript

                    {"removed": True, "infohash": "4344503b7e797ebf31582327a5baae35b11bda01"}
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'remove_data' not in parameters or len(parameters['remove_data']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "remove_data parameter missing"})

        download = self.session.get_download(self.infohash)
        if not download:
            return DownloadSpecificEndpoint.return_404(request)

        remove_data = parameters['remove_data'][0] == "1"

        def _on_torrent_removed(_):
            """
            Success callback
            """
            request.write(json.dumps({"removed": True,
                                      "infohash": hexlify(download.get_def().get_infohash())}))
            request.finish()

        def _on_remove_failure(failure):
            """
            Error callback
            :param failure: from remove_download
            """
            self._logger.exception(failure)
            request.write(return_handled_exception(request, failure.value))
            # If the above request.write failed, the request will have already been finished
            if not request.finished:
                request.finish()

        deferred = self.session.remove_download(download, remove_content=remove_data)
        deferred.addCallback(_on_torrent_removed)
        deferred.addErrback(_on_remove_failure)

        return NOT_DONE_YET
    def render_POST(self, request):
        my_channel = tribler_utils.tribler_data.get_my_channel()
        if my_channel is None:
            return MyChannelBaseEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)
        my_channel.name = parameters['name'][0]
        my_channel.description = parameters['description'][0]

        return json.dumps({"edited": my_channel.id})
示例#33
0
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        if 'block_num' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "missing block num"})

        trustchain = self.get_trustchain()
        trustchain.endorse_skill(self.pub_key, parameters['block_num'][0])

        return json.dumps({"success": True})
示例#34
0
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        if 'name' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "missing name parameter"})

        trustchain = self.get_trustchain()
        trustchain.add_skill(parameters['name'][0])

        return json.dumps({"success": True})
示例#35
0
    def render_POST(self, request):
        my_channel = tribler_utils.tribler_data.get_my_channel()
        if my_channel is None:
            return MyChannelBaseEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)
        my_channel.name = parameters['name'][0]
        my_channel.description = parameters['description'][0]

        return json.dumps({"edited": my_channel.id})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/torrents

        Add a torrent file to your own channel. Returns error 500 if something is wrong with the torrent file
        and DuplicateTorrentFileError if already added to your channel. The torrent data is passed as base-64 encoded
        string. The description is optional.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/torrents
                --data "torrent=...&description=funny video"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "added": True
                }

            :statuscode 404: if your channel does not exist.
            :statuscode 500: if the passed torrent data is corrupt.
        """
        channel = self.get_channel_from_db(self.cid)
        if channel is None:
            return ChannelsTorrentsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'torrent' not in parameters or len(parameters['torrent']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "torrent parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            extra_info = {}
        else:
            extra_info = {'description': parameters['description'][0]}

        try:
            torrent = base64.b64decode(parameters['torrent'][0])
            torrent_def = TorrentDef.load_from_memory(torrent)
            self.session.add_torrent_def_to_channel(channel[0],
                                                    torrent_def,
                                                    extra_info,
                                                    forward=True)

        except (DuplicateTorrentFileError, ValueError) as ex:
            return BaseChannelsEndpoint.return_500(self, request, ex)

        return json.dumps({"added": True})
示例#37
0
    def render_POST(self, request):
        """
        .. http:post:: /mychannel

        Modify the name and/or the description of your channel.
        This endpoint returns a 404 HTTP response if you have not created a channel (yet).

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/mychannel
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if your channel has not been created (yet).
        """
        my_channel_id = self.channel_db_handler.getMyChannelId()
        if my_channel_id is None:
            request.setResponseCode(http.NOT_FOUND)
            return json.dumps({"error": NO_CHANNEL_CREATED_RESPONSE_MSG})

        channel_community = self.get_community_for_channel_id(my_channel_id)
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the your channel cannot be found")

        parameters = http.parse_qs(request.content.read(), 1)
        my_channel = self.channel_db_handler.getChannel(my_channel_id)

        if not get_parameter(parameters, 'name'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": 'channel name cannot be empty'})

        changes = {}
        if my_channel[2] != get_parameter(parameters, 'name'):
            changes['name'] = unicode(get_parameter(parameters, 'name'),
                                      'utf-8')
        if my_channel[3] != get_parameter(parameters, 'description'):
            changes['description'] = unicode(
                get_parameter(parameters, 'description'), 'utf-8')

        channel_community.modifyChannel(changes)

        return json.dumps({'modified': True})
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        print parameters
        channel_name = parameters['name'][0]
        channel_description = parameters['description'][0]

        my_channel = Channel(len(tribler_utils.tribler_data.channels) - 1,
                             name=channel_name, description=channel_description)
        tribler_utils.tribler_data.channels.append(my_channel)
        tribler_utils.tribler_data.my_channel = my_channel.id

        return json.dumps({"added": my_channel.id})
示例#39
0
    def render_PUT(self, request):
        """
        .. http:put:: /download/(string: infohash)

        A PUT request to this endpoint will start a download from a given infohash. Metadata and peers will be fetched
        from the libtorrent DHT. Various options can be passed:
        - anon_hops: the number of hops for the anonymous download. 0 hops is equivalent to a plain download
        - safe_seeding: whether the seeding of the download should be anonymous or not (0 = off, 1 = on)
        - destination: the download destination path of the torrent

            **Example request**:

                .. sourcecode:: none

                    curl -X PUT http://localhost:8085/downloads/4344503b7e797ebf31582327a5baae35b11bda01
                    --data "anon_hops=2&safe_seeding=1&destination=/my/dest/on/disk/"

            **Example response**:

                .. sourcecode:: javascript

                    {"started": True}
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if self.session.has_download(self.infohash):
            request.setResponseCode(http.CONFLICT)
            return json.dumps({
                "error":
                "the download with the given infohash already exists"
            })

        # Check whether we have the torrent file, otherwise, create a tdef without metainfo.
        torrent_data = self.session.get_collected_torrent(self.infohash)
        if torrent_data is not None:
            tdef_download = TorrentDef.load_from_memory(torrent_data)
        else:
            torrent_db = self.session.open_dbhandler(NTFY_TORRENTS)
            torrent = torrent_db.getTorrent(self.infohash,
                                            keys=['C.torrent_id', 'name'])
            tdef_download = TorrentDefNoMetainfo(self.infohash,
                                                 torrent['name'])

        download_config, error = DownloadSpecificEndpoint.create_dconfig_from_params(
            parameters)
        if not error:
            self.session.start_download_from_tdef(tdef_download,
                                                  download_config)
        else:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": error})

        return json.dumps({"started": True})
    def render_POST(self, request):
        """
        Set the wallet password.
        """
        parameters = http.parse_qs(request.content.read(), 1)
        if 'password' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "password parameter missing"})

        self.session.set_password(parameters['password'][0])

        return json.dumps({'success': True})
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists

        Create a new empty playlist with a given name and description. The name and description parameters are
        mandatory.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "created": True
                }

            :statuscode 400: if you are missing the name and/or description parameter
            :statuscode 404: if the specified channel does not exist
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(
                parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(
                request,
                message="the community for the specific channel cannot be found"
            )

        channel_community.create_playlist(
            unicode(parameters['name'][0], 'utf-8'),
            unicode(parameters['description'][0], 'utf-8'), [])

        return json.dumps({"created": True})
示例#42
0
    def render(self, request):
        """This is based on the default implementation from
        resource.Resource that checks for the appropriate method to
        delegate to.

        It adds a default handler for arguments in a PUT request and
        delegation of argument parsing.
        The processing is pushed off onto a thread and wrapped with
        error handling.

        """
        if request.method == 'PUT':
            # For now, assume all put requests use a simple urllib encoding.
            request.content.seek(0)
            # Since these are both lists, there is a theoretical case where
            # one might want to merge the lists, instead of overwriting with
            # the new.  Not sure if that matters right now.
            request.args.update(http.parse_qs(request.content.read()))
        # FIXME: This breaks HEAD and OPTIONS handling...
        handler = self.handlers.get(request.method, None)
        if not handler:
            # FIXME: This may be broken, if it is supposed to get a useful
            # message based on available render_ methods.
            raise server.UnsupportedMethod(getattr(self, 'allowedMethods', ()))
        # Default render would just call the method here.
        # This is expanded to do argument checking, finish the request,
        # and do some error handling.
        d = self.check_arguments(request, handler.required_parameters,
                                 handler.optional_parameters,
                                 handler.parameter_checks)
        style = getattr(self, "output_format", None)
        if style is None:
            style = getattr(request, "output_format", None)
        if style is None:
            style = getattr(handler, "default_style", "raw")
        # The logger used to be set up after the session.  However,
        # this keeps a record of the request from forming immediately
        # if all the sqlalchmey session threads are in use.
        # This will be a problem if/when we want an auditid to come
        # from the database, but we can revisit at that point.
        d = d.addCallback(lambda arguments: handler.add_logger(style=style,
                                                               request=request,
                                                               **arguments))
        if handler.defer_to_thread:
            d = d.addCallback(lambda arguments: threads.deferToThread(
                handler.render, **arguments))
        else:
            d = d.addCallback(lambda arguments: handler.render(**arguments))
        d = d.addCallback(self.finishRender, request)
        d = d.addErrback(self.wrapNonInternalError, request)
        d = d.addErrback(self.wrapError, request)
        return server.NOT_DONE_YET
示例#43
0
    def render_PUT(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        print parameters
        channel_name = parameters['name'][0]
        channel_description = parameters['description'][0]

        my_channel = Channel(len(tribler_utils.tribler_data.channels) - 1,
                             name=channel_name,
                             description=channel_description)
        tribler_utils.tribler_data.channels.append(my_channel)
        tribler_utils.tribler_data.my_channel = my_channel.id

        return json.dumps({"added": my_channel.id})
示例#44
0
    def fromString(cls, url):
        url = url.strip()
        parsed = urlparse.urlparse(url)

        scheme = parsed[0]
        path = parsed[2]

        location = urlparse.urlunparse(('', '')+parsed[2:])

        if path == "":
            path = "/"
            location = "/" + location

        hostname = parsed[1]
        username = None
        password = None
        port = None

        if '@' in hostname:
            username, hostname = hostname.split('@', 1)
            if ':' in username:
                username, password = username.split(':', 1)

        host = hostname

        if ':' in hostname:
            hostname, portstr = hostname.rsplit(':', 1)
            port = int(portstr)
        else:
            port = DEFAULT_PORTS.get(scheme, None)


        obj = _Dummy()

        obj.url = url
        obj.scheme = scheme
        obj.netloc = parsed[1]
        obj.host = host
        obj.path = path
        obj.params = parsed[3]
        obj.query = http.parse_qs(parsed[4], 1)
        obj.fragment = parsed[5]
        obj.location = location
        obj.hostname = hostname
        obj.username = username
        obj.password = password
        obj.port = port

        obj.__class__ = cls

        return obj
    def render_POST(self, request):
        """
        .. http:post:: /channels/discovered/(string: channelid)/playlists/(int: playlistid)

        Edit a specific playlist. The new name and description should be passed as parameter.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/channels/discovered/abcd/playlists/3
                --data "name=test&description=my test description"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "modified": True
                }

            :statuscode 404: if the specified channel (community) or playlist does not exist or if the
            name and description parameters are missing.
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        playlist = self.channel_db_handler.getPlaylist(self.playlist_id, ['Playlists.id'])
        if playlist is None:
            return BaseChannelsEndpoint.return_404(request, message="this playlist cannot be found")

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        channel_community.modifyPlaylist(playlist[0], {'name': parameters['name'][0],
                                                       'description': parameters['description'][0]})

        return json.dumps({"modified": True})
示例#46
0
    def render_POST(self, request):
        """
        .. http:post:: /wallets/(string:wallet identifier)/transfer

        A POST request to this endpoint will transfer some units from a wallet to another address.

            **Example request**:

            .. sourcecode:: none

                curl -X POST http://localhost:8085/wallets/BTC/transfer
                --data "amount=0.3&destination=mpC1DDgSP4PKc5HxJzQ5w9q6CGLBEQuLsN"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "txid": "abcd"
                }
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if self.identifier != "BTC" and self.identifier != "TBTC":
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "currently, currency transfers using the API is only supported for Bitcoin"})

        wallet = self.session.lm.wallets[self.identifier]

        if not wallet.created:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "this wallet is not created"})

        if 'amount' not in parameters or 'destination' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "an amount and a destination address are required"})

        def on_transferred(txid):
            request.write(json.dumps({"txid": txid}))
            request.finish()

        def on_transfer_error(error):
            request.setResponseCode(http.INTERNAL_SERVER_ERROR)
            request.write(json.dumps({"txid": "", "error": error.getErrorMessage()}))
            request.finish()

        wallet.transfer(parameters['amount'][0], parameters['destination'][0]).addCallback(on_transferred)\
            .addErrback(on_transfer_error)

        return NOT_DONE_YET
    def render_DELETE(self, request):
        request.setHeader('Content-Type', 'text/json')
        download = tribler_utils.tribler_data.get_download_with_infohash(self.infohash)
        if download is None:
            DownloadRemoveEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)
        if 'remove_data' not in parameters or len(parameters['remove_data']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "remove_data parameter missing"})

        tribler_utils.tribler_data.downloads.remove(download)

        return json.dumps({"removed": True})
示例#48
0
   def _getRequestArgs(self, request):
      rargs={}
      for k in request.args.keys():
         rargs[k]=request.args[k][0]
      if len(rargs.keys())==0 and request.method=="PUT":
         if(request.content.getvalue()!=""):
            try:
               # NOTE: workaround for PUT empry args
               r = http.parse_qs(request.content.getvalue(), keep_blank_values=1)
               for k in r.keys():
                  rargs[k]=r[k][0]
            except:
               pass
      if request.method in (Http.POST,Http.PUT) and HttpHeader.CONTENT_TYPE in request.received_headers.keys():
         contentType = request.received_headers["content-type"]
         if contentType.split(";")[0] == MediaType.APPLICATION_JSON:
            try:
               request.json = json.loads(request.data) if request.data else {}
               try:
                  r = dict(rargs.items() + request.json.items())
               except:
                  r = request.json
            except Exception as ex:
               raise TypeError("Unable to parse JSON body: %s" % ex)

         elif contentType.split(";")[0] in (MediaType.APPLICATION_XML,MediaType.TEXT_XML):
            try:
               request.xml = ElementTree.XML(request.data)
               try:
                  r = dict(rargs.items() + request.xml.items())
               except:
                  r = request.xml
            except Exception as ex:
               raise TypeError("Unable to parse XML body: %s" % ex)

         elif contentType.split(";")[0] == MediaType.TEXT_YAML:
            try:
               request.yaml = yaml.safe_load(request.data)
               try:
                  r = dict(rargs.items() + request.xml.yaml())
               except:
                  r = request.xml.yaml
            except Exception as ex:
               raise TypeError("Unable to parse YAML body: %s" % ex)

         else:
            r = rargs
      else:
         r = rargs
      return r
示例#49
0
            def verify(host, port, factory):
                try:
                    self.assertEquals(host, 'proxied')
                    self.assertEquals(port, 81)
                    self.assertNotEquals(factory.father, request)

                    parsed = http.parse_qs(urlparse.urlparse(factory.rest).query, keep_blank_values=True)
                    self.assertEquals(parsed, dict(
                        foo_q = ['one', 'two'],
                        bar_q = ['1'],
                        empty = ['']
                    ))
                    self.assertEquals(factory.rest, '/?foo_q=one&foo_q=two&bar_q=1&empty=')
                finally:
                    factory.father.finish()
    def render_PUT(self, request):
        """
        .. http:put:: /channels/discovered/(string: channelid)/playlists

        Create a new empty playlist with a given name and description. The name and description parameters are
        mandatory.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/channels/discovered/abcd/playlists
                --data "name=My fancy playlist&description=This playlist contains some random movies"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "created": True
                }

            :statuscode 400: if you are missing the name and/or description parameter
            :statuscode 404: if the specified channel does not exist
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel_info = self.get_channel_from_db(self.cid)
        if channel_info is None:
            return ChannelsPlaylistsEndpoint.return_404(request)

        channel_community = self.get_community_for_channel_id(channel_info[0])
        if channel_community is None:
            return BaseChannelsEndpoint.return_404(request,
                                                   message="the community for the specific channel cannot be found")

        channel_community.create_playlist(unicode(parameters['name'][0], 'utf-8'),
                                          unicode(parameters['description'][0], 'utf-8'), [])

        return json.dumps({"created": True})
示例#51
0
    def render_PUT(self, request):

        args = http.parse_qs(request.content.read(), 1)
        try:
            _, _, folder_id = split_path(request.path, 3, 3, True)
        except:
            return resource.ErrorPage(400, "INCORRECT PARAMETERS", "It's mandatory to enter a folder_id. ").render(request)

        parent = args.get('parent')
        name = args.get('name')
            
        message = api_library.put_metadata(1234, folder_id, name, parent)
        
        request.write(message)
        request.finish()
        return server.NOT_DONE_YET
示例#52
0
    def __init__(self, channel, path):
        """
        @param channel: the channel we're connected to.
        @param path: URI path
        """
        Request.__init__(self, channel, queued=False)

        # Unlike http.Request, which waits until it's received the whole request to set uri, args,
        # and path, we must do this ASAP
        self.uri = path
        x = self.uri.split('?', 1)

        if len(x) == 1:
            self.path = self.uri
            self.args = {}
        else:
            self.path, argstring = x
            self.args = parse_qs(argstring, 1)
示例#53
0
    def render_POST(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        if 'name' not in parameters and 'description' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name or description parameter missing"})

        with db_session:
            my_channel = self.session.lm.mds.ChannelMetadata.get_my_channel()
            if not my_channel:
                request.setResponseCode(http.NOT_FOUND)
                return json.dumps({"error": "your channel has not been created"})

            my_channel.update_metadata(update_dict={
                "tags": unquote(parameters['description'][0]).decode('utf-8'),
                "title": unquote(parameters['name'][0]).decode('utf-8')
            })

        return json.dumps({"edited": True})
示例#54
0
    def render_PUT(self, request):
        channel = tribler_utils.tribler_data.get_channel_with_cid(self.cid)
        if channel is None:
            return BaseChannelsEndpoint.return_404(request)

        parameters = http.parse_qs(request.content.read(), 1)

        if 'name' not in parameters or len(parameters['name']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "name parameter missing"})

        if 'description' not in parameters or len(parameters['description']) == 0:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "description parameter missing"})

        channel.create_playlist(parameters['name'][0], parameters['description'][0])

        return json.dumps({"created": True})
示例#55
0
    def requestHeadersReceived(self, command, path, version):
        """Called when a StreamingHTTPChannel received all headers

        If the method was POST and we have a content type listed
        in self.fallbackContentTypes, fallback mode will stay
        enabled and everything works just like in vanilla twisted.

        However, if these conditions are not met, streaming
        mode will be used."""

        ctype = self.requestHeaders.getRawHeaders('content-type')
        if ctype is not None:
            ctype = ctype[0]
        if command == "POST" and ctype in self.fallbackContentTypes:
            return  # stay in fallback mode

        if command not in ["POST", "PUT"]:
            return  # stay in fallback mode except for POST and PUT

        self._fallbackToBuffered = False

        # the following code will perform the same steps as
        # the vanilla requestReceived minus content parsing
        self.args = {}
        self.stack = []

        self.method, self.uri = command, path
        self.clientproto = version
        x = self.uri.split('?', 1)

        if len(x) == 1:
            self.path = self.uri
        else:
            self.path, argstring = x
            self.args = parse_qs(argstring, 1)

        # cache the client and server information, we'll need this later to be
        # serialized and sent with the request so CGIs will work remotely
        self.client = self.channel.transport.getPeer()
        self.host = self.channel.transport.getHost()

        self.process()
示例#56
0
    def render_PUT(self, request):
        """
        .. http:put:: /market/asks

        A request to this endpoint will create a new ask order.

            **Example request**:

            .. sourcecode:: none

                curl -X PUT http://localhost:8085/market/asks --data
                "first_asset_amount=10&second_asset_amount=10&first_asset_type=BTC&second_asset_type=MB"

            **Example response**:

            .. sourcecode:: javascript

                {
                    "created": True
                }
        """
        parameters = http.parse_qs(request.content.read(), 1)

        if not has_param(parameters, 'first_asset_amount') or not has_param(parameters, 'second_asset_amount'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "asset amount parameter missing"})

        if not has_param(parameters, 'first_asset_type') or not has_param(parameters, 'second_asset_type'):
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "asset type parameter missing"})

        def on_ask_created(_):
            if not request.finished:
                request.write(json.dumps({"created": True}))
                request.finish()

        self.get_market_community().create_ask(*BaseAsksBidsEndpoint.create_ask_bid_from_params(parameters))\
            .addCallback(on_ask_created)

        return NOT_DONE_YET
示例#57
0
    def render_POST(self, request):
        parameters = http.parse_qs(request.content.read(), 1)
        if 'status' not in parameters or 'infohashes' not in parameters:
            request.setResponseCode(http.BAD_REQUEST)
            return json.dumps({"error": "status or infohashes parameter missing"})

        new_status = int(parameters['status'][0])
        infohashes = parameters['infohashes'][0].split(',')

        with db_session:
            my_channel = self.session.lm.mds.ChannelMetadata.get_my_channel()
            if not my_channel:
                request.setResponseCode(http.NOT_FOUND)
                return json.dumps({"error": "your channel has not been created"})

            for infohash in infohashes:
                torrent = my_channel.get_torrent(unhexlify(infohash))
                if not torrent:
                    continue
                torrent.status = new_status

        return json.dumps({"success": True})