2 // System.Net.FileWebRequest
\r
5 // Lawrence Pit (loz@cable.a2000.nl)
\r
9 using System.Collections;
\r
11 using System.Runtime.Serialization;
\r
12 using System.Runtime.Remoting.Messaging;
\r
13 using System.Threading;
\r
15 namespace System.Net
\r
18 public class FileWebRequest : WebRequest, ISerializable
\r
21 private WebHeaderCollection webHeaders;
\r
23 private ICredentials credentials;
\r
24 private string connectionGroup;
\r
25 private string method = "GET";
\r
26 private int timeout = 100000;
\r
28 private Stream requestStream;
\r
29 private FileWebResponse webResponse;
\r
30 private AutoResetEvent requestEndEvent;
\r
31 private bool requesting;
\r
32 private bool asyncResponding;
\r
36 internal FileWebRequest (Uri uri)
\r
39 this.webHeaders = new WebHeaderCollection ();
\r
42 protected FileWebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
\r
44 SerializationInfo info = serializationInfo;
\r
46 method = info.GetString ("method");
\r
47 uri = (Uri) info.GetValue ("uri", typeof (Uri));
\r
48 timeout = info.GetInt32 ("timeout");
\r
49 connectionGroup = info.GetString ("connectionGroup");
\r
50 webHeaders = (WebHeaderCollection) info.GetValue ("webHeaders", typeof (WebHeaderCollection));
\r
55 // currently not used according to spec
\r
56 public override string ConnectionGroupName {
\r
57 get { return connectionGroup; }
\r
58 set { connectionGroup = value; }
\r
61 public override long ContentLength {
\r
64 return Int64.Parse (webHeaders ["Content-Length"]);
\r
65 } catch (Exception) {
\r
71 throw new ArgumentException ("value");
\r
72 webHeaders ["Content-Length"] = Convert.ToString (value);
\r
76 public override string ContentType {
\r
77 get { return webHeaders ["Content-Type"]; }
\r
78 set { webHeaders ["Content-Type"] = value; }
\r
81 public override ICredentials Credentials {
\r
82 get { return credentials; }
\r
83 set { credentials = value; }
\r
86 public override WebHeaderCollection Headers {
\r
87 get { return webHeaders; }
\r
90 // currently not used according to spec
\r
91 public override string Method {
\r
92 get { return this.method; }
\r
93 set { this.method = value; }
\r
96 // currently not used according to spec
\r
97 public override bool PreAuthenticate {
\r
98 get { throw new NotSupportedException (); }
\r
99 set { throw new NotSupportedException (); }
\r
102 // currently not used according to spec
\r
103 public override IWebProxy Proxy {
\r
104 get { throw new NotSupportedException (); }
\r
105 set { throw new NotSupportedException (); }
\r
108 public override Uri RequestUri {
\r
109 get { return this.uri; }
\r
112 public override int Timeout {
\r
113 get { return timeout; }
\r
116 throw new ArgumentException ("value");
\r
123 private delegate Stream GetRequestStreamCallback ();
\r
124 private delegate WebResponse GetResponseCallback ();
\r
126 public override IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
\r
128 if (method == null || (!method.Equals ("PUT") && !method.Equals ("POST")))
\r
129 throw new ProtocolViolationException ("Cannot send file when method is: " + this.method + ". Method must be PUT.");
\r
130 // workaround for bug 24943
\r
131 Exception e = null;
\r
133 if (asyncResponding || webResponse != null)
\r
134 e = new InvalidOperationException ("This operation cannot be performed after the request has been submitted.");
\r
135 else if (requesting)
\r
136 e = new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
144 if (asyncResponding || webResponse != null)
\r
145 throw new InvalidOperationException ("This operation cannot be performed after the request has been submitted.");
\r
147 throw new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
151 GetRequestStreamCallback c = new GetRequestStreamCallback (this.GetRequestStreamInternal);
\r
152 return c.BeginInvoke (callback, state);
\r
155 public override Stream EndGetRequestStream (IAsyncResult asyncResult)
\r
157 if (asyncResult == null)
\r
158 throw new ArgumentNullException ("asyncResult");
\r
159 if (!asyncResult.IsCompleted)
\r
160 asyncResult.AsyncWaitHandle.WaitOne ();
\r
161 AsyncResult async = (AsyncResult) asyncResult;
\r
162 GetRequestStreamCallback cb = (GetRequestStreamCallback) async.AsyncDelegate;
\r
163 return cb.EndInvoke (asyncResult);
\r
166 public override Stream GetRequestStream()
\r
168 IAsyncResult asyncResult = BeginGetRequestStream (null, null);
\r
169 if (!(asyncResult.AsyncWaitHandle.WaitOne (timeout, false))) {
\r
170 throw new WebException("The request timed out", WebExceptionStatus.Timeout);
\r
172 return EndGetRequestStream (asyncResult);
\r
175 internal Stream GetRequestStreamInternal ()
\r
177 this.requestStream = new FileWebStream (
\r
179 FileMode.CreateNew,
\r
182 return this.requestStream;
\r
185 public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
\r
187 // workaround for bug 24943
\r
188 Exception e = null;
\r
190 if (asyncResponding)
\r
191 e = new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
193 asyncResponding = true;
\r
199 if (asyncResponding)
\r
200 throw new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
201 asyncResponding = true;
\r
204 GetResponseCallback c = new GetResponseCallback (this.GetResponseInternal);
\r
205 return c.BeginInvoke (callback, state);
\r
208 public override WebResponse EndGetResponse (IAsyncResult asyncResult)
\r
210 if (asyncResult == null)
\r
211 throw new ArgumentNullException ("asyncResult");
\r
212 if (!asyncResult.IsCompleted)
\r
213 asyncResult.AsyncWaitHandle.WaitOne ();
\r
214 AsyncResult async = (AsyncResult) asyncResult;
\r
215 GetResponseCallback cb = (GetResponseCallback) async.AsyncDelegate;
\r
216 WebResponse webResponse = cb.EndInvoke(asyncResult);
\r
217 asyncResponding = false;
\r
218 return webResponse;
\r
221 public override WebResponse GetResponse ()
\r
223 IAsyncResult asyncResult = BeginGetResponse (null, null);
\r
224 if (!(asyncResult.AsyncWaitHandle.WaitOne (timeout, false))) {
\r
225 throw new WebException("The request timed out", WebExceptionStatus.Timeout);
\r
227 return EndGetResponse (asyncResult);
\r
230 WebResponse GetResponseInternal ()
\r
232 if (webResponse != null)
\r
233 return webResponse;
\r
236 requestEndEvent = new AutoResetEvent (false);
\r
239 if (requestEndEvent != null) {
\r
240 requestEndEvent.WaitOne ();
\r
242 FileStream fileStream = new FileWebStream (
\r
247 this.webResponse = new FileWebResponse (this.uri, fileStream);
\r
248 return (WebResponse) this.webResponse;
\r
251 void ISerializable.GetObjectData (SerializationInfo serializationInfo, StreamingContext streamingContext)
\r
253 SerializationInfo info = serializationInfo;
\r
255 info.AddValue ("method", method);
\r
256 info.AddValue ("uri", uri, typeof (Uri));
\r
257 info.AddValue ("timeout", timeout);
\r
258 info.AddValue ("connectionGroup", connectionGroup);
\r
259 info.AddValue ("webHeaders", webHeaders, typeof (WebHeaderCollection));
\r
262 internal void Close ()
\r
264 // already done in class below
\r
265 // if (requestStream != null) {
\r
266 // requestStream.Close ();
\r
270 requesting = false;
\r
271 if (requestEndEvent != null)
\r
272 requestEndEvent.Set ();
\r
273 // requestEndEvent = null;
\r
277 // to catch the Close called on the FileStream
\r
278 internal class FileWebStream : FileStream
\r
280 FileWebRequest webRequest;
\r
282 internal FileWebStream (FileWebRequest webRequest,
\r
286 : base (webRequest.RequestUri.LocalPath,
\r
287 mode, access, share)
\r
289 this.webRequest = webRequest;
\r
292 public override void Close()
\r
295 FileWebRequest req = webRequest;
\r