Esempio n. 1
0
    def testXMLRPCbinary(self):
        # CNY-1932
        # Make sure we properly encode and decode XMLRPC Binary objects on the
        # fly
        marshaller = util.XMLRPCMarshaller("utf-8", allow_none=False)
        srcdata = "abc\x80"
        data = marshaller.dumps((srcdata, ))
        self.assertEqual(
            data,
            "<params>\n<param>\n<value><base64>\nYWJjgA==\n</base64></value>\n"
            "</param>\n</params>\n")

        data = util.xmlrpcDump((srcdata, ), methodresponse=True)
        self.assertEqual(
            data, "<?xml version='1.0'?>\n"
            "<methodResponse>\n"
            "<params>\n<param>\n<value><base64>\nYWJjgA==\n</base64></value>\n"
            "</param>\n</params>\n"
            "</methodResponse>\n")

        srcdata = ["abc\x80", util.ProtectedString("abc\x80")]
        data = util.xmlrpcDump((srcdata, ), methodresponse=True)

        sio = StringIO.StringIO(data)
        params, methodname = util.xmlrpcLoad(sio)
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, None)

        # Produce a very large string representation
        srcdata = ["abc\x80"] * 4096
        sio = util.BoundedStringIO()
        util.xmlrpcDump((srcdata, ), methodname="somemethod", stream=sio)
        sio.seek(0)
        params, methodname = util.xmlrpcLoad(sio)
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, 'somemethod')

        sio.seek(0)
        params, methodname = util.xmlrpcLoad(sio.read())
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, 'somemethod')

        # Test a Fault too
        x = util.xmlrpclib.Fault(1001, "blah")
        repr1 = util.xmlrpclib.dumps(x)
        repr2 = util.xmlrpcDump(x)
        self.assertEqual(repr1, repr2)

        try:
            util.xmlrpcLoad(repr1)
        except util.xmlrpclib.Fault, x2:
            self.assertEqual(x.faultCode, x2.faultCode)
            self.assertEqual(x.faultString, x2.faultString)
Esempio n. 2
0
    def testXMLRPCbinary(self):
        # CNY-1932
        # Make sure we properly encode and decode XMLRPC Binary objects on the
        # fly
        marshaller = util.XMLRPCMarshaller("utf-8", allow_none=False)
        srcdata = "abc\x80"
        data = marshaller.dumps((srcdata, ))
        self.assertEqual(data,
            "<params>\n<param>\n<value><base64>\nYWJjgA==\n</base64></value>\n"
            "</param>\n</params>\n")

        data = util.xmlrpcDump((srcdata, ), methodresponse = True)
        self.assertEqual(data,
            "<?xml version='1.0'?>\n"
            "<methodResponse>\n"
            "<params>\n<param>\n<value><base64>\nYWJjgA==\n</base64></value>\n"
            "</param>\n</params>\n"
            "</methodResponse>\n")

        srcdata = ["abc\x80", util.ProtectedString("abc\x80")]
        data = util.xmlrpcDump((srcdata, ), methodresponse = True)

        sio = StringIO.StringIO(data)
        params, methodname = util.xmlrpcLoad(sio)
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, None)

        # Produce a very large string representation
        srcdata = [ "abc\x80" ] * 4096
        sio = util.BoundedStringIO()
        util.xmlrpcDump((srcdata, ), methodname = "somemethod", stream = sio)
        sio.seek(0)
        params, methodname = util.xmlrpcLoad(sio)
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, 'somemethod')

        sio.seek(0)
        params, methodname = util.xmlrpcLoad(sio.read())
        self.assertEqual(params, (srcdata, ))
        self.assertEqual(methodname, 'somemethod')

        # Test a Fault too
        x = util.xmlrpclib.Fault(1001, "blah")
        repr1 = util.xmlrpclib.dumps(x)
        repr2 = util.xmlrpcDump(x)
        self.assertEqual(repr1, repr2)

        try:
            util.xmlrpcLoad(repr1)
        except util.xmlrpclib.Fault, x2:
            self.assertEqual(x.faultCode, x2.faultCode)
            self.assertEqual(x.faultString, x2.faultString)
Esempio n. 3
0
    def _request(self, methodname, params):
        # Call a method on the remote server
        request = util.xmlrpcDump(params, methodname,
            encoding = self.__encoding, allow_none=self.__allow_none)

        response = self.__transport.request(
            self.__host,
            self.__handler,
            request,
            verbose=self.__verbose)

        if len(response) == 1:
            response = response[0]

        return response
Esempio n. 4
0
    def _request(self, methodname, params):
        # Call a method on the remote server
        request = util.xmlrpcDump(params,
                                  methodname,
                                  encoding=self.__encoding,
                                  allow_none=self.__allow_none)

        response = self.__transport.request(self.__host,
                                            self.__handler,
                                            request,
                                            verbose=self.__verbose)

        if len(response) == 1:
            response = response[0]

        return response
Esempio n. 5
0
    def postRpc(self):
        if self.request.content_type != 'text/xml':
            return self._makeError('400 Bad Request',
                    "Unrecognized Content-Type")
        stream = self.request.body_file
        encoding = self.request.headers.get('Content-Encoding', 'identity')
        if encoding == 'deflate':
            stream = util.decompressStream(stream)
            stream.seek(0)
        elif encoding != 'identity':
            return self._makeError('400 Bad Request',
                    "Unrecognized Content-Encoding")

        try:
            params, method = util.xmlrpcLoad(stream)
        except:
            return self._makeError('400 Bad Request',
                    "Malformed XMLRPC request")

        localAddr = '%s:%s' % (socket.gethostname(), self.getLocalPort())
        try:
            request = self.requestFilter.fromWire(params)
        except (TypeError, ValueError, IndexError):
            return self._makeError('400 Bad Request',
                    "Malformed XMLRPC arguments")

        rawUrl = self.request.url
        scheme = self.request.headers.get('X-Conary-Proxy-Target-Scheme')
        if scheme in ('http', 'https'):
            rawUrl = str(URL(rawUrl)._replace(scheme=scheme))

        # Execution phase -- locate and call the target method
        try:
            responseArgs, extraInfo = self.proxyServer.callWrapper(
                    protocol=None,
                    port=None,
                    methodname=method,
                    authToken=self.auth,
                    request=request,
                    remoteIp=self.auth.remote_ip,
                    rawUrl=rawUrl,
                    localAddr=localAddr,
                    protocolString=self.request.http_version,
                    headers=self.request.headers,
                    isSecure=self.isSecure)
        except errors.InsufficientPermission:
            return self._makeError('403 Forbidden', "Insufficient permission")

        rawResponse, headers = responseArgs.toWire(request.version)
        if extraInfo:
            headers['Via'] = proxy.formatViaHeader(localAddr,
                    self.request.http_version, prefix=extraInfo.getVia())
        response = self.responseFactory(headerlist=headers.items())
        response.content_type = 'text/xml'

        # Output phase -- serialize and write the response
        body = util.xmlrpcDump((rawResponse,), methodresponse=1)
        accept = self.request.accept_encoding
        if len(body) > 200 and 'deflate' in accept:
            response.content_encoding = 'deflate'
            response.body = zlib.compress(body, 5)
        else:
            response.body = body

        if (method == 'getChangeSet'
                and request.version >= 71
                and not responseArgs.isException
                and response.status_int == 200
                and responseArgs.result[0]
                and 'multipart/mixed' in list(self.request.accept)
                ):
            return self.inlineChangeset(response, responseArgs, headers)
        else:
            return response
Esempio n. 6
0
    def handleXml(self, authToken):
        contentLength = int(self.headers['Content-Length'])
        sio = util.BoundedStringIO()

        actual = util.copyStream(self.rfile, sio, contentLength)
        if contentLength != actual:
            raise Exception(contentLength, actual)

        sio.seek(0)

        encoding = self.headers.get('Content-Encoding', None)
        if encoding == 'deflate':
            sio = util.decompressStream(sio)
            sio.seek(0)

        (params, method) = util.xmlrpcLoad(sio)
        logMe(
            3, "decoded xml-rpc call %s from %d bytes request" %
            (method, contentLength))

        if self.netProxy:
            repos = self.netProxy
        else:
            repos = self.netRepos

        localHost, localPort = self.request.getsockname()[:2]
        if ':' in localHost:
            localHost = '[%s]' % localHost
        localAddr = '%s:%s' % (localHost, localPort)
        request = xmlshims.RequestArgs.fromWire(params)

        if repos is not None:
            try:
                response, extraInfo = repos.callWrapper(
                    protocol='http',
                    port=None,
                    methodname=method,
                    authToken=authToken,
                    request=request,
                    remoteIp=self.connection.getpeername()[0],
                    rawUrl=self.path,
                    localAddr=localAddr,
                    protocolString=self.request_version,
                    headers=self.headers,
                    isSecure=self.server.isSecure,
                )
            except errors.InsufficientPermission:
                self.send_error(403)
                return None
            except:
                # exceptions are handled (logged) in callWrapper - send
                # 500 code back to the client to indicate an error happened
                self.send_error(500)
                from conary.lib import formattrace
                excType, excValue, excTb = sys.exc_info()
                formattrace.formatTrace(excType,
                                        excValue,
                                        excTb,
                                        withLocals=False)
                return None
            logMe(3, "returned from", method)

        rawResponse, headers = response.toWire(request.version)

        sio = util.BoundedStringIO()
        util.xmlrpcDump((rawResponse, ), stream=sio, methodresponse=1)
        respLen = sio.tell()
        logMe(3, "encoded xml-rpc response to %d bytes" % respLen)

        self.send_response(200)
        encoding = self.headers.get('Accept-encoding', '')
        if respLen > 200 and 'deflate' in encoding:
            sio.seek(0)
            sio = util.compressStream(sio, level=5)
            respLen = sio.tell()
            self.send_header('Content-encoding', 'deflate')
        self.send_header("Content-type", "text/xml")
        self.send_header("Content-length", str(respLen))
        for key, value in sorted(headers.items()):
            self.send_header(key, value)
        if extraInfo:
            # If available, send to the client the via headers all the way up
            # to us
            self.send_header(
                'Via',
                proxy.formatViaHeader(localAddr,
                                      'HTTP/1.0',
                                      prefix=extraInfo.getVia()))

        self.end_headers()
        sio.seek(0)
        util.copyStream(sio, self.wfile)
        logMe(3, "sent response to client", respLen, "bytes")
        return respLen
Esempio n. 7
0
                    authToken=authToken,
                    request=request,
                    remoteIp=remoteIp,
                    rawUrl=req.unparsed_uri,
                    localAddr=localAddr,
                    protocolString=req.protocol,
                    headers=req.headers_in,
                    isSecure=isSecure,
                )
            except errors.InsufficientPermission:
                return apache.HTTP_FORBIDDEN

        rawResponse, headers = response.toWire(request.version)

        sio = util.BoundedStringIO()
        util.xmlrpcDump((rawResponse, ), stream=sio, methodresponse=1)
        respLen = sio.tell()
        repos.log(1, method,
                  "time=%.3f size=%d" % (time.time() - startTime, respLen))

        req.content_type = "text/xml"
        # check to see if the client will accept a compressed response
        encoding = req.headers_in.get('Accept-encoding', '')
        if respLen > 200 and 'deflate' in encoding:
            req.headers_out['Content-encoding'] = 'deflate'
            sio.seek(0)
            sio = util.compressStream(sio, 5)
            respLen = sio.tell()
        req.headers_out['Content-length'] = '%d' % respLen
        for key, value in sorted(headers.items()):
            req.headers_out[key] = value
Esempio n. 8
0
    def handleXml(self, authToken):
        contentLength = int(self.headers['Content-Length'])
        sio = util.BoundedStringIO()

        actual = util.copyStream(self.rfile, sio, contentLength)
        if contentLength != actual:
            raise Exception(contentLength, actual)

        sio.seek(0)

        encoding = self.headers.get('Content-Encoding', None)
        if encoding == 'deflate':
            sio = util.decompressStream(sio)
            sio.seek(0)

        (params, method) = util.xmlrpcLoad(sio)
        logMe(3, "decoded xml-rpc call %s from %d bytes request" %(method, contentLength))

        if self.netProxy:
            repos = self.netProxy
        else:
            repos = self.netRepos

        localHost, localPort = self.request.getsockname()[:2]
        if ':' in localHost:
            localHost = '[%s]' % localHost
        localAddr = '%s:%s' % (localHost, localPort)
        request = xmlshims.RequestArgs.fromWire(params)

        if repos is not None:
            try:
                response, extraInfo = repos.callWrapper(
                        protocol='http',
                        port=None,
                        methodname=method,
                        authToken=authToken,
                        request=request,
                        remoteIp=self.connection.getpeername()[0],
                        rawUrl=self.path,
                        localAddr=localAddr,
                        protocolString=self.request_version,
                        headers=self.headers,
                        isSecure=self.server.isSecure,
                        )
            except errors.InsufficientPermission:
                self.send_error(403)
                return None
            except:
                # exceptions are handled (logged) in callWrapper - send
                # 500 code back to the client to indicate an error happened
                self.send_error(500)
                from conary.lib import formattrace
                excType, excValue, excTb = sys.exc_info()
                formattrace.formatTrace(excType, excValue, excTb,
                    withLocals = False)
                return None
            logMe(3, "returned from", method)

        rawResponse, headers = response.toWire(request.version)

        sio = util.BoundedStringIO()
        util.xmlrpcDump((rawResponse,), stream = sio, methodresponse=1)
        respLen = sio.tell()
        logMe(3, "encoded xml-rpc response to %d bytes" % respLen)

        self.send_response(200)
        encoding = self.headers.get('Accept-encoding', '')
        if respLen > 200 and 'deflate' in encoding:
            sio.seek(0)
            sio = util.compressStream(sio, level = 5)
            respLen = sio.tell()
            self.send_header('Content-encoding', 'deflate')
        self.send_header("Content-type", "text/xml")
        self.send_header("Content-length", str(respLen))
        for key, value in sorted(headers.items()):
            self.send_header(key, value)
        if extraInfo:
            # If available, send to the client the via headers all the way up
            # to us
            self.send_header('Via', proxy.formatViaHeader(localAddr,
                'HTTP/1.0', prefix=extraInfo.getVia()))

        self.end_headers()
        sio.seek(0)
        util.copyStream(sio, self.wfile)
        logMe(3, "sent response to client", respLen, "bytes")
        return respLen
Esempio n. 9
0
                        authToken=authToken,
                        request=request,
                        remoteIp=remoteIp,
                        rawUrl=req.unparsed_uri,
                        localAddr=localAddr,
                        protocolString=req.protocol,
                        headers=req.headers_in,
                        isSecure=isSecure,
                        )
            except errors.InsufficientPermission:
                return apache.HTTP_FORBIDDEN

        rawResponse, headers = response.toWire(request.version)

        sio = util.BoundedStringIO()
        util.xmlrpcDump((rawResponse,), stream=sio, methodresponse=1)
        respLen = sio.tell()
        repos.log(1, method, "time=%.3f size=%d" % (time.time()-startTime,
                                                    respLen))

        req.content_type = "text/xml"
        # check to see if the client will accept a compressed response
        encoding = req.headers_in.get('Accept-encoding', '')
        if respLen > 200 and 'deflate' in encoding:
            req.headers_out['Content-encoding'] = 'deflate'
            sio.seek(0)
            sio = util.compressStream(sio, 5)
            respLen = sio.tell()
        req.headers_out['Content-length'] = '%d' % respLen
        for key, value in sorted(headers.items()):
            req.headers_out[key] = value
Esempio n. 10
0
    def postRpc(self):
        if self.request.content_type != 'text/xml':
            return self._makeError('400 Bad Request',
                                   "Unrecognized Content-Type")
        stream = self.request.body_file
        encoding = self.request.headers.get('Content-Encoding', 'identity')
        if encoding == 'deflate':
            stream = util.decompressStream(stream)
            stream.seek(0)
        elif encoding != 'identity':
            return self._makeError('400 Bad Request',
                                   "Unrecognized Content-Encoding")

        try:
            params, method = util.xmlrpcLoad(stream)
        except:
            return self._makeError('400 Bad Request',
                                   "Malformed XMLRPC request")

        localAddr = socket.gethostname()
        try:
            request = self.requestFilter.fromWire(params)
        except (TypeError, ValueError, IndexError):
            return self._makeError('400 Bad Request',
                                   "Malformed XMLRPC arguments")

        # Execution phase -- locate and call the target method
        try:
            response, extraInfo = self.proxyServer.callWrapper(
                protocol=None,
                port=None,
                methodname=method,
                authToken=self.auth,
                request=request,
                remoteIp=self.auth.remote_ip,
                rawUrl=self.request.url,
                localAddr=localAddr,
                protocolString=self.request.http_version,
                headers=self.request.headers,
                isSecure=self.isSecure)
        except errors.InsufficientPermission:
            return self._makeError('403 Forbidden', "Insufficient permission")

        rawResponse, headers = response.toWire(request.version)
        response = self.responseFactory(
            headerlist=headers.items(),
            content_type='text/xml',
        )

        # Output phase -- serialize and write the response
        body = util.xmlrpcDump((rawResponse, ), methodresponse=1)
        accept = self.request.accept_encoding
        if len(body) > 200 and 'deflate' in accept:
            response.content_encoding = 'deflate'
            response.body = zlib.compress(body, 5)
        else:
            response.body = body
        if extraInfo:
            headers['Via'] = proxy.formatViaHeader(localAddr,
                                                   self.request.http_version,
                                                   prefix=extraInfo.getVia())

        return response
Esempio n. 11
0
    def postRpc(self):
        if self.request.content_type != 'text/xml':
            return self._makeError('400 Bad Request',
                                   "Unrecognized Content-Type")
        stream = self.request.body_file
        encoding = self.request.headers.get('Content-Encoding', 'identity')
        if encoding == 'deflate':
            stream = util.decompressStream(stream)
            stream.seek(0)
        elif encoding != 'identity':
            return self._makeError('400 Bad Request',
                                   "Unrecognized Content-Encoding")

        try:
            params, method = util.xmlrpcLoad(stream)
        except:
            return self._makeError('400 Bad Request',
                                   "Malformed XMLRPC request")

        localAddr = '%s:%s' % (socket.gethostname(), self.getLocalPort())
        try:
            request = self.requestFilter.fromWire(params)
        except (TypeError, ValueError, IndexError):
            return self._makeError('400 Bad Request',
                                   "Malformed XMLRPC arguments")

        rawUrl = self.request.url
        scheme = self.request.headers.get('X-Conary-Proxy-Target-Scheme')
        if scheme in ('http', 'https'):
            rawUrl = str(URL(rawUrl)._replace(scheme=scheme))

        # Execution phase -- locate and call the target method
        try:
            responseArgs, extraInfo = self.proxyServer.callWrapper(
                protocol=None,
                port=None,
                methodname=method,
                authToken=self.auth,
                request=request,
                remoteIp=self.auth.remote_ip,
                rawUrl=rawUrl,
                localAddr=localAddr,
                protocolString=self.request.http_version,
                headers=self.request.headers,
                isSecure=self.isSecure)
        except errors.InsufficientPermission:
            return self._makeError('403 Forbidden', "Insufficient permission")

        rawResponse, headers = responseArgs.toWire(request.version)
        if extraInfo:
            headers['Via'] = proxy.formatViaHeader(localAddr,
                                                   self.request.http_version,
                                                   prefix=extraInfo.getVia())
        response = self.responseFactory(headerlist=headers.items())
        response.content_type = 'text/xml'

        # Output phase -- serialize and write the response
        body = util.xmlrpcDump((rawResponse, ), methodresponse=1)
        accept = self.request.accept_encoding
        if len(body) > 200 and 'deflate' in accept:
            response.content_encoding = 'deflate'
            response.body = zlib.compress(body, 5)
        else:
            response.body = body

        if (method == 'getChangeSet' and request.version >= 71
                and not responseArgs.isException and response.status_int == 200
                and responseArgs.result[0]
                and 'multipart/mixed' in list(self.request.accept)):
            return self.inlineChangeset(response, responseArgs, headers)
        else:
            return response