Exemple #1
0
        public void UploadFilesSafe(DBWork work, string [] filenames, bool [] hidden_values)
        {
            Queue <string> files = new Queue <string> (filenames);
            Queue <bool>   hiddens;

            if (hidden_values != null)
            {
                hiddens = new Queue <bool> (hidden_values);
            }
            else
            {
                hiddens = new Queue <bool> (new bool [filenames.Length]);
            }

            if (filenames.Length != hiddens.Count)
            {
                throw new ArgumentOutOfRangeException("filenames/hidden");
            }

            ExecuteSafe("Upload files safe", () =>
            {
                byte version;
                byte type;
                int port;
                string gz            = null;
                BinaryReader reader  = null;
                BinaryWriter writer  = null;
                NetworkStream stream = null;
                byte [] buffer       = new byte [1024];
                TcpClient client     = null;

                if (files.Count == 0)
                {
                    return;
                }

                Logger.Log("UploadFilesSafe () trying to upload {0} files...", files.Count);

                port = this.GetUploadPort();

                try {
                    client = new TcpClient();
                    client.Connect(new Uri(this.Url, UriKind.Absolute).Host, port);
                    stream              = client.GetStream();
                    stream.ReadTimeout  = (int)TimeSpan.FromMinutes(5).TotalMilliseconds;
                    stream.WriteTimeout = stream.ReadTimeout;
                    reader              = new BinaryReader(stream);
                    writer              = new BinaryWriter(stream);

                    writer.Write((byte)1);                             // version
                    WriteStringByte(writer, WebServiceLogin.User);     // name_length + name
                    WriteStringByte(writer, WebServiceLogin.Password); // password_length + password
                    writer.Write((int)work.id);                        // work_id
                    writer.Write((ushort)filenames.Length);            // file_count
                    writer.Write((ulong)0);                            // reserved

                    const string NotFoundMessage = "*** COULD NOT FIND THIS FILE, UPLOADED THIS ERROR MESSAGE INSTEAD ***";
                    byte [] NotFoundMessageBytes = null;

                    while (files.Count > 0)
                    {
                        string path_to_contents = files.Peek();
                        string filename         = Path.GetFileName(path_to_contents);
                        string compressed_mime;
                        bool hidden = hiddens.Peek();
                        byte [] md5;
                        FileInfo fi;
                        bool exists = File.Exists(path_to_contents);

                        if (!exists && NotFoundMessageBytes == null)
                        {
                            NotFoundMessageBytes = System.Text.UTF8Encoding.UTF8.GetBytes(NotFoundMessage);
                        }

                        Logger.Log(2, "WebServices.UploadFilesSafe (): uploading '{0}' to port {1}", filename, port);

                        if (exists)
                        {
                            using (FileStream fs = new FileStream(path_to_contents, FileMode.Open, FileAccess.Read, FileShare.Read))
                                md5 = FileUtilities.CalculateMD5_Bytes(fs);
                        }
                        else
                        {
                            Logger.Log("WebServices.UploadFilesSafe (): the file '{0}' does not exist, uploading an error message instead", path_to_contents, port);
                            using (var str = new MemoryStream(NotFoundMessageBytes))
                                md5 = FileUtilities.CalculateMD5_Bytes(str);
                        }

                        writer.Write("MonkeyWrench".ToCharArray());                // marker
                        writer.Write(md5, 0, md5.Length);                          // md5
                        writer.Write((byte)(hidden ? 3 : 1));                      // flags
                        WriteStringByte(writer, filename);                         // filename_length + filename
                        writer.Flush();

                        ReadResponse(reader, out version, out type);

                        Logger.Log(2, "WebServices.UploadFilesSafe (): uploading '{0}', got response type {1}", filename, type);

                        // 1 = everything OK, 2 = file received OK, 3 = error, 4 = send file
                        switch (type)
                        {
                        case 2:
                            /* No need to send file */
                            break;

                        case 4:
                            /* Send file */
                            int read;
                            int total = 0;

                            // try to compress the file
                            if (exists)
                            {
                                string original_contents = path_to_contents;
                                try {
                                    gz = FileUtilities.GZCompress(path_to_contents);
                                    if (gz != null)
                                    {
                                        path_to_contents = gz;
                                        compressed_mime  = MimeTypes.GZ;
                                    }
                                    else
                                    {
                                        path_to_contents = filename;
                                        compressed_mime  = null;
                                    }
                                    Logger.Log(2, "Compressed {0} to {1}.", original_contents, gz);
                                } catch (Exception ex) {
                                    path_to_contents = filename;
                                    compressed_mime  = null;
                                    Logger.Log("Could not compress the file {0}: {1}, uploading uncompressed.", filename, ex.Message);
                                }

                                fi = new FileInfo(path_to_contents);

                                long length = fi.Length;
                                if (length > 1024 * 1024 * 200)
                                {
                                    files.Dequeue();
                                    hiddens.Dequeue();
                                    throw new ApplicationException(string.Format("Not uploading {0} ({2}): filesize is > 200MB (it is: {1} MB)", path_to_contents, length / (1024.0 * 1024.0), filename));
                                }

                                if (compressed_mime == null)
                                {
                                    writer.Write((byte)0);
                                }
                                else
                                {
                                    WriteStringByte(writer, compressed_mime);                    // compressed_mime_length + compressed_mime
                                }
                                writer.Write((uint)fi.Length);                                   // content_length

                                using (FileStream fs = new FileStream(path_to_contents, FileMode.Open, FileAccess.Read, FileShare.Read)) {
                                    while ((read = fs.Read(buffer, 0, buffer.Length)) != 0)
                                    {
                                        total += read;
                                        writer.Write(buffer, 0, read);
                                    }
                                    writer.Flush();
                                }
                            }
                            else
                            {
                                writer.Write((byte)0);
                                writer.Write((uint)NotFoundMessageBytes.Length);
                                writer.Write(NotFoundMessageBytes, 0, NotFoundMessageBytes.Length);
                                writer.Flush();
                                total += NotFoundMessageBytes.Length;
                            }

                            Logger.Log(2, "WebServices.UploadFilesSafe (): uploaded '{0}', {1} bytes", filename, total);

                            ReadResponse(reader, out version, out type);
                            if (type == 2)
                            {
                                Logger.Log("WebServices.UploadFilesSafe (): uploaded '{0}' successfully", filename);
                            }
                            break;
                        }

                        files.Dequeue();
                        hiddens.Dequeue();
                    }
                    ReadResponse(reader, out version, out type);
                    if (type == 4)
                    {
                        Logger.Log("WebServices.UploadFilesSafe (): all files uploaded successfully");
                    }
                } finally {
                    FileUtilities.TryDeleteFile(gz);
                    try {
                        stream.Close();
                        reader.Close();
                        writer.Close();
                    } catch {
                        // Ignore
                    }
                    try {
                        client.Close();
                    } catch {
                        // Ignore
                    }
                }
            });
        }