/// <summary> /// Download a file /// </summary> /// <param name="request"></param> /// <returns></returns> public RemoteFileDescriptor Download(RemoteFileIdentifier request) { //Get path to file storage string sPath = FileStorage.Provider.ConnectionString; System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sPath); //Get the file guid string sFileGuid = System.IO.Path.GetFileNameWithoutExtension(request.RemoteFile.LocalPath); Guid gFileGuid = new Guid(sFileGuid); //Get file definition File f = FileBroker.SelectByGuid(gFileGuid, di); System.Diagnostics.Debug.Assert(f.Guid == gFileGuid); //Report start System.Diagnostics.Trace.WriteLine("Start downloading " + f.FileName); //Open stream _StorageStream = FileStorage.GetFileStream(f.Key, AccessMode.Read); System.Diagnostics.Debug.Assert(f.Size == _StorageStream.Length); //Note that we cannot close the stream before returning the stream to the client //Otherwise the client gets a closed stream. //So we need to monitor the use of the stream made by the client to close it on a separate thread //once the client has entirely read it or once the connection is closed //System.Threading.Thread objMonitoringThread = new System.Threading.Thread( // new System.Threading.ParameterizedThreadStart(this.MonitorAndClose)); //objMonitoringThread.Start(objStorageStream); RemoteFileDescriptor objRemoteFileInfoRet = new RemoteFileDescriptor(); objRemoteFileInfoRet.ContentType = f.ContentType; objRemoteFileInfoRet.Email = null; objRemoteFileInfoRet.FileGuid = f.Guid; objRemoteFileInfoRet.FileName = f.FileName; objRemoteFileInfoRet.HashCode = f.HashValue; objRemoteFileInfoRet.Length = f.Size; objRemoteFileInfoRet.SecurityCode = null; objRemoteFileInfoRet.Stream = _StorageStream; // report end System.Diagnostics.Trace.WriteLine("Download complete!"); // return result return(objRemoteFileInfoRet); }
/// <summary> /// Upload a file /// </summary> /// <param name="request"></param> public void Upload(RemoteFileDescriptor request) { //report start System.Diagnostics.Trace.WriteLine("Start uploading " + request.FileName); //TODO: We need to report exceptions properly using FaultContractAttribute and FaultException //In this particular example, we want to raise a proper exception as soon as possible if the file upload is too large. //Note that currently the upload progresses for a while before the exception is raised. //Using HttpContext to access configuration data (especially httpRuntime section in web.config) //from WCF services requires HttpContext which is only available to WCF services in Asp.Net compatibility mode //See: http://blogs.msdn.com/wenlong/archive/2006/01/23/516041.aspx //But the good news is apparently since .NET 3.0 SP1, WCF services are not dependant upon the httpRuntime section //See: http://blogs.msdn.com/wenlong/archive/2008/03/10/why-changing-sendtimeout-does-not-help-for-hosted-wcf-services.aspx //So we essentially need to check that request.Length (unless there is a way to access the Content-Length Htpp header) //is lower than the value of BasicHttpBinding.MaxReceivedMessageSize configured in web.config #if NOTUSED //Raise error Http 413 asap //Use FaultContractAttribute and FaultException to report an error Binding objBinding = OperationContext.Current.Host.Description.Endpoints[0].Binding; System.Diagnostics.Debug.Assert(objBinding.Name == "BasicHttpBinding"); BasicHttpBinding objBasicHttpBinding = objBinding as BasicHttpBinding; if (objBasicHttpBinding != null) { if (request.Length > objBasicHttpBinding.MaxReceivedMessageSize) { throw new System.Web.HttpException(413, "Too large!"); } } #endif //Authenticate user if (!Authenticate(request.Email, request.SecurityCode)) { throw new ApplicationException(Resources.Web.glossary.WebService_AuthenticationFailInfo); } //Stream file int iBytesRead; byte[] arrBuffer = new byte[Constants.WcfStreamingBufferSize]; //The file key is unknown from the client object objProviderFileKey = FileStorage.GetNewFileKey(request.FileName); //Create stream to write to _StorageStream = FileStorage.GetFileStream(objProviderFileKey, AccessMode.Create); do { // Read bytes from input stream iBytesRead = request.Stream.Read(arrBuffer, 0, Constants.WcfStreamingBufferSize); // Write bytes to output stream _StorageStream.Write(arrBuffer, 0, iBytesRead); } while (iBytesRead > 0); _StorageStream.Close(); //Create file object File f = new File( request.FileGuid, request.FileName, request.ContentType, objProviderFileKey.ToString(), request.Length, request.HashCode); //Get path to file storage string sPath = FileStorage.Provider.ConnectionString; System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(sPath); //Add definition to file storage (Existence will be checked in FileBroker) FileBroker.Insert(f, di); // report end System.Diagnostics.Trace.WriteLine("Upload complete!"); }