Exemple #1
0
    def testStreaming(self):
        bin_data = os.urandom(20)
        f = Msgpack.FilePart("%s/users.json" % config.data_dir, "rb")
        f.read_bytes = 30

        data = {"cmd": "response", "body": f, "bin": bin_data}

        out_buff = io.BytesIO()
        Msgpack.stream(data, out_buff.write)
        out_buff.seek(0)

        data_packb = {
            "cmd": "response",
            "body": open("%s/users.json" % config.data_dir, "rb").read(30),
            "bin": bin_data
        }

        out_buff.seek(0)
        data_unpacked = Msgpack.unpack(out_buff.read())
        assert data_unpacked == data_packb
        assert data_unpacked["cmd"] == "response"
        assert type(data_unpacked["body"]) == bytes
Exemple #2
0
    def handleGetFile(self, params, streaming=False):
        site = self.sites.get(params["site"])
        if not site or not site.isServing():  # Site unknown or not serving
            self.response({"error": "Unknown site"})
            self.connection.badAction(5)
            return False
        try:
            file_path = site.storage.getPath(params["inner_path"])
            if streaming:
                file_obj = site.storage.open(params["inner_path"])
            else:
                file_obj = Msgpack.FilePart(file_path, "rb")

            with file_obj as file:
                file.seek(params["location"])
                read_bytes = params.get("read_bytes", FILE_BUFF)
                file_size = os.fstat(file.fileno()).st_size

                if file_size > read_bytes:  # Check if file is readable at current position (for big files)
                    if not self.isReadable(site, params["inner_path"], file,
                                           params["location"]):
                        raise RequestError(
                            "File not readable at position: %s" %
                            params["location"])
                else:
                    if params.get(
                            "file_size") and params["file_size"] != file_size:
                        self.connection.badAction(2)
                        raise RequestError(
                            "File size does not match: %sB != %sB" %
                            (params["file_size"], file_size))

                if not streaming:
                    file.read_bytes = read_bytes

                if params["location"] > file_size:
                    self.connection.badAction(5)
                    raise RequestError("Bad file location")

                if streaming:
                    back = {
                        "size":
                        file_size,
                        "location":
                        min(file.tell() + read_bytes, file_size),
                        "stream_bytes":
                        min(read_bytes, file_size - params["location"])
                    }
                    self.response(back)
                    self.sendRawfile(file, read_bytes=read_bytes)
                else:
                    back = {
                        "body": file,
                        "size": file_size,
                        "location": min(file.tell() + file.read_bytes,
                                        file_size)
                    }
                    self.response(back, streaming=True)

                bytes_sent = min(
                    read_bytes, file_size -
                    params["location"])  # Number of bytes we going to send
                site.settings["bytes_sent"] = site.settings.get(
                    "bytes_sent", 0) + bytes_sent
            if config.debug_socket:
                self.log.debug("File %s at position %s sent %s bytes" %
                               (file_path, params["location"], bytes_sent))

            # Add peer to site if not added before
            connected_peer = site.addPeer(self.connection.ip,
                                          self.connection.port,
                                          source="request")
            if connected_peer:  # Just added
                connected_peer.connect(
                    self.connection)  # Assign current connection to peer

            return {
                "bytes_sent": bytes_sent,
                "file_size": file_size,
                "location": params["location"]
            }

        except RequestError as err:
            self.log.debug("GetFile %s %s request error: %s" %
                           (self.connection, params["inner_path"],
                            Debug.formatException(err)))
            self.response({"error": "File read error: %s" % err})
        except OSError as err:
            if config.verbose:
                self.log.debug("GetFile read error: %s" %
                               Debug.formatException(err))
            self.response({"error": "File read error"})
            return False
        except Exception as err:
            self.log.error("GetFile exception: %s" %
                           Debug.formatException(err))
            self.response({"error": "File read exception"})
            return False