Beispiel #1
0
        protected override Task <IActionResult> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
        {
            // CORE TODO Similar to VfsController: File() apparently has built in support for range requests and etags. From a cursory glance
            // that renders bascially all of this obsolete. Will need checking to ensure proper behavior. Can we use PhysicalFile instead?
            var stream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));

            return(Task.FromResult(
                       (IActionResult)File(stream, MediaTypeMap.GetMediaType(info.Extension).ToString(), info.LastWriteTime, _currentEtag)));

            //// Check whether we have a conditional If-None-Match request
            //if (IsIfNoneMatchRequest(_currentEtag))
            //{
            //    var result = StatusCode(StatusCodes.Status304NotModified);
            //    // CORE TODO make sure this works properly
            //    Response.GetTypedHeaders().ETag = _currentEtag;
            //    return Task.FromResult((IActionResult)result);
            //}

            //// Check whether we have a conditional range request containing both a Range and If-Range header field
            //bool isRangeRequest = IsRangeRequest(_currentEtag);

            //// Generate file response
            //try
            //{
            //    _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
            //    MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension);
            //    HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);

            //    if (isRangeRequest)
            //    {
            //        successFileResponse.Content = new ByteRangeStreamContent(_readStream, Request.Headers.Range, mediaType, BufferSize);
            //    }
            //    else
            //    {
            //        successFileResponse.Content = new StreamContent(_readStream, BufferSize);
            //        successFileResponse.Content.Headers.ContentType = mediaType;
            //    }

            //    // Set etag for the file
            //    successFileResponse.Headers.ETag = _currentEtag;
            //    return Task.FromResult(successFileResponse);
            //}
            //catch (InvalidByteRangeException invalidByteRangeException)
            //{
            //    // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable)
            //    // including a Content-Range header with the current size.
            //    Tracer.TraceError(invalidByteRangeException);
            //    HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException);
            //    CloseReadStream();
            //    return Task.FromResult(invalidByteRangeResponse);
            //}
            //catch (Exception ex)
            //{
            //    // Could not read the file
            //    Tracer.TraceError(ex);
            //    HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
            //    CloseReadStream();
            //    return Task.FromResult(errorResponse);
            //}
        }
Beispiel #2
0
        protected override Task <HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
        {
            // Check whether we have a conditional If-None-Match request
            if (IsIfNoneMatchRequest(_currentEtag))
            {
                HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified);
                notModifiedResponse.Headers.ETag = _currentEtag;
                return(Task.FromResult(notModifiedResponse));
            }

            // Check whether we have a conditional range request containing both a Range and If-Range header field
            bool isRangeRequest = IsRangeRequest(_currentEtag);

            // Generate file response
            try
            {
                _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                MediaTypeHeaderValue mediaType           = MediaTypeMap.GetMediaType(info.Extension);
                HttpResponseMessage  successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);

                if (isRangeRequest)
                {
                    successFileResponse.Content = new ByteRangeStreamContent(_readStream, Request.Headers.Range, mediaType, BufferSize);
                }
                else
                {
                    successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                    successFileResponse.Content.Headers.ContentType = mediaType;
                }

                // Set etag for the file
                successFileResponse.Headers.ETag = _currentEtag;
                return(Task.FromResult(successFileResponse));
            }
            catch (InvalidByteRangeException invalidByteRangeException)
            {
                // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable)
                // including a Content-Range header with the current size.
                Tracer.TraceError(invalidByteRangeException);
                HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException);
                CloseReadStream();
                return(Task.FromResult(invalidByteRangeResponse));
            }
            catch (Exception ex)
            {
                // Could not read the file
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
                CloseReadStream();
                return(Task.FromResult(errorResponse));
            }
        }
        protected override async Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                HttpResponseMessage errorResponse;
                if (!PrepareBranch(itemExists, out errorResponse))
                {
                    return errorResponse;
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                // Get the query parameters
                QueryParameters parameters = new QueryParameters(this.Request);

                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Content.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message),
                            ex);
                        return conflictResponse;
                    }
                }

                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = true;

                // Commit to local branch
                bool commitResult = _repository.Commit(parameters.Message, authorName: null, emailAddress: null);
                if (!commitResult)
                {
                    HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                    return noChangeResponse;
                }

                bool rebasing = false;
                if (_currentEtag != null)
                {
                    try
                    {
                        // Only rebase if VFS branch isn't up-to-date already
                        if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch))
                        {
                            // Rebase to get updates from master while checking whether we get a conflict
                            rebasing = true;
                            updateBranchIsUpToDate = _repository.Rebase(MasterBranch);
                        }

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        if (rebasing)
                        {
                            // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                            // can see the conflicts and resubmit.
                            _cleanupRebaseConflict = true;
                            HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                            _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                            conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                            return conflictResponse;
                        }
                        else
                        {
                            HttpResponseMessage updateErrorResponse =
                               Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmUpdate_Error, commandLineException.Message));
                            return updateErrorResponse;
                        }
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result 
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                HttpResponseMessage successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.OK);
                        _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                        successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension);
                    }
                }
                else
                {
                    successFileResponse = Request.CreateResponse(HttpStatusCode.Created);
                }

                // Get current commit ID
                string currentId = _repository.CurrentId;

                // Deploy changes unless request indicated to not deploy
                if (!parameters.NoDeploy)
                {
                    DeployResult result = await DeployChangesAsync(currentId);
                    if (result != null && result.Status != DeployStatus.Success)
                    {
                        HttpResponseMessage deploymentErrorResponse =
                            Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText));
                        return deploymentErrorResponse;
                    }
                }

                // Set updated etag for the file
                successFileResponse.Headers.ETag = CreateEtag(currentId);
                return successFileResponse;
            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict,
                    RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex);
                return errorResponse;
            }
        }
        protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
        {
            // Check whether we have a conditional If-None-Match request
            if (IsIfNoneMatchRequest(_currentEtag))
            {
                HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified);
                notModifiedResponse.Headers.ETag = _currentEtag;
                return Task.FromResult(notModifiedResponse);
            }

            // Check whether we have a conditional range request containing both a Range and If-Range header field
            bool isRangeRequest = IsRangeRequest(_currentEtag);

            // Generate file response
            try
            {
                _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension);
                HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);

                if (isRangeRequest)
                {
                    successFileResponse.Content = new ByteRangeStreamContent(_readStream, Request.Headers.Range, mediaType, BufferSize);
                }
                else
                {
                    successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                    successFileResponse.Content.Headers.ContentType = mediaType;
                }

                // Set etag for the file
                successFileResponse.Headers.ETag = _currentEtag;
                return Task.FromResult(successFileResponse);
            }
            catch (InvalidByteRangeException invalidByteRangeException)
            {
                // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable)
                // including a Content-Range header with the current size.
                Tracer.TraceError(invalidByteRangeException);
                HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException);
                CloseReadStream();
                return Task.FromResult(invalidByteRangeResponse);
            }
            catch (Exception ex)
            {
                // Could not read the file
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
                CloseReadStream();
                return Task.FromResult(errorResponse);
            }
        }
Beispiel #5
0
        protected override async Task <IActionResult> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                if (!PrepareBranch(itemExists, out IActionResult errorResponse))
                {
                    return(errorResponse);
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                // Get the query parameters
                QueryParameters parameters = new QueryParameters(this.Request);

                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Body.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        return(StatusCode(StatusCodes.Status409Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
                    }
                }

                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = true;

                // Commit to local branch
                bool commitResult = _repository.Commit(parameters.Message, authorName: null, emailAddress: null);
                if (!commitResult)
                {
                    // TODO this is janky here, we return an actionresult but set the etag on the response directly
                    Response.GetTypedHeaders().ETag = CreateEtag(_repository.CurrentId);
                    return(NoContent());
                }

                bool rebasing = false;
                if (_currentEtag != null)
                {
                    try
                    {
                        // Only rebase if VFS branch isn't up-to-date already
                        if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch))
                        {
                            // Rebase to get updates from master while checking whether we get a conflict
                            rebasing = true;
                            updateBranchIsUpToDate = _repository.Rebase(MasterBranch);
                        }

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        if (rebasing)
                        {
                            // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                            // can see the conflicts and resubmit.
                            _cleanupRebaseConflict = true;

                            // CORE TODO not sure this works; I'm not sure you can set StatusCode for a File result
                            Response.StatusCode = StatusCodes.Status409Conflict;
                            _readStream         = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            // CORE TODO make sure mediatype.tostring works as intended here
                            return(File(_readStream, _conflictMediaType.ToString()));

                            //HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                            //_readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            //conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                            //conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                            //return conflictResponse;
                        }
                        else
                        {
                            return(StatusCode(StatusCodes.Status500InternalServerError,
                                              RS.Format(Resources.VfsScmUpdate_Error, commandLineException.Message)));
                        }
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                IActionResult successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = NoContent();
                    }
                    else
                    {
                        _readStream         = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse = File(_readStream, MediaTypeMap.GetMediaType(info.Extension).ToString());
                    }
                }
                else
                {
                    successFileResponse = StatusCode(StatusCodes.Status201Created);
                }

                // Get current commit ID
                string currentId = _repository.CurrentId;

                // Deploy changes unless request indicated to not deploy
                if (!parameters.NoDeploy)
                {
                    DeployResult result = await DeployChangesAsync(currentId);

                    if (result != null && result.Status != DeployStatus.Success)
                    {
                        return(StatusCode(StatusCodes.Status500InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText)));
                    }
                }

                // Set updated etag for the file
                Response.GetTypedHeaders().ETag = CreateEtag(currentId);
                return(successFileResponse);
            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                return(StatusCode(StatusCodes.Status409Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message)));
            }
        }
 private void CloseReadStream()
 {
     if (_readStream != null)
     {
         _readStream.Close();
         _readStream = null;
     }
 }
        protected override Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfo info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                HttpResponseMessage errorResponse;
                if (!PrepareBranch(itemExists, out errorResponse))
                {
                    return Task.FromResult(errorResponse);
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            Stream fileStream = null;
            try
            {
                fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists);
                return Request.Content.CopyToAsync(fileStream)
                    .Then(() =>
                    {
                        // Successfully saved the file
                        fileStream.Close();
                        fileStream = null;

                        // Use to track whether our rebase applied updates from master.
                        bool updateBranchIsUpToDate = false;

                        // Commit to local branch
                        ChangeSet commitResult = _repository.Commit(String.Format("Committing update from request {0}", Request.RequestUri), authorName: null);
                        if (commitResult == null)
                        {
                            HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                            noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                            return noChangeResponse;
                        }

                        if (_currentEtag != null)
                        {
                            try
                            {
                                // Rebase to get updates from master while checking whether we get a conflict
                                updateBranchIsUpToDate = _repository.Rebase(MasterBranch);

                                // Switch content back to master
                                _repository.UpdateRef(VfsUpdateBranch);
                            }
                            catch (CommandLineException commandLineException)
                            {
                                Tracer.TraceError(commandLineException);

                                // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                                // can see the conflicts and resubmit.
                                _cleanupRebaseConflict = true;
                                HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                                _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                                conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                                conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                                return conflictResponse;
                            }
                        }

                        // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result 
                        // in a non-conflicting merge we send back the committed version so that a client
                        // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                        HttpResponseMessage successFileResponse = null;
                        if (itemExists)
                        {
                            if (updateBranchIsUpToDate)
                            {
                                successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                            }
                            else
                            {
                                successFileResponse = Request.CreateResponse(HttpStatusCode.OK);
                                _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                                successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                                successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension);
                            }
                        }
                        else
                        {
                            successFileResponse = Request.CreateResponse(HttpStatusCode.Created);
                        }

                        // Set updated etag for the file
                        successFileResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                        return successFileResponse;
                    }, runSynchronously: true)
                    .Catch((catchInfo) =>
                    {
                        Tracer.TraceError(catchInfo.Exception);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath),
                            catchInfo.Exception);

                        if (fileStream != null)
                        {
                            fileStream.Close();
                        }

                        return catchInfo.Handled(conflictResponse);
                    });

            }
            catch (Exception e)
            {
                Tracer.TraceError(e);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict,
                    RS.Format(Resources.VfsController_WriteConflict, localFilePath), e);
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                return Task.FromResult(errorResponse);
            }
        }
        protected override async Task <HttpResponseMessage> CreateItemPutResponse(FileSystemInfo info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                HttpResponseMessage errorResponse;
                if (!PrepareBranch(itemExists, out errorResponse))
                {
                    return(errorResponse);
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Content.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath),
                            ex);
                        return(conflictResponse);
                    }
                }


                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = false;

                // Commit to local branch
                bool commitResult = _repository.Commit(String.Format("Committing update from request {0}", Request.RequestUri), authorName: null);
                if (!commitResult)
                {
                    HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                    return(noChangeResponse);
                }

                if (_currentEtag != null)
                {
                    try
                    {
                        // Rebase to get updates from master while checking whether we get a conflict
                        updateBranchIsUpToDate = _repository.Rebase(MasterBranch);

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                        // can see the conflicts and resubmit.
                        _cleanupRebaseConflict = true;
                        HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                        _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                        conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                        return(conflictResponse);
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                HttpResponseMessage successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        successFileResponse         = Request.CreateResponse(HttpStatusCode.OK);
                        _readStream                 = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                        successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension);
                    }
                }
                else
                {
                    successFileResponse = Request.CreateResponse(HttpStatusCode.Created);
                }

                // Deploy changes
                DeployResult result = DeployChanges();
                if (result != null && result.Status != DeployStatus.Success)
                {
                    HttpResponseMessage deploymentErrorResponse =
                        Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText));
                    return(deploymentErrorResponse);
                }

                // Set updated etag for the file
                successFileResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                return(successFileResponse);
            }
            catch (Exception e)
            {
                Tracer.TraceError(e);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict,
                                                                                RS.Format(Resources.VfsController_WriteConflict, localFilePath), e);
                return(errorResponse);
            }
        }