/// <summary> /// Processes a GetLock request /// </summary> /// <remarks> /// For full documentation on GetLock, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/GetLock.html /// </remarks> private async static Task <HttpResponseMessage> GetLock(this HttpContext context, FileModel file) { // Check for valid lock on file if (String.IsNullOrEmpty(file.LockValue)) { // File is not locked...return empty X-WOPI-Lock header context.Response.Headers[WopiResponseHeaders.LOCK] = String.Empty; // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } else if (file.LockExpires != null && file.LockExpires < DateTime.Now) { // File lock expired, so clear it out file.LockValue = null; file.LockExpires = null; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // File is not locked...return empty X-WOPI-Lock header context.Response.Headers[WopiResponseHeaders.LOCK] = String.Empty; // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } else { // File has a valid lock, so we need to return it context.Response.Headers[WopiResponseHeaders.LOCK] = file.LockValue; // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } }
/// <summary> /// Processes a Lock request /// </summary> /// <remarks> /// For full documentation on Lock, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/Lock.html /// </remarks> private async static Task <HttpResponseMessage> Lock(this HttpContext context, FileModel file) { // Get the Lock value passed in on the request string requestLock = context.Request.Headers[WopiRequestHeaders.LOCK]; // Ensure the file isn't already locked or expired if (String.IsNullOrEmpty(file.LockValue) || (file.LockExpires != null && file.LockExpires < DateTime.Now)) { // Update the file with a LockValue and LockExpiration file.LockValue = requestLock; file.LockExpires = DateTime.Now.AddMinutes(30); await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } else if (file.LockValue == requestLock) { // File lock matches existing lock, so refresh lock by extending expiration file.LockExpires = DateTime.Now.AddMinutes(30); await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); return(returnStatus(HttpStatusCode.OK, "Success")); } else { // The file is locked by someone else...return mismatch return(context.returnLockMismatch(file.LockValue, String.Format("File already locked by {0}", file.LockValue))); } }
/// <summary> /// Processes a PutUserInfo request /// </summary> /// <remarks> /// For full documentation on PutUserInfo, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/PutUserInfo.html /// </remarks> private async static Task <HttpResponseMessage> PutUserInfo(this HttpContext context, FileModel file) { // Set and save the UserInfo on the file var stream = context.Request.InputStream; var bytes = new byte[stream.Length]; await stream.ReadAsync(bytes, 0, (int)stream.Length); file.UserInfo = System.Text.Encoding.UTF8.GetString(bytes); // Update the file in DocumentDB await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success return(returnStatus(HttpStatusCode.OK, "Success")); }
/// <summary> /// Processes a RenameFile request /// </summary> /// <remarks> /// For full documentation on RenameFile, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/RenameFile.html /// </remarks> private async static Task <HttpResponseMessage> RenameFile(this HttpContext context, FileModel file) { // Get the Lock value passed in on the request string requestLock = context.Request.Headers[WopiRequestHeaders.LOCK]; // Make sure the X-WOPI-RequestedName header is included if (context.Request.Headers[WopiRequestHeaders.REQUESTED_NAME] != null) { // Get the new file name var newFileName = context.Request.Headers[WopiRequestHeaders.REQUESTED_NAME]; // Ensure the file isn't locked if (String.IsNullOrEmpty(file.LockValue) || (file.LockExpires != null && file.LockExpires < DateTime.Now)) { // Update the file with a LockValue and LockExpiration file.LockValue = requestLock; file.LockExpires = DateTime.Now.AddMinutes(30); file.BaseFileName = newFileName; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } else if (file.LockValue == requestLock) { // File lock matches existing lock, so we can change the name file.LockExpires = DateTime.Now.AddMinutes(30); file.BaseFileName = newFileName; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK); return(returnStatus(HttpStatusCode.OK, "Success")); } else { // The file is locked by someone else...return mismatch return(context.returnLockMismatch(file.LockValue, String.Format("File locked by {0}", file.LockValue))); } } else { // X-WOPI-RequestedName header wasn't included return(returnStatus(HttpStatusCode.BadRequest, "X-WOPI-RequestedName header wasn't included in request")); } }
/// <summary> /// Processes a UnlockAndRelock request /// </summary> /// <remarks> /// For full documentation on UnlockAndRelock, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/UnlockAndRelock.html /// </remarks> private async static Task <HttpResponseMessage> UnlockAndRelock(this HttpContext context, FileModel file) { // Get the Lock and OldLock values passed in on the request string requestLock = context.Request.Headers[WopiRequestHeaders.LOCK]; string requestOldLock = context.Request.Headers[WopiRequestHeaders.OLD_LOCK]; // Ensure the file has a valid lock if (String.IsNullOrEmpty(file.LockValue)) { // File isn't locked...pass empty Lock in mismatch response return(context.returnLockMismatch(String.Empty, "File isn't locked")); } else if (file.LockExpires != null && file.LockExpires < DateTime.Now) { // File lock expired, so clear it out file.LockValue = null; file.LockExpires = null; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // File isn't locked...pass empty Lock in mismatch response return(context.returnLockMismatch(String.Empty, "File isn't locked")); } else if (requestOldLock != file.LockValue) { // File lock mismatch...pass Lock in mismatch response return(context.returnLockMismatch(file.LockValue, "Lock mismatch")); } else { // Update the file with a LockValue and LockExpiration file.LockValue = requestLock; file.LockExpires = DateTime.Now.AddMinutes(30); await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } }
/// <summary> /// Processes a PutFile request /// </summary> /// <remarks> /// For full documentation on PutFile, see https://wopi.readthedocs.org/projects/wopirest/en/latest/files/PutFile.html /// </remarks> private async static Task <HttpResponseMessage> PutFile(this HttpContext context, FileModel file) { // Get the Lock value passed in on the request string requestLock = context.Request.Headers[WopiRequestHeaders.LOCK]; // Ensure the file has a valid lock if (String.IsNullOrEmpty(file.LockValue)) { // If the file is 0 bytes, this is document creation if (context.Request.InputStream.Length == 0) { // Update the file in blob storage var bytes = new byte[context.Request.InputStream.Length]; context.Request.InputStream.Read(bytes, 0, bytes.Length); file.Size = bytes.Length; await AzureStorageUtil.UploadFile(file.id.ToString(), file.Container, bytes); // Update version file.Version++; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } else { // File isn't locked...pass empty Lock in mismatch response return(context.returnLockMismatch(String.Empty, "File isn't locked")); } } else if (file.LockExpires != null && file.LockExpires < DateTime.Now) { // File lock expired, so clear it out file.LockValue = null; file.LockExpires = null; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // File isn't locked...pass empty Lock in mismatch response return(context.returnLockMismatch(String.Empty, "File isn't locked")); } else if (requestLock != file.LockValue) { // File lock mismatch...pass Lock in mismatch response return(context.returnLockMismatch(file.LockValue, "Lock mismatch")); } else { // Update the file in blob storage var bytes = new byte[context.Request.InputStream.Length]; context.Request.InputStream.Read(bytes, 0, bytes.Length); file.Size = bytes.Length; await AzureStorageUtil.UploadFile(file.id.ToString(), file.Container, bytes); // Update version file.Version++; await DocumentRepository <FileModel> .UpdateItemAsync("Files", file.id.ToString(), (FileModel)file); // Return success 200 return(returnStatus(HttpStatusCode.OK, "Success")); } }