Esempio n. 1
0
        public void Put(string remotename, System.IO.Stream stream)
        {
            HttpWebRequest req = CreateRequest("/" + remotename, "");
            req.Method = "PUT";
            req.ContentType = "application/octet-stream";

            //According to the MSDN docs, the timeout should only affect the
            // req.GetRequestStream() or req.GetResponseStream() call, but apparently
            // it means that the entire operation on the request stream must
            // be completed within the limit
            //We use Infinite, and rely on the ReadWriteTimeout value instead
            req.Timeout = System.Threading.Timeout.Infinite;

            try { req.ContentLength = stream.Length; }
            catch { }

            //If we can pre-calculate the MD5 hash before transmission, do so
            /*if (stream.CanSeek)
            {
                System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
                req.Headers["ETag"] = Core.Utility.ByteArrayAsHexString(md5.ComputeHash(stream)).ToLower();
                stream.Seek(0, System.IO.SeekOrigin.Begin);

                using (System.IO.Stream s = req.GetRequestStream())
                    Core.Utility.CopyStream(stream, s);

                //Reset the timeout to the default value of 100 seconds to
                // avoid blocking the GetResponse() call
                req.Timeout = 100000;

                //The server handles the eTag verification for us, and gives an error if the hash was a mismatch
                using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
                    if ((int)resp.StatusCode >= 300)
                        throw new WebException(Strings.CloudFiles.FileUploadError, null, WebExceptionStatus.ProtocolError, resp);

            }
            else //Otherwise use a client-side calculation
            */
            //TODO: We cannot use the local MD5 calculation, because that could involve a throttled read,
            // and may invoke various events
            {
                string fileHash = null;

                using (System.IO.Stream s = req.GetRequestStream())
                using (MD5CalculatingStream mds = new MD5CalculatingStream(s))
                {
                    Utility.Utility.CopyStream(stream, mds);
                    fileHash = mds.GetFinalHashString();
                }

                string md5Hash = null;

                //Reset the timeout to the default value of 100 seconds to
                // avoid blocking the GetResponse() call
                req.Timeout = 100000;

                //We need to verify the eTag locally
                try
                {
                    using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse())
                        if ((int)resp.StatusCode >= 300)
                            throw new WebException(Strings.CloudFiles.FileUploadError, null, WebExceptionStatus.ProtocolError, resp);
                        else
                            md5Hash = resp.Headers["ETag"];
                }
                catch (WebException wex)
                {
                    //Catch 404 and turn it into a FolderNotFound error
                    if (wex.Response is HttpWebResponse && ((HttpWebResponse)wex.Response).StatusCode == HttpStatusCode.NotFound)
                        throw new FolderMissingException(wex);

                    //Other error, just re-throw
                    throw;
                }

                if (md5Hash == null || md5Hash.ToLower() != fileHash.ToLower())
                {
                    //Remove the broken file
                    try { Delete(remotename); }
                    catch { }

                    throw new Exception(Strings.CloudFiles.ETagVerificationError);
                }
            }
        }
Esempio n. 2
0
        public void Get(string remotename, System.IO.Stream stream)
        {
            HttpWebRequest req = CreateRequest("/" + remotename, "");
            req.Method = "GET";

            //According to the MSDN docs, the timeout should only affect the
            // req.GetRequestStream() or req.GetResponseStream() call, but apparently
            // it means that the entire operation on the request stream must
            // be completed within the limit
            //We use Infinite, and rely on the ReadWriteTimeout value instead
            req.Timeout = System.Threading.Timeout.Infinite;

            using (WebResponse resp = req.GetResponse())
            using (System.IO.Stream s = resp.GetResponseStream())
            using (MD5CalculatingStream mds = new MD5CalculatingStream(s))
            {
                string md5Hash = resp.Headers["ETag"];
                Utility.Utility.CopyStream(mds, stream);

                if (mds.GetFinalHashString().ToLower() != md5Hash.ToLower())
                    throw new Exception(Strings.CloudFiles.ETagVerificationError);
            }
        }