3 using System.Collections;
\r
4 using System.Collections.Specialized;
\r
5 using System.Configuration;
\r
6 using System.Globalization;
\r
8 using System.Runtime;
\r
9 using System.Runtime.CompilerServices;
\r
10 using System.Runtime.Serialization;
\r
11 using System.Security;
\r
12 using System.Security.Cryptography.X509Certificates;
\r
13 using System.Security.Permissions;
\r
15 using System.Threading;
\r
18 namespace System.Net
\r
21 public class HttpWebRequest : WebRequest
\r
26 private static readonly int DEFAULT_MAX_RESP_HEADER_LEN = 64;
\r
28 private static int _defaultMaxResponseHeadersLength = DEFAULT_MAX_RESP_HEADER_LEN;
\r
31 private HttpProvider _provider;
\r
35 #region Constructors
\r
37 internal HttpWebRequest(Uri uri)
\r
39 _provider = HttpProvider.GetHttpProvider(uri);
\r
40 // Console.WriteLine("uri to string: " + uri.ToString());
\r
49 public string Accept
\r
51 get{return Headers["Accept"];}
\r
54 if(_provider.IsRequestStarted ())
\r
55 throw new InvalidOperationException ("request started");
\r
56 _provider.Headers.RemoveAndAdd ("Accept", value);
\r
62 get{return _provider.GetAddress();}
\r
65 public bool AllowAutoRedirect
\r
67 get{return _provider.AllowAutoRedirect;}
\r
68 set{_provider.AllowAutoRedirect = value;}
\r
71 public bool AllowWriteStreamBuffering
\r
73 get{return _provider.AllowWriteStreamBuffering;}
\r
74 set{_provider.AllowWriteStreamBuffering = value;}
\r
77 [MonoTODO] //documentation related
\r
78 public X509CertificateCollection ClientCertificates
\r
81 get{return _provider.GetX509Certificates();}
\r
84 public string Connection
\r
86 get { return Headers["Connection"]; }
\r
89 if(_provider.IsRequestStarted())
\r
90 throw new InvalidOperationException ("request started");
\r
94 val = val.Trim ().ToLower ();
\r
96 if (val == null || val.Length == 0)
\r
98 Headers.RemoveInternal ("Connection");
\r
102 if (val == "keep-alive" || val == "close")
\r
103 throw new ArgumentException ("Keep-Alive and Close may not be set with this property");
\r
105 // if (this.KeepAlive && val.IndexOf ("keep-alive") == -1)
\r
106 // value = value + ", Keep-Alive";
\r
108 Headers.RemoveAndAdd ("Connection", value);
\r
112 public override string ConnectionGroupName
\r
114 get{return _provider.ConnectionGroupName;}
\r
115 set{_provider.ConnectionGroupName = value;}
\r
118 public override long ContentLength
\r
120 get{return _provider.ContentLength;}
\r
123 if(_provider.IsRequestStarted())
\r
124 throw new InvalidOperationException("Connection already opened");
\r
125 _provider.ContentLength = value;
\r
129 public override string ContentType
\r
131 get { return Headers["Content-Type"]; }
\r
134 if (value == null || value.Trim().Length == 0)
\r
136 Headers.RemoveInternal ("Content-Type");
\r
139 Headers.RemoveAndAdd ("Content-Type", value);
\r
142 [MonoTODO] //needed for automatic documentation tools,
\r
143 //since currently we don't support this feature
\r
144 public HttpContinueDelegate ContinueDelegate
\r
147 get{return _provider.ContinueDelegate;}
\r
149 set{_provider.ContinueDelegate = value;}
\r
152 public CookieContainer CookieContainer
\r
154 get{return _provider.CookieContainer;}
\r
155 set{_provider.CookieContainer = value;}
\r
158 public override ICredentials Credentials
\r
160 get{return _provider.Credentials;}
\r
161 set{_provider.Credentials = value;}
\r
164 public static int DefaultMaximumResponseHeadersLength
\r
166 get{return HttpProvider.DefaultMaxResponseHeadersLength;}
\r
167 set{HttpProvider.DefaultMaxResponseHeadersLength = value;}
\r
170 public string Expect
\r
172 get{return Headers["Expect"];}
\r
175 if(_provider.IsRequestStarted ())
\r
176 throw new InvalidOperationException("Connection already opened");
\r
177 string val = value;
\r
179 val = val.Trim ().ToLower ();
\r
181 if (val == null || val.Length == 0)
\r
183 Headers.RemoveInternal ("Expect");
\r
187 if (val == "100-continue")
\r
188 throw new ArgumentException ("100-Continue cannot be set with this property.",
\r
190 Headers.RemoveAndAdd ("Expect", value);
\r
194 public bool HaveResponse
\r
196 get{return _provider.IsHaveResponse();}
\r
199 public override WebHeaderCollection Headers
\r
201 get{return _provider.Headers;}
\r
202 set{_provider.Headers = value;}
\r
205 public DateTime IfModifiedSince
\r
209 string str = Headers["If-Modified-Since"];
\r
211 return DateTime.Now;
\r
214 return MonoHttpDate.Parse (str);
\r
218 return DateTime.Now;
\r
223 if(_provider.IsRequestStarted ())
\r
224 throw new InvalidOperationException("Connection already started");
\r
225 // rfc-1123 pattern
\r
226 Headers.SetInternal ("If-Modified-Since",
\r
227 value.ToUniversalTime ().ToString ("r", null));
\r
228 // TODO: check last param when using different locale
\r
232 public bool KeepAlive
\r
234 get{return _provider.KeepAlive;}
\r
235 set{_provider.KeepAlive = value;}
\r
238 public int MaximumAutomaticRedirections
\r
240 get{return _provider.MaxAutoRedirections;}
\r
241 set{_provider.MaxAutoRedirections = value;}
\r
244 [MonoTODO] //documentation
\r
245 public int MaximumResponseHeadersLength
\r
248 get{return _provider.MaximumResponseHeadersLength;}
\r
250 set{_provider.MaximumResponseHeadersLength = value;}
\r
253 public string MediaType
\r
255 get{return _provider.MediaType;}
\r
256 set{_provider.MediaType = value;}
\r
259 public override string Method
\r
261 get{return _provider.MethodName;}
\r
262 set{_provider.MethodName = value;}
\r
264 [MonoTODO] //for documentation related - limited.
\r
265 public bool Pipelined
\r
268 get{return _provider.Pipelined;}
\r
270 set{_provider.Pipelined = value;}
\r
273 public override bool PreAuthenticate
\r
275 get{return _provider.PreAuthenticate;}
\r
276 set{_provider.PreAuthenticate = value;}
\r
279 public Version ProtocolVersion
\r
281 get{return _provider.ProtocolVersion;}
\r
282 set{_provider.ProtocolVersion = value;}
\r
285 public override IWebProxy Proxy
\r
287 get{return _provider.Proxy;}
\r
288 set{_provider.Proxy = value;}
\r
291 public int ReadWriteTimeout
\r
293 get{return _provider.ReadWriteTimeout;}
\r
294 set{_provider.ReadWriteTimeout = value;}
\r
297 public string Referer
\r
299 get {return Headers["Referer"];}
\r
302 if(_provider.IsRequestStarted ())
\r
303 throw new InvalidOperationException("Connection already opened");
\r
304 if (value == null || value.Trim().Length == 0)
\r
306 Headers.RemoveInternal ("Referer");
\r
309 Headers.SetInternal ("Referer", value);
\r
312 internal Uri AuthUri
\r
314 get { return RequestUri; }
\r
316 public override Uri RequestUri
\r
318 get{return _provider.GetOriginalAddress();}
\r
321 public bool SendChunked
\r
323 get{return _provider.SendChunked;}
\r
324 set{_provider.SendChunked = value;}
\r
327 public ServicePoint ServicePoint
\r
329 get{return _provider.ServicePoint;}
\r
331 [MonoTODO] //once again - needed since our impl. still
\r
332 //doesn't support this feature we need document it..
\r
333 public override int Timeout
\r
336 get{return _provider.Timeout;}
\r
338 set{_provider.Timeout = value;}
\r
342 public string TransferEncoding
\r
344 get { return Headers ["Transfer-Encoding"]; }
\r
347 if(_provider.IsRequestStarted ())
\r
349 throw new InvalidOperationException("Connection has been already opened");
\r
351 string val = value;
\r
353 val = val.Trim ().ToLower ();
\r
355 if (val == null || val.Length == 0)
\r
357 Headers.RemoveInternal ("Transfer-Encoding");
\r
361 if (val == "chunked")
\r
362 throw new ArgumentException ("Chunked encoding must be set with the SendChunked property");
\r
364 if (!this.SendChunked)
\r
365 throw new InvalidOperationException ("SendChunked must be True");
\r
367 Headers.RemoveAndAdd ("Transfer-Encoding", value);
\r
372 public bool UnsafeAuthenticatedConnectionSharing
\r
374 get { throw new NotImplementedException (); }
\r
375 set { throw new NotImplementedException (); }
\r
378 public string UserAgent
\r
380 get { return Headers ["User-Agent"]; }
\r
381 set { Headers.SetInternal ("User-Agent", value); }
\r
392 public override void Abort()
\r
395 // _connection.disconnect();
\r
396 // _haveResponse = true;
\r
397 // //aborted = true;
\r
398 // if (_asyncWrite != null)
\r
400 // GHWebAsyncResult r = _asyncWrite;
\r
401 // WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled);
\r
402 // r.SetCompleted (false, wexc);
\r
403 // r.DoCallback ();
\r
404 // _asyncWrite = null;
\r
407 // if (_asyncRead != null)
\r
409 // GHWebAsyncResult r = _asyncRead;
\r
410 // WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled);
\r
411 // r.SetCompleted (false, wexc);
\r
412 // r.DoCallback ();
\r
413 // _asyncRead = null;
\r
416 //// if (abortHandler != null)
\r
420 //// abortHandler (this, EventArgs.Empty);
\r
423 //// abortHandler = null;
\r
426 // if (_writeStream != null)
\r
430 // _writeStream.Close ();
\r
431 // _writeStream = null;
\r
436 // if (_response != null)
\r
440 // _response.Close ();
\r
441 // _response = null;
\r
447 public void AddRange (int range)
\r
449 AddRange ("bytes", range);
\r
452 public void AddRange (int from, int to)
\r
454 AddRange ("bytes", from, to);
\r
457 public void AddRange (string rangeSpecifier, int range)
\r
459 if (rangeSpecifier == null)
\r
460 throw new ArgumentNullException ("rangeSpecifier");
\r
461 string value = Headers ["Range"];
\r
462 if (value == null || value.Length == 0)
\r
463 value = rangeSpecifier + "=";
\r
464 else if (value.ToLower ().StartsWith (rangeSpecifier.ToLower () + "="))
\r
467 throw new InvalidOperationException ("rangeSpecifier");
\r
468 Headers.RemoveAndAdd ("Range", value + range + "-");
\r
471 public void AddRange (string rangeSpecifier, int from, int to)
\r
473 if (rangeSpecifier == null)
\r
474 throw new ArgumentNullException ("rangeSpecifier");
\r
475 if (from < 0 || to < 0 || from > to)
\r
476 throw new ArgumentOutOfRangeException ();
\r
477 string value = Headers ["Range"];
\r
478 if (value == null || value.Length == 0)
\r
479 value = rangeSpecifier + "=";
\r
480 else if (value.ToLower ().StartsWith (rangeSpecifier.ToLower () + "="))
\r
483 throw new InvalidOperationException ("rangeSpecifier");
\r
484 Headers.RemoveAndAdd ("Range", value + from + "-" + to);
\r
487 public override Stream GetRequestStream()
\r
489 return _provider.GetRequestStream();
\r
492 // Type t = Type.GetType("System.IO.ConsoleWriteStream", true);
\r
493 // _connection.setDoOutput(true);
\r
496 //// Console.WriteLine("Request is sent with following headers:");
\r
497 //// java.util.Map map = _connection.getRequestProperties();
\r
498 //// for(java.util.Iterator iter = map.keySet().iterator(); iter.hasNext();)
\r
500 //// string key = (string) iter.next();
\r
501 //// Console.WriteLine(key + ": " + map.get(key));
\r
504 // foreach(string k in Headers)
\r
506 // string val = Headers[k];
\r
507 // val = (val == null) ? "" : val;
\r
508 // _connection.setRequestProperty(k, val);
\r
511 // _writeStream = (Stream) Activator.CreateInstance(t, new object[]{_connection.getOutputStream()});
\r
512 // _haveRequest = true;
\r
513 // return _writeStream;
\r
517 public override WebResponse GetResponse()
\r
519 return _provider.GetResponse();
\r
522 private void CommonChecks (bool putpost)
\r
524 string method = _connection.getRequestMethod();
\r
526 if (method == null)
\r
527 throw new ProtocolViolationException ("Method is null.");
\r
529 bool keepAlive = _headers["Keep-Alive"] == null;
\r
530 bool allowBuffering = true;
\r
531 bool sendChunked = true;
\r
532 long contentLength = _connection.getContentLength();
\r
534 if (putpost && ((!keepAlive || (contentLength == -1 && !sendChunked)) && !allowBuffering))
\r
535 throw new ProtocolViolationException ("Content-Length not set");
\r
537 string transferEncoding = TransferEncoding;
\r
538 if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
\r
539 throw new ProtocolViolationException ("SendChunked should be true.");
\r
543 public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
\r
545 return _provider.BeginGetRequestStream(callback, state);
\r
548 public override Stream EndGetRequestStream(IAsyncResult asyncResult)
\r
550 return _provider.EndGetRequestStream(asyncResult);
\r
553 public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
\r
555 //todo check input, http headers etc.
\r
557 return _provider.BeginGetResponse(callback, state);
\r
560 public override WebResponse EndGetResponse(IAsyncResult asyncResult)
\r
562 return _provider.EndGetResponse(asyncResult);
\r
570 #region Inner Classes
\r
572 // #region JavaHeaders class
\r
574 // internal sealed class JavaHeaders : WebHeaderCollection
\r
576 // private java.net.HttpURLConnection _connection;
\r
578 // internal JavaHeaders(java.net.HttpURLConnection con)
\r
580 // _connection = con;
\r
583 // public string this[string key]
\r
587 // return _connection.getHeaderField(key);
\r
591 // _connection.addRequestProperty(key, value);
\r