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;
\r
26 private int timeout;
\r
28 private Stream requestStream = null;
\r
29 private FileWebResponse webResponse = null;
\r
30 private AutoResetEvent requestEndEvent = null;
\r
31 private bool requesting = false;
\r
32 private bool asyncResponding = false;
\r
36 internal FileWebRequest (Uri uri)
\r
39 this.webHeaders = new WebHeaderCollection ();
\r
40 this.method = "GET";
\r
41 this.timeout = System.Threading.Timeout.Infinite;
\r
45 protected FileWebRequest (SerializationInfo serializationInfo, StreamingContext streamingContext)
\r
47 throw new NotImplementedException ();
\r
52 // currently not used according to spec
\r
53 public override string ConnectionGroupName {
\r
54 get { return connectionGroup; }
\r
55 set { connectionGroup = value; }
\r
58 public override long ContentLength {
\r
61 return Int64.Parse (webHeaders ["Content-Length"]);
\r
62 } catch (Exception) {
\r
68 throw new ArgumentException ("value");
\r
69 webHeaders ["Content-Length"] = Convert.ToString (value);
\r
73 public override string ContentType {
\r
74 get { return webHeaders ["Content-Type"]; }
\r
75 set { webHeaders ["Content-Type"] = value; }
\r
78 public override ICredentials Credentials {
\r
79 get { return credentials; }
\r
80 set { credentials = value; }
\r
83 public override WebHeaderCollection Headers {
\r
84 get { return webHeaders; }
\r
87 // currently not used according to spec
\r
88 public override string Method {
\r
89 get { return this.method; }
\r
90 set { this.method = value; }
\r
93 // currently not used according to spec
\r
94 public override bool PreAuthenticate {
\r
95 get { throw new NotSupportedException (); }
\r
96 set { throw new NotSupportedException (); }
\r
99 // currently not used according to spec
\r
100 public override IWebProxy Proxy {
\r
101 get { throw new NotSupportedException (); }
\r
102 set { throw new NotSupportedException (); }
\r
105 public override Uri RequestUri {
\r
106 get { return this.uri; }
\r
109 public override int Timeout {
\r
110 get { return timeout; }
\r
113 throw new ArgumentException ("value");
\r
120 private delegate Stream GetRequestStreamCallback ();
\r
121 private delegate WebResponse GetResponseCallback ();
\r
123 public override IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state)
\r
125 if (method == null || (!method.Equals ("PUT") && !method.Equals ("POST")))
\r
126 throw new ProtocolViolationException ("Cannot send file when method is: " + this.method + ". Method must be PUT.");
\r
127 // workaround for bug 24943
\r
128 Exception e = null;
\r
130 if (asyncResponding || webResponse != null)
\r
131 e = new InvalidOperationException ("This operation cannot be performed after the request has been submitted.");
\r
132 else if (requesting)
\r
133 e = new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
141 if (asyncResponding || webResponse != null)
\r
142 throw new InvalidOperationException ("This operation cannot be performed after the request has been submitted.");
\r
144 throw new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
148 GetRequestStreamCallback c = new GetRequestStreamCallback (this.GetRequestStreamInternal);
\r
149 return c.BeginInvoke (callback, state);
\r
152 public override Stream EndGetRequestStream (IAsyncResult asyncResult)
\r
154 if (asyncResult == null)
\r
155 throw new ArgumentNullException ("asyncResult");
\r
156 if (!asyncResult.IsCompleted)
\r
157 asyncResult.AsyncWaitHandle.WaitOne ();
\r
158 AsyncResult async = (AsyncResult) asyncResult;
\r
159 GetRequestStreamCallback cb = (GetRequestStreamCallback) async.AsyncDelegate;
\r
160 return cb.EndInvoke (asyncResult);
\r
163 public override Stream GetRequestStream()
\r
165 IAsyncResult asyncResult = BeginGetRequestStream (null, null);
\r
166 if (!(asyncResult.AsyncWaitHandle.WaitOne (timeout, false))) {
\r
167 throw new WebException("The request timed out", WebExceptionStatus.Timeout);
\r
169 return EndGetRequestStream (asyncResult);
\r
172 internal Stream GetRequestStreamInternal ()
\r
174 this.requestStream = new FileWebStream (
\r
176 FileMode.CreateNew,
\r
179 return this.requestStream;
\r
182 public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
\r
184 // workaround for bug 24943
\r
185 Exception e = null;
\r
187 if (asyncResponding)
\r
188 e = new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
190 asyncResponding = true;
\r
196 if (asyncResponding)
\r
197 throw new InvalidOperationException ("Cannot re-call start of asynchronous method while a previous call is still in progress.");
\r
198 asyncResponding = true;
\r
201 GetResponseCallback c = new GetResponseCallback (this.GetResponseInternal);
\r
202 return c.BeginInvoke (callback, state);
\r
205 public override WebResponse EndGetResponse (IAsyncResult asyncResult)
\r
207 if (asyncResult == null)
\r
208 throw new ArgumentNullException ("asyncResult");
\r
209 if (!asyncResult.IsCompleted)
\r
210 asyncResult.AsyncWaitHandle.WaitOne ();
\r
211 AsyncResult async = (AsyncResult) asyncResult;
\r
212 GetResponseCallback cb = (GetResponseCallback) async.AsyncDelegate;
\r
213 WebResponse webResponse = cb.EndInvoke(asyncResult);
\r
214 asyncResponding = false;
\r
215 return webResponse;
\r
218 public override WebResponse GetResponse ()
\r
220 IAsyncResult asyncResult = BeginGetResponse (null, null);
\r
221 if (!(asyncResult.AsyncWaitHandle.WaitOne (timeout, false))) {
\r
222 throw new WebException("The request timed out", WebExceptionStatus.Timeout);
\r
224 return EndGetResponse (asyncResult);
\r
227 public WebResponse GetResponseInternal ()
\r
229 if (webResponse != null)
\r
230 return webResponse;
\r
233 requestEndEvent = new AutoResetEvent (false);
\r
236 if (requestEndEvent != null) {
\r
237 requestEndEvent.WaitOne ();
\r
239 FileStream fileStream = new FileWebStream (
\r
244 this.webResponse = new FileWebResponse (this.uri, fileStream);
\r
245 return (WebResponse) this.webResponse;
\r
249 void ISerializable.GetObjectData (SerializationInfo serializationInfo,
\r
250 StreamingContext streamingContext)
\r
252 throw new NotImplementedException ();
\r
255 internal void Close ()
\r
257 // already done in class below
\r
258 // if (requestStream != null) {
\r
259 // requestStream.Close ();
\r
263 requesting = false;
\r
264 if (requestEndEvent != null)
\r
265 requestEndEvent.Set ();
\r
266 // requestEndEvent = null;
\r
270 // to catch the Close called on the FileStream
\r
271 internal class FileWebStream : FileStream
\r
273 FileWebRequest webRequest;
\r
275 internal FileWebStream (FileWebRequest webRequest,
\r
279 : base (webRequest.RequestUri.LocalPath,
\r
280 mode, access, share)
\r
282 this.webRequest = webRequest;
\r
285 public override void Close()
\r
288 FileWebRequest req = webRequest;
\r