Exemplo n.º 1
0
        public static (FileDescriptor, List <byte[]>) FromFile(Stream file, string name, int chunk_size = 65000)
        {
            var pieces     = new List <byte[]>();
            var hasher     = HashSingleton.Duplicate();
            var descriptor = new FileDescriptor()
            {
                Name             = name,
                Length           = file.Length,
                Created          = DateTime.UtcNow,
                Checksum         = new byte[hasher.HashSize / 8],
                PieceIdentifiers = new List <byte[]>(),
                MimeType         = MimeMapper.MapToMime(name)
            };

            byte[] buffer = new byte[chunk_size];

            while (file.Position < file.Length)
            {
                var read  = file.Read(buffer, 0, chunk_size);
                var chunk = new byte[read];

                Array.Copy(buffer, 0, chunk, 0, read);

                if (file.Position == file.Length)
                {
                    hasher.TransformFinalBlock(buffer, 0, read);
                }
                else
                {
                    hasher.TransformBlock(buffer, 0, read, buffer, 0);
                }

                pieces.Add(chunk);
                descriptor.PieceIdentifiers.Add(HashSingleton.Compute(chunk));
            }

            descriptor.Checksum = hasher.Hash;

            return(descriptor, pieces);
        }
Exemplo n.º 2
0
        public HarmonyModule()
        {
            Get("/health", _ =>
            {
                if (Node == null)
                {
                    return(Response.AsJson(new { Running = false }));
                }

                try
                {
                    return(Response.AsJson(new
                    {
                        Running = Node.Running,
                        Uptime = (long)(DateTime.Now - Start).TotalMilliseconds,
                        Stable = Node.Stable,
                        ListenEndPoint = Node.ListenEndPoint.ToString(),

                        id = Node.ID.ToUsefulString(),
                        Successor = Node.Successor.ToUsefulString(),
                        Predecessor = Node.Predecessor.ToUsefulString(),

                        PeerCount = Node.Network.PeerCount,
                        Connections = Node.Network.Nodes.Values.OfType <RemoteNode>()
                                      .Select(n => new { id = n.ID.ToUsefulString(), ep = n.RemoteEndPoint?.ToString(), alive = n.Ping() }),
                        CandidatePeers = Node.Network.GetCandidatePeers().Count(),
                        KeysInMemory = Node.LocalDataStore.Pieces.Values
                                       .Where(piece => piece != null)
                                       .Select(piece => new
                        {
                            id = piece.OriginalID.ToUsefulString(),
                            d = piece.RedundancyIndex,
                            IteratedID = piece.ID.ToUsefulString(),
                            Contents = $"{piece.Data.ToUsefulString(true)} ({piece.Data.Length} bytes)",
                            ContentsText = piece.Data.Length > 50 ? "(too long)" : Encoding.UTF8.GetString(piece.Data),
                            Source = piece.Source.ToUsefulString()
                        })
                    }));
                }
                catch (Exception ex)
                {
                    return(CreateError($"{ex.GetType()} occurred while generating health page: {ex.Message}", HttpStatusCode.InternalServerError));
                }
            });

            Get("/file", _ =>
            {
                if (Node == null || !Node.Running)
                {
                    return(CreateError("Node is down", HttpStatusCode.ServiceUnavailable));
                }

                var id_str = "";
                id_str     = Request.Query["id"] ?? "";

                if (id_str.Length != Node.KeySize * 2 ||
                    !Utilities.TryParseBytesFromString(id_str, out byte[] descriptor_piece_id))
                {
                    return(CreateError("Invalid piece ID"));
                }

                var descriptor_piece = Node.RetrievePiece(descriptor_piece_id);

                if (descriptor_piece == null)
                {
                    return(CreateError($"Failed to retrieve descriptor piece"));
                }

                var descriptor = FileDescriptor.Deserialize(descriptor_piece.Data);
                var pieces     = descriptor.PieceIdentifiers.Select(piece_id => Node.RetrievePiece(piece_id));

                if (pieces.Any(p => p == null))
                {
                    return(CreateError($"Failed to retrieve {pieces.Count(p => p == null)} pieces out of {descriptor.PieceIdentifiers.Count}"));
                }

                var descriptor_mime_type   = descriptor.MimeType;
                var whitelisted_mime_types = new[] {
                    "image/*",
                    "audio/*",
                    "video/*",
                    "font/*",
                    "model/*",
                    "text/plain",
                    "text/csv",
                    "application/pdf",
                    "application/octet-stream"
                };

                if (!whitelisted_mime_types.Any(allowed_type => MimeMapper.WildcardMatch(allowed_type, descriptor_mime_type)))
                {
                    descriptor_mime_type = "application/octet-stream";
                }

                return(new Response()
                {
                    Contents = (str) =>
                    {
                        foreach (var piece in pieces)
                        {
                            str.Write(piece.Data, 0, piece.Data.Length);
                        }

                        str.Flush();
                    },
                    ContentType = descriptor_mime_type,
                    StatusCode = HttpStatusCode.OK
                });
            });