|
//------------------------------------------------------------------------------
// <copyright file="filewebresponse.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
//------------------------------------------------------------------------------
namespace System.Net {
using System.Runtime.Serialization;
using System.IO;
using System.Globalization;
using System.Security.Permissions;
using System.Diagnostics.CodeAnalysis;
[Serializable]
public class FileWebResponse : WebResponse, ISerializable, ICloseEx
{
const int DefaultFileStreamBufferSize = 8192;
const string DefaultFileContentType = "application/octet-stream";
// fields
bool m_closed;
long m_contentLength;
FileAccess m_fileAccess;
WebHeaderCollection m_headers;
Stream m_stream;
Uri m_uri;
// constructors
internal FileWebResponse(FileWebRequest request, Uri uri, FileAccess access, bool asyncHint) {
GlobalLog.Enter("FileWebResponse::FileWebResponse", "uri="+uri+", access="+access+", asyncHint="+asyncHint);
try {
m_fileAccess = access;
if (access == FileAccess.Write) {
m_stream = Stream.Null;
} else {
//
// apparently, specifying async when the stream will be read
// synchronously, or vice versa, can lead to a 10x perf hit.
// While we don't know how the app will read the stream, we
// use the hint from whether the app called BeginGetResponse
// or GetResponse to supply the async flag to the stream ctor
//
m_stream = new FileWebStream(request,
uri.LocalPath,
FileMode.Open,
FileAccess.Read,
FileShare.Read,
DefaultFileStreamBufferSize,
asyncHint
);
m_contentLength = m_stream.Length;
}
m_headers = new WebHeaderCollection(WebHeaderCollectionType.FileWebResponse);
m_headers.AddInternal(HttpKnownHeaderNames.ContentLength, m_contentLength.ToString(NumberFormatInfo.InvariantInfo));
m_headers.AddInternal(HttpKnownHeaderNames.ContentType, DefaultFileContentType);
m_uri = uri;
} catch (Exception e) {
Exception ex = new WebException(e.Message, e, WebExceptionStatus.ConnectFailure, null);
GlobalLog.LeaveException("FileWebResponse::FileWebResponse", ex);
throw ex;
}
GlobalLog.Leave("FileWebResponse::FileWebResponse");
}
//
// ISerializable constructor
//
[Obsolete("Serialization is obsoleted for this type. http://go.microsoft.com/fwlink/?linkid=14202")]
protected FileWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext):base(serializationInfo, streamingContext) {
m_headers = (WebHeaderCollection)serializationInfo.GetValue("headers", typeof(WebHeaderCollection));
m_uri = (Uri)serializationInfo.GetValue("uri", typeof(Uri));
m_contentLength = serializationInfo.GetInt64("contentLength");
m_fileAccess = (FileAccess )serializationInfo.GetInt32("fileAccess");
}
//
// ISerializable method
//
/// <internalonly/>
[SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
[SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter, SerializationFormatter=true)]
void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
{
GetObjectData(serializationInfo, streamingContext);
}
//
// FxCop: provide some way for derived classes to access GetObjectData even if the derived class
// explicitly re-inherits ISerializable.
//
[SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)]
protected override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
{
serializationInfo.AddValue("headers", m_headers, typeof(WebHeaderCollection));
serializationInfo.AddValue("uri", m_uri, typeof(Uri));
serializationInfo.AddValue("contentLength", m_contentLength);
serializationInfo.AddValue("fileAccess", m_fileAccess);
base.GetObjectData(serializationInfo, streamingContext);
}
// properties
public override long ContentLength {
get {
CheckDisposed();
return m_contentLength;
}
}
public override string ContentType {
get {
CheckDisposed();
return DefaultFileContentType;
}
}
public override WebHeaderCollection Headers {
get {
CheckDisposed();
return m_headers;
}
}
// For portability only
public override bool SupportsHeaders {
get {
return true;
}
}
public override Uri ResponseUri {
get {
CheckDisposed();
return m_uri;
}
}
// methods
private void CheckDisposed() {
if (m_closed) {
throw new ObjectDisposedException(this.GetType().FullName);
}
}
public override void Close() {
((ICloseEx)this).CloseEx(CloseExState.Normal);
}
void ICloseEx.CloseEx(CloseExState closeState) {
GlobalLog.Enter("FileWebResponse::Close()");
try {
if (!m_closed) {
m_closed = true;
Stream chkStream = m_stream;
if (chkStream!=null) {
if (chkStream is ICloseEx)
((ICloseEx)chkStream).CloseEx(closeState);
else
chkStream.Close();
m_stream = null;
}
}
}
finally {
GlobalLog.Leave("FileWebResponse::Close()");
}
}
public override Stream GetResponseStream() {
GlobalLog.Enter("FileWebResponse::GetResponseStream()");
try {
CheckDisposed();
}
finally {
GlobalLog.Leave("FileWebResponse::GetResponseStream()");
}
return m_stream;
}
}
}
|