Adding reference source for System.Net
[mono.git] / mcs / class / referencesource / System / net / System / Net / filewebresponse.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="filewebresponse.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Net {
8     using System.Runtime.Serialization;
9     using System.IO;
10     using System.Globalization;
11     using System.Security.Permissions;
12     using System.Diagnostics.CodeAnalysis;
13
14     [Serializable]
15     public class FileWebResponse : WebResponse, ISerializable, ICloseEx
16     {
17         const int DefaultFileStreamBufferSize = 8192;
18         const string DefaultFileContentType = "application/octet-stream";
19
20     // fields
21
22         bool m_closed;
23         long m_contentLength;
24         FileAccess m_fileAccess;
25         WebHeaderCollection m_headers;
26         Stream m_stream;
27         Uri m_uri;
28
29     // constructors
30
31         internal FileWebResponse(FileWebRequest request, Uri uri, FileAccess access, bool asyncHint) {
32             GlobalLog.Enter("FileWebResponse::FileWebResponse", "uri="+uri+", access="+access+", asyncHint="+asyncHint);
33             try {
34                 m_fileAccess = access;
35                 if (access == FileAccess.Write) {
36                     m_stream = Stream.Null;
37                 } else {
38
39                     //
40                     // apparently, specifying async when the stream will be read
41                     // synchronously, or vice versa, can lead to a 10x perf hit.
42                     // While we don't know how the app will read the stream, we
43                     // use the hint from whether the app called BeginGetResponse
44                     // or GetResponse to supply the async flag to the stream ctor
45                     //
46
47                     m_stream = new FileWebStream(request,
48                                                  uri.LocalPath,
49                                                  FileMode.Open,
50                                                  FileAccess.Read,
51                                                  FileShare.Read,
52                                                  DefaultFileStreamBufferSize,
53                                                  asyncHint
54                                                  );
55                     m_contentLength = m_stream.Length;
56                 }
57                 m_headers = new WebHeaderCollection(WebHeaderCollectionType.FileWebResponse);
58                 m_headers.AddInternal(HttpKnownHeaderNames.ContentLength, m_contentLength.ToString(NumberFormatInfo.InvariantInfo));
59                 m_headers.AddInternal(HttpKnownHeaderNames.ContentType, DefaultFileContentType);
60                 m_uri = uri;
61             } catch (Exception e) {
62                 Exception ex = new WebException(e.Message, e, WebExceptionStatus.ConnectFailure, null);
63                 GlobalLog.LeaveException("FileWebResponse::FileWebResponse", ex);
64                 throw ex;
65             }            
66             GlobalLog.Leave("FileWebResponse::FileWebResponse");
67         }
68
69         //
70         // ISerializable constructor
71         //
72         [Obsolete("Serialization is obsoleted for this type. http://go.microsoft.com/fwlink/?linkid=14202")]
73         protected FileWebResponse(SerializationInfo serializationInfo, StreamingContext streamingContext):base(serializationInfo, streamingContext) {
74             m_headers       = (WebHeaderCollection)serializationInfo.GetValue("headers", typeof(WebHeaderCollection));
75             m_uri           = (Uri)serializationInfo.GetValue("uri", typeof(Uri));
76             m_contentLength = serializationInfo.GetInt64("contentLength");
77             m_fileAccess    = (FileAccess )serializationInfo.GetInt32("fileAccess");
78         }
79
80         //
81         // ISerializable method
82         //
83         /// <internalonly/>
84         [SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase", Justification = "System.dll is still using pre-v4 security model and needs this demand")]
85         [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.SerializationFormatter, SerializationFormatter=true)]
86         void ISerializable.GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
87         {
88             GetObjectData(serializationInfo, streamingContext);
89         }
90
91         //
92         // FxCop: provide some way for derived classes to access GetObjectData even if the derived class
93         // explicitly re-inherits ISerializable.
94         //
95         [SecurityPermission(SecurityAction.Demand, SerializationFormatter=true)]
96         protected override void GetObjectData(SerializationInfo serializationInfo, StreamingContext streamingContext)
97         {
98             serializationInfo.AddValue("headers", m_headers, typeof(WebHeaderCollection));
99             serializationInfo.AddValue("uri", m_uri, typeof(Uri));
100             serializationInfo.AddValue("contentLength", m_contentLength);
101             serializationInfo.AddValue("fileAccess", m_fileAccess);
102             base.GetObjectData(serializationInfo, streamingContext);
103         }
104
105     // properties
106
107         public override long ContentLength {
108             get {
109                 CheckDisposed();
110                 return m_contentLength;
111             }
112         }
113
114         public override string ContentType {
115             get {
116                 CheckDisposed();
117                 return DefaultFileContentType;
118             }
119         }
120
121         public override WebHeaderCollection Headers {
122             get {
123                 CheckDisposed();
124                 return m_headers;
125             }
126         }
127         
128         // For portability only
129         public override bool SupportsHeaders {
130             get {
131                 return true;
132             }
133         }
134
135         public override Uri ResponseUri {
136             get {
137                 CheckDisposed();
138                 return m_uri;
139             }
140         }
141
142     // methods
143
144         private void CheckDisposed() {
145             if (m_closed) {
146                 throw new ObjectDisposedException(this.GetType().FullName);
147             }
148         }
149
150         public override void Close() {
151             ((ICloseEx)this).CloseEx(CloseExState.Normal);
152         }
153
154         void ICloseEx.CloseEx(CloseExState closeState) {
155             GlobalLog.Enter("FileWebResponse::Close()");
156             try {
157                 if (!m_closed) {
158                     m_closed = true;
159
160                     Stream chkStream = m_stream;
161                     if (chkStream!=null) {
162                         if (chkStream is ICloseEx)
163                             ((ICloseEx)chkStream).CloseEx(closeState);
164                         else
165                             chkStream.Close();
166                         m_stream = null;
167                     }
168                 }
169             }
170             finally {
171                 GlobalLog.Leave("FileWebResponse::Close()");
172             }
173         }
174
175         public override Stream GetResponseStream() {
176             GlobalLog.Enter("FileWebResponse::GetResponseStream()");
177             try {
178                 CheckDisposed();
179             }
180             finally {
181                 GlobalLog.Leave("FileWebResponse::GetResponseStream()");
182             }
183             return m_stream;
184         }
185     }
186 }