Ejemplo n.º 1
0
        /// <summary>
        /// Processes a GetFile request
        /// </summary>
        /// <remarks>
        /// For full documentation on GetFile, see
        /// https://wopi.readthedocs.io/projects/wopirest/en/latest/files/GetFile.html
        /// </remarks>
        private void HandleGetFileRequest(HttpContext context, WopiRequest requestData)
        {
            if (!ValidateAccess(requestData, writeAccessRequired: false))
            {
                ReturnInvalidToken(context.Response);
                return;
            }

            if (!File.Exists(requestData.FullPath))
            {
                ReturnFileUnknown(context.Response);
                return;
            }

            try
            {
                context.Response.AddHeader(WopiHeaders.ItemVersion, GetFileVersion(requestData.FullPath));
                // transmit file from local storage to the response stream.
                ReturnSuccess(context.Response);
                context.Response.TransmitFile(requestData.FullPath);
            }
            catch (UnauthorizedAccessException ex)
            {
                ConsoleTo.Log(ex);
                ReturnFileUnknown(context.Response);
            }
            catch (FileNotFoundException ex)
            {
                ConsoleTo.Log(ex);
                ReturnFileUnknown(context.Response);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Processes a PutFile request
        /// </summary>
        /// <remarks>
        /// For full documentation on PutFile, see
        /// https://wopi.readthedocs.io/projects/wopirest/en/latest/files/PutFile.html
        /// </remarks>
        private void HandlePutFileRequest(HttpContext context, WopiRequest requestData)
        {
            if (!ValidateAccess(requestData, writeAccessRequired: true))
            {
                ReturnInvalidToken(context.Response);
                return;
            }

            if (!File.Exists(requestData.FullPath))
            {
                ReturnFileUnknown(context.Response);
                return;
            }

            string   newLock = context.Request.Headers[WopiHeaders.Lock];
            LockInfo existingLock;
            bool     hasExistingLock;

            lock (Locks)
            {
                hasExistingLock = TryGetLock(requestData.Id, out existingLock);
            }

            if (hasExistingLock && existingLock.Lock != newLock)
            {
                // lock mismatch/locked by another interface
                ReturnLockMismatch(context.Response, existingLock.Lock);
                return;
            }

            FileInfo putTargetFileInfo = new FileInfo(requestData.FullPath);

            // The WOPI spec allows for a PutFile to succeed on a non-locked file if the file is currently zero bytes in length.
            // This allows for a more efficient Create New File flow that saves the Lock roundtrips.
            if (!hasExistingLock && putTargetFileInfo.Length != 0)
            {
                // With no lock and a non-zero file, a PutFile could potentially result in data loss by clobbering
                // existing content.  Therefore, return a lock mismatch error.
                ReturnLockMismatch(context.Response, reason: "PutFile on unlocked file with current size != 0");
            }

            // Either the file has a valid lock that matches the lock in the request, or the file is unlocked
            // and is zero bytes.  Either way, proceed with the PutFile.
            try
            {
                // TODO: Should be replaced with proper file save logic to a real storage system and ensures write atomicity
                using (var fileStream = File.Open(requestData.FullPath, FileMode.Truncate, FileAccess.Write, FileShare.None))
                {
                    context.Request.InputStream.CopyTo(fileStream);
                }
                context.Response.AddHeader(WopiHeaders.ItemVersion, GetFileVersion(requestData.FullPath));
            }
            catch (UnauthorizedAccessException ex)
            {
                ConsoleTo.Log(ex);
                ReturnFileUnknown(context.Response);
            }
            catch (IOException ex)
            {
                ConsoleTo.Log(ex);
                ReturnServerError(context.Response);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Processes a CheckFileInfo request
        /// </summary>
        /// <remarks>
        /// For full documentation on CheckFileInfo, see
        /// https://wopi.readthedocs.io/projects/wopirest/en/latest/files/CheckFileInfo.html
        /// </remarks>
        private void HandleCheckFileInfoRequest(HttpContext context, WopiRequest requestData)
        {
            if (!ValidateAccess(requestData, writeAccessRequired: false))
            {
                ReturnInvalidToken(context.Response);
                return;
            }

            if (!File.Exists(requestData.FullPath))
            {
                ReturnFileUnknown(context.Response);
                return;
            }

            try
            {
                FileInfo fileInfo = new FileInfo(requestData.FullPath);

                if (!fileInfo.Exists)
                {
                    ReturnFileUnknown(context.Response);
                    return;
                }

                // For more info on CheckFileInfoResponse fields, see
                // https://wopi.readthedocs.io/projects/wopirest/en/latest/files/CheckFileInfo.html#response
                CheckFileInfoResponse responseData = new CheckFileInfoResponse()
                {
                    // required CheckFileInfo properties
                    BaseFileName = Path.GetFileName(requestData.FullPath),
                    OwnerId      = requestData.UserId,
                    Size         = (int)fileInfo.Length,
                    UserId       = requestData.UserId,
                    Version      = fileInfo.LastWriteTimeUtc.ToString("O" /* ISO 8601 DateTime format string */), // Using the file write time is an arbitrary choice.

                    // optional CheckFileInfo properties
                    BreadcrumbBrandName = WopiConfig.BreadcrumbBrandName,
                    //BreadcrumbFolderName = fileInfo.Directory != null ? fileInfo.Directory.Name : "",
                    //BreadcrumbDocName = Path.GetFileNameWithoutExtension(requestData.FullPath),
                    //BreadcrumbBrandUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Host,
                    //BreadcrumbFolderUrl = context.Request.Url.Scheme + "://" + context.Request.Url.Host,

                    UserFriendlyName = requestData.UserName,

                    SupportsLocks           = true,
                    SupportsUpdate          = true,
                    UserCanNotWriteRelative = true, /* Because this host does not support PutRelativeFile */

                    ReadOnly     = fileInfo.IsReadOnly,
                    UserCanWrite = !fileInfo.IsReadOnly,
                };

                string jsonString = JsonConvert.SerializeObject(responseData);

                context.Response.Write(jsonString);
                ReturnSuccess(context.Response);
            }
            catch (UnauthorizedAccessException ex)
            {
                ConsoleTo.Log(ex);
                ReturnFileUnknown(context.Response);
            }
        }