in src/WebJobs.Script.WebHost/Management/VirtualFileSystem.cs [259:333]
protected Task<HttpResponseMessage> CreateItemGetResponse(HttpRequest request, FileSystemInfoBase info, string localFilePath)
{
// Get current etag
var currentEtag = CreateEntityTag(info);
var lastModified = info.LastWriteTimeUtc;
// Check whether we have a range request (taking If-Range condition into account)
bool isRangeRequest = IsRangeRequest(request, currentEtag);
// Check whether we have a conditional If-None-Match request
// Unless it is a range request (see RFC2616 sec 14.35.2 Range Retrieval Requests)
if (!isRangeRequest && IsIfNoneMatchRequest(request, currentEtag.ToSystemETag()))
{
var notModifiedResponse = CreateResponse(HttpStatusCode.NotModified);
notModifiedResponse.SetEntityTagHeader(currentEtag.ToSystemETag(), lastModified);
return Task.FromResult(notModifiedResponse);
}
// Generate file response
Stream fileStream = null;
try
{
fileStream = GetFileReadStream(localFilePath);
var mediaType = MediaTypeMap.GetMediaType(info.Extension);
var successFileResponse = CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);
if (isRangeRequest)
{
var typedHeaders = request.GetTypedHeaders();
var rangeHeader = new RangeHeaderValue
{
Unit = typedHeaders.Range.Unit.Value
};
foreach (var range in typedHeaders.Range.Ranges)
{
rangeHeader.Ranges.Add(new RangeItemHeaderValue(range.From, range.To));
}
successFileResponse.Content = new ByteRangeStreamContent(fileStream, rangeHeader, mediaType, BufferSize);
}
else
{
successFileResponse.Content = new StreamContent(fileStream, BufferSize);
successFileResponse.Content.Headers.ContentType = mediaType;
}
// Set etag for the file
successFileResponse.SetEntityTagHeader(currentEtag.ToSystemETag(), lastModified);
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.
_logger.LogWarning(invalidByteRangeException.Message);
var invalidByteRangeResponse = CreateResponse(HttpStatusCode.RequestedRangeNotSatisfiable, invalidByteRangeException);
if (fileStream != null)
{
fileStream.Close();
}
return Task.FromResult(invalidByteRangeResponse);
}
catch (Exception ex)
{
// Could not read the file
_logger.LogError(ex, "Unable to read file: " + ex.Message);
var errorResponse = CreateResponse(HttpStatusCode.NotFound, ex);
if (fileStream != null)
{
fileStream.Close();
}
return Task.FromResult(errorResponse);
}
}