| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461 |
- //
- // System.Net.WebClient
- //
- // Authors:
- // Lawrence Pit ([email protected])
- // Gonzalo Paniagua Javier ([email protected])
- // Atsushi Enomoto ([email protected])
- // Miguel de Icaza ([email protected])
- //
- // Copyright 2003 Ximian, Inc. (http://www.ximian.com)
- // Copyright 2006, 2007 Novell, Inc. (http://www.novell.com)
- //
- //
- // Permission is hereby granted, free of charge, to any person obtaining
- // a copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to
- // permit persons to whom the Software is furnished to do so, subject to
- // the following conditions:
- //
- // The above copyright notice and this permission notice shall be
- // included in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- //
- using System;
- using System.Collections.Specialized;
- using System.ComponentModel;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Runtime.Serialization;
- using System.Text;
- using System.Threading;
- #if NET_2_0
- using System.Net.Cache;
- #endif
- namespace System.Net
- {
- [ComVisible(true)]
- public
- #if !NET_2_0
- sealed
- #endif
- class WebClient : Component
- {
- static readonly string urlEncodedCType = "application/x-www-form-urlencoded";
- static byte [] hexBytes;
- ICredentials credentials;
- WebHeaderCollection headers;
- WebHeaderCollection responseHeaders;
- Uri baseAddress;
- string baseString;
- NameValueCollection queryString;
- bool is_busy, async;
- #if NET_2_0
- Thread async_thread;
- Encoding encoding = Encoding.Default;
- IWebProxy proxy;
- #endif
- // Constructors
- static WebClient ()
- {
- hexBytes = new byte [16];
- int index = 0;
- for (int i = '0'; i <= '9'; i++, index++)
- hexBytes [index] = (byte) i;
- for (int i = 'A'; i <= 'F'; i++, index++)
- hexBytes [index] = (byte) i;
- }
-
- public WebClient ()
- {
- }
-
- // Properties
-
- public string BaseAddress {
- get {
- if (baseString == null) {
- if (baseAddress == null)
- return "";
- }
- baseString = baseAddress.ToString ();
- return baseString;
- }
-
- set {
- if (value == null || value == "") {
- baseAddress = null;
- } else {
- baseAddress = new Uri (value);
- }
- }
- }
- #if NET_2_0
- static Exception GetMustImplement ()
- {
- return new NotImplementedException ();
- }
-
- [MonoTODO]
- public RequestCachePolicy CachePolicy
- {
- get {
- throw GetMustImplement ();
- }
- set {
- throw GetMustImplement ();
- }
- }
- [MonoTODO]
- public bool UseDefaultCredentials
- {
- get {
- throw GetMustImplement ();
- }
- set {
- throw GetMustImplement ();
- }
- }
- #endif
-
- public ICredentials Credentials {
- get { return credentials; }
- set { credentials = value; }
- }
- public WebHeaderCollection Headers {
- get {
- if (headers == null)
- headers = new WebHeaderCollection ();
- return headers;
- }
- set { headers = value; }
- }
-
- public NameValueCollection QueryString {
- get {
- if (queryString == null)
- queryString = new NameValueCollection ();
- return queryString;
- }
- set { queryString = value; }
- }
-
- public WebHeaderCollection ResponseHeaders {
- get { return responseHeaders; }
- }
- #if NET_2_0
- public Encoding Encoding {
- get { return encoding; }
- set {
- if (value == null)
- throw new ArgumentNullException ("value");
- encoding = value;
- }
- }
- public IWebProxy Proxy {
- get { return proxy; }
- set { proxy = value; }
- }
- #endif
- #if NET_2_0
- public bool IsBusy {
- get { return is_busy; }
- }
- #else
- bool IsBusy {
- get { return is_busy; }
- }
- #endif
- // Methods
- void CheckBusy ()
- {
- if (IsBusy)
- throw new NotSupportedException ("WebClient does not support conccurent I/O operations.");
- }
- void SetBusy ()
- {
- lock (this) {
- CheckBusy ();
- is_busy = true;
- }
- }
- // DownloadData
- public byte [] DownloadData (string address)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return DownloadData (CreateUri (address));
- }
- #if NET_2_0
- public
- #endif
- byte [] DownloadData (Uri address)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- try {
- SetBusy ();
- async = false;
- return DownloadDataCore (address, null);
- } finally {
- is_busy = false;
- }
- }
- byte [] DownloadDataCore (Uri address, object userToken)
- {
- WebRequest request = null;
-
- try {
- request = SetupRequest (address, "GET");
- WebResponse response = request.GetResponse ();
- Stream st = ProcessResponse (response);
- return ReadAll (st, (int) response.ContentLength, userToken);
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- throw;
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- }
- }
- // DownloadFile
- public void DownloadFile (string address, string fileName)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- DownloadFile (CreateUri (address), fileName);
- }
- #if NET_2_0
- public
- #endif
- void DownloadFile (Uri address, string fileName)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- if (fileName == null)
- throw new ArgumentNullException ("fileName");
- #endif
- try {
- SetBusy ();
- async = false;
- DownloadFileCore (address, fileName, null);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- void DownloadFileCore (Uri address, string fileName, object userToken)
- {
- WebRequest request = null;
-
- using (FileStream f = new FileStream (fileName, FileMode.Create)) {
- try {
- request = SetupRequest (address);
- WebResponse response = request.GetResponse ();
- Stream st = ProcessResponse (response);
-
- int cLength = (int) response.ContentLength;
- int length = (cLength <= -1 || cLength > 32*1024) ? 32*1024 : cLength;
- byte [] buffer = new byte [length];
-
- int nread = 0;
- long notify_total = 0;
- while ((nread = st.Read (buffer, 0, length)) != 0){
- #if NET_2_0
- if (async && DownloadProgressChanged != null){
- notify_total += nread;
- DownloadProgressChanged (
- this,
- new DownloadProgressChangedEventArgs (response.ContentLength, notify_total, userToken));
-
- }
- #endif
- f.Write (buffer, 0, nread);
- }
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- throw;
- }
- }
- }
- // OpenRead
- public Stream OpenRead (string address)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return OpenRead (CreateUri (address));
- }
- #if NET_2_0
- public
- #endif
- Stream OpenRead (Uri address)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- WebRequest request = null;
- try {
- SetBusy ();
- async = false;
- request = SetupRequest (address);
- WebResponse response = request.GetResponse ();
- return ProcessResponse (response);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- // OpenWrite
- public Stream OpenWrite (string address)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return OpenWrite (CreateUri (address));
- }
-
- public Stream OpenWrite (string address, string method)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return OpenWrite (CreateUri (address), method);
- }
- #if NET_2_0
- public
- #endif
- Stream OpenWrite (Uri address)
- {
- return OpenWrite (address, (string) null);
- }
- #if NET_2_0
- public
- #endif
- Stream OpenWrite (Uri address, string method)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- try {
- SetBusy ();
- async = false;
- WebRequest request = SetupRequest (address, method);
- return request.GetRequestStream ();
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- private string DetermineMethod (Uri address, string method)
- {
- if (method != null)
- return method;
- #if NET_2_0
- if (address.Scheme == Uri.UriSchemeFtp)
- return "RETR";
- #endif
- return "POST";
- }
- // UploadData
- public byte [] UploadData (string address, byte [] data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return UploadData (CreateUri (address), data);
- }
-
- public byte [] UploadData (string address, string method, byte [] data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return UploadData (CreateUri (address), method, data);
- }
- #if NET_2_0
- public
- #endif
- byte [] UploadData (Uri address, byte [] data)
- {
- return UploadData (address, (string) null, data);
- }
- #if NET_2_0
- public
- #endif
- byte [] UploadData (Uri address, string method, byte [] data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- #endif
- try {
- SetBusy ();
- async = false;
- return UploadDataCore (address, method, data, null);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- byte [] UploadDataCore (Uri address, string method, byte [] data, object userToken)
- {
- #if ONLY_1_1
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- #endif
- WebRequest request = SetupRequest (address, method);
- try {
- int contentLength = data.Length;
- request.ContentLength = contentLength;
- using (Stream stream = request.GetRequestStream ()) {
- stream.Write (data, 0, contentLength);
- }
-
- WebResponse response = request.GetResponse ();
- Stream st = ProcessResponse (response);
- return ReadAll (st, (int) response.ContentLength, userToken);
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- throw;
- }
- }
- // UploadFile
- public byte [] UploadFile (string address, string fileName)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return UploadFile (CreateUri (address), fileName);
- }
- #if NET_2_0
- public
- #endif
- byte [] UploadFile (Uri address, string fileName)
- {
- return UploadFile (address, (string) null, fileName);
- }
-
- public byte [] UploadFile (string address, string method, string fileName)
- {
- return UploadFile (CreateUri (address), method, fileName);
- }
- #if NET_2_0
- public
- #endif
- byte [] UploadFile (Uri address, string method, string fileName)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- if (fileName == null)
- throw new ArgumentNullException ("fileName");
- #endif
- try {
- SetBusy ();
- async = false;
- return UploadFileCore (address, method, fileName, null);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- byte [] UploadFileCore (Uri address, string method, string fileName, object userToken)
- {
- #if ONLY_1_1
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- string fileCType = Headers ["Content-Type"];
- if (fileCType != null) {
- string lower = fileCType.ToLower ();
- if (lower.StartsWith ("multipart/"))
- throw new WebException ("Content-Type cannot be set to a multipart" +
- " type for this request.");
- } else {
- fileCType = "application/octet-stream";
- }
- string boundary = "------------" + DateTime.Now.Ticks.ToString ("x");
- Headers ["Content-Type"] = String.Format ("multipart/form-data; boundary={0}", boundary);
- Stream reqStream = null;
- Stream fStream = null;
- byte [] resultBytes = null;
- fileName = Path.GetFullPath (fileName);
- WebRequest request = null;
- try {
- fStream = File.OpenRead (fileName);
- request = SetupRequest (address, method);
- reqStream = request.GetRequestStream ();
- byte [] realBoundary = Encoding.ASCII.GetBytes ("--" + boundary + "\r\n");
- reqStream.Write (realBoundary, 0, realBoundary.Length);
- string partHeaders = String.Format ("Content-Disposition: form-data; " +
- "name=\"file\"; filename=\"{0}\"\r\n" +
- "Content-Type: {1}\r\n\r\n",
- Path.GetFileName (fileName), fileCType);
- byte [] partHeadersBytes = Encoding.UTF8.GetBytes (partHeaders);
- reqStream.Write (partHeadersBytes, 0, partHeadersBytes.Length);
- int nread;
- byte [] buffer = new byte [4096];
- while ((nread = fStream.Read (buffer, 0, 4096)) != 0)
- reqStream.Write (buffer, 0, nread);
- reqStream.WriteByte ((byte) '\r');
- reqStream.WriteByte ((byte) '\n');
- reqStream.Write (realBoundary, 0, realBoundary.Length);
- reqStream.Close ();
- reqStream = null;
- WebResponse response = request.GetResponse ();
- Stream st = ProcessResponse (response);
- resultBytes = ReadAll (st, (int) response.ContentLength, userToken);
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- throw;
- } finally {
- if (fStream != null)
- fStream.Close ();
- if (reqStream != null)
- reqStream.Close ();
- }
-
- return resultBytes;
- }
-
- public byte[] UploadValues (string address, NameValueCollection data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return UploadValues (CreateUri (address), data);
- }
-
- public byte[] UploadValues (string address, string method, NameValueCollection data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- #endif
- return UploadValues (CreateUri (address), method, data);
- }
- #if NET_2_0
- public
- #endif
- byte[] UploadValues (Uri address, NameValueCollection data)
- {
- return UploadValues (address, (string) null, data);
- }
- #if NET_2_0
- public
- #endif
- byte[] UploadValues (Uri address, string method, NameValueCollection data)
- {
- #if NET_2_0
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- #endif
- try {
- SetBusy ();
- async = false;
- return UploadValuesCore (address, method, data, null);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- } finally {
- is_busy = false;
- }
- }
- byte[] UploadValuesCore (Uri uri, string method, NameValueCollection data, object userToken)
- {
- #if ONLY_1_1
- if (data == null)
- throw new ArgumentNullException ("data");
- #endif
- string cType = Headers ["Content-Type"];
- if (cType != null && String.Compare (cType, urlEncodedCType, true) != 0)
- throw new WebException ("Content-Type header cannot be changed from its default " +
- "value for this request.");
- Headers ["Content-Type"] = urlEncodedCType;
- WebRequest request = SetupRequest (uri, method);
- try {
- Stream rqStream = request.GetRequestStream ();
- MemoryStream tmpStream = new MemoryStream ();
- foreach (string key in data) {
- byte [] bytes = Encoding.ASCII.GetBytes (key);
- UrlEncodeAndWrite (tmpStream, bytes);
- tmpStream.WriteByte ((byte) '=');
- bytes = Encoding.ASCII.GetBytes (data [key]);
- UrlEncodeAndWrite (tmpStream, bytes);
- tmpStream.WriteByte ((byte) '&');
- }
-
- int length = (int) tmpStream.Length;
- if (length > 0)
- tmpStream.SetLength (--length); // remove trailing '&'
-
- tmpStream.WriteByte ((byte) '\r');
- tmpStream.WriteByte ((byte) '\n');
-
- byte [] buf = tmpStream.GetBuffer ();
- rqStream.Write (buf, 0, length + 2);
- rqStream.Close ();
- tmpStream.Close ();
-
- WebResponse response = request.GetResponse ();
- Stream st = ProcessResponse (response);
- return ReadAll (st, (int) response.ContentLength, userToken);
- } catch (ThreadInterruptedException){
- request.Abort ();
- throw;
- }
- }
- #if NET_2_0
- public string DownloadString (string address)
- {
- return encoding.GetString (DownloadData (address));
- }
- public string DownloadString (Uri address)
- {
- return encoding.GetString (DownloadData (address));
- }
- public string UploadString (string address, string data)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- byte [] resp = UploadData (address, encoding.GetBytes (data));
- return encoding.GetString (resp);
- }
- public string UploadString (string address, string method, string data)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- byte [] resp = UploadData (address, method, encoding.GetBytes (data));
- return encoding.GetString (resp);
- }
- public string UploadString (Uri address, string data)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- byte [] resp = UploadData (address, encoding.GetBytes (data));
- return encoding.GetString (resp);
- }
- public string UploadString (Uri address, string method, string data)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
- byte [] resp = UploadData (address, method, encoding.GetBytes (data));
- return encoding.GetString (resp);
- }
- public event DownloadDataCompletedEventHandler DownloadDataCompleted;
- public event AsyncCompletedEventHandler DownloadFileCompleted;
- public event DownloadProgressChangedEventHandler DownloadProgressChanged;
- public event DownloadStringCompletedEventHandler DownloadStringCompleted;
- public event OpenReadCompletedEventHandler OpenReadCompleted;
- public event OpenWriteCompletedEventHandler OpenWriteCompleted;
- public event UploadDataCompletedEventHandler UploadDataCompleted;
- public event UploadFileCompletedEventHandler UploadFileCompleted;
- public event UploadProgressChangedEventHandler UploadProgressChanged;
- public event UploadStringCompletedEventHandler UploadStringCompleted;
- public event UploadValuesCompletedEventHandler UploadValuesCompleted;
- #endif
- Uri CreateUri (string address)
- {
- #if ONLY_1_1
- try {
- return MakeUri (address);
- } catch (Exception ex) {
- throw new WebException ("An error occurred " +
- "performing a WebClient request.", ex);
- }
- #else
- return MakeUri (address);
- #endif
- }
- Uri MakeUri (string path)
- {
- string query = null;
- if (queryString != null && queryString.Count != 0) {
- // This is not the same as UploadValues, because these 'keys' are not
- // urlencoded here.
- StringBuilder sb = new StringBuilder ();
- sb.Append ('?');
- foreach (string key in queryString)
- sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
- if (sb.Length != 0) {
- sb.Length--; // remove trailing '&'
- query = sb.ToString ();
- }
- }
- if (baseAddress == null && query == null) {
- try {
- return new Uri (path);
- #if NET_2_0
- } catch (ArgumentNullException) {
- path = Path.GetFullPath (path);
- return new Uri ("file://" + path);
- #endif
- } catch (UriFormatException) {
- path = Path.GetFullPath (path);
- return new Uri ("file://" + path);
- }
- }
- if (baseAddress == null)
- return new Uri (path + query, (query != null));
- if (query == null)
- return new Uri (baseAddress, path);
- return new Uri (baseAddress, path + query, (query != null));
- }
-
- WebRequest SetupRequest (Uri uri)
- {
- WebRequest request = WebRequest.Create (uri);
- #if NET_2_0
- if (Proxy != null)
- request.Proxy = Proxy;
- #endif
- request.Credentials = credentials;
- // Special headers. These are properties of HttpWebRequest.
- // What do we do with other requests differnt from HttpWebRequest?
- if (headers != null && headers.Count != 0 && (request is HttpWebRequest)) {
- HttpWebRequest req = (HttpWebRequest) request;
- string expect = headers ["Expect"];
- string contentType = headers ["Content-Type"];
- string accept = headers ["Accept"];
- string connection = headers ["Connection"];
- string userAgent = headers ["User-Agent"];
- string referer = headers ["Referer"];
- headers.RemoveInternal ("Expect");
- headers.RemoveInternal ("Content-Type");
- headers.RemoveInternal ("Accept");
- headers.RemoveInternal ("Connection");
- headers.RemoveInternal ("Referer");
- headers.RemoveInternal ("User-Agent");
- request.Headers = headers;
- if (expect != null && expect.Length > 0)
- req.Expect = expect;
- if (accept != null && accept.Length > 0)
- req.Accept = accept;
- if (contentType != null && contentType.Length > 0)
- req.ContentType = contentType;
- if (connection != null && connection.Length > 0)
- req.Connection = connection;
- if (userAgent != null && userAgent.Length > 0)
- req.UserAgent = userAgent;
- if (referer != null && referer.Length > 0)
- req.Referer = referer;
- }
- responseHeaders = null;
- return request;
- }
- WebRequest SetupRequest (Uri uri, string method)
- {
- WebRequest request = SetupRequest (uri);
- request.Method = DetermineMethod (uri, method);
- return request;
- }
- Stream ProcessResponse (WebResponse response)
- {
- responseHeaders = response.Headers;
- return response.GetResponseStream ();
- }
- byte [] ReadAll (Stream stream, int length, object userToken)
- {
- MemoryStream ms = null;
-
- bool nolength = (length == -1);
- int size = ((nolength) ? 8192 : length);
- if (nolength)
- ms = new MemoryStream ();
- long total = 0;
- int nread = 0;
- int offset = 0;
- byte [] buffer = new byte [size];
- while ((nread = stream.Read (buffer, offset, size)) != 0) {
- if (nolength) {
- ms.Write (buffer, 0, nread);
- } else {
- offset += nread;
- size -= nread;
- }
- #if NET_2_0
- if (async && DownloadProgressChanged != null){
- total += nread;
- DownloadProgressChanged (this, new DownloadProgressChangedEventArgs (nread, length, userToken));
- }
- #endif
- }
- if (nolength)
- return ms.ToArray ();
- return buffer;
- }
- string UrlEncode (string str)
- {
- StringBuilder result = new StringBuilder ();
- int len = str.Length;
- for (int i = 0; i < len; i++) {
- char c = str [i];
- if (c == ' ')
- result.Append ('+');
- else if ((c < '0' && c != '-' && c != '.') ||
- (c < 'A' && c > '9') ||
- (c > 'Z' && c < 'a' && c != '_') ||
- (c > 'z')) {
- result.Append ('%');
- int idx = ((int) c) >> 4;
- result.Append ((char) hexBytes [idx]);
- idx = ((int) c) & 0x0F;
- result.Append ((char) hexBytes [idx]);
- } else {
- result.Append (c);
- }
- }
- return result.ToString ();
- }
- static void UrlEncodeAndWrite (Stream stream, byte [] bytes)
- {
- if (bytes == null)
- return;
- int len = bytes.Length;
- if (len == 0)
- return;
- for (int i = 0; i < len; i++) {
- char c = (char) bytes [i];
- if (c == ' ')
- stream.WriteByte ((byte) '+');
- else if ((c < '0' && c != '-' && c != '.') ||
- (c < 'A' && c > '9') ||
- (c > 'Z' && c < 'a' && c != '_') ||
- (c > 'z')) {
- stream.WriteByte ((byte) '%');
- int idx = ((int) c) >> 4;
- stream.WriteByte (hexBytes [idx]);
- idx = ((int) c) & 0x0F;
- stream.WriteByte (hexBytes [idx]);
- } else {
- stream.WriteByte ((byte) c);
- }
- }
- }
- #if NET_2_0
- public void CancelAsync ()
- {
- lock (this){
- if (async_thread == null)
- return;
- //
- // We first flag things as done, in case the Interrupt hangs
- // or the thread decides to hang in some other way inside the
- // event handlers, or if we are stuck somewhere else. This
- // ensures that the WebClient object is reusable immediately
- //
- Thread t = async_thread;
- CompleteAsync ();
- t.Interrupt ();
- }
- }
- void CompleteAsync ()
- {
- lock (this){
- is_busy = false;
- async_thread = null;
- }
- }
- // DownloadDataAsync
- public void DownloadDataAsync (Uri address)
- {
- DownloadDataAsync (address, null);
- }
- public void DownloadDataAsync (Uri address, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- lock (this) {
- SetBusy ();
- async = true;
-
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- try {
- byte [] data = DownloadDataCore ((Uri) args [0], args [1]);
- OnDownloadDataCompleted (
- new DownloadDataCompletedEventArgs (data, null, false, args [1]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnDownloadDataCompleted (
- new DownloadDataCompletedEventArgs (null, null, true, args [1]));
- throw;
- }
- });
- object [] cb_args = new object [] {address, userToken};
- async_thread.Start (cb_args);
- }
- }
- // DownloadFileAsync
- public void DownloadFileAsync (Uri address, string fileName)
- {
- DownloadFileAsync (address, fileName, null);
- }
- public void DownloadFileAsync (Uri address, string fileName, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (fileName == null)
- throw new ArgumentNullException ("fileName");
-
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- try {
- DownloadFileCore ((Uri) args [0], (string) args [1], args [2]);
- OnDownloadFileCompleted (
- new AsyncCompletedEventArgs (null, false, args [2]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnDownloadFileCompleted (
- new AsyncCompletedEventArgs (null, true, args [2]));
- }
- });
- object [] cb_args = new object [] {address, fileName, userToken};
- async_thread.Start (cb_args);
- }
- }
- // DownloadStringAsync
- public void DownloadStringAsync (Uri address)
- {
- DownloadStringAsync (address, null);
- }
- public void DownloadStringAsync (Uri address, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- try {
- string data = encoding.GetString (DownloadDataCore ((Uri) args [0], args [1]));
- OnDownloadStringCompleted (
- new DownloadStringCompletedEventArgs (data, null, false, args [1]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnDownloadStringCompleted (
- new DownloadStringCompletedEventArgs (null, null, true, args [1]));
- }
- });
- object [] cb_args = new object [] {address, userToken};
- async_thread.Start (cb_args);
- }
- }
- // OpenReadAsync
- public void OpenReadAsync (Uri address)
- {
- OpenReadAsync (address, null);
- }
- public void OpenReadAsync (Uri address, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
-
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- WebRequest request = null;
- try {
- request = SetupRequest ((Uri) args [0]);
- WebResponse response = request.GetResponse ();
- Stream stream = ProcessResponse (response);
- OnOpenReadCompleted (
- new OpenReadCompletedEventArgs (stream, null, false, args [1]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
-
- OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
- }
- } );
- object [] cb_args = new object [] {address, userToken};
- async_thread.Start (cb_args);
- }
- }
- // OpenWriteAsync
- public void OpenWriteAsync (Uri address)
- {
- OpenWriteAsync (address, null);
- }
- public void OpenWriteAsync (Uri address, string method)
- {
- OpenWriteAsync (address, method, null);
- }
- public void OpenWriteAsync (Uri address, string method, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (method == null)
- throw new ArgumentNullException ("method");
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- WebRequest request = null;
- try {
- request = SetupRequest ((Uri) args [0], (string) args [1]);
- Stream stream = request.GetRequestStream ();
- OnOpenWriteCompleted (
- new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- OnOpenWriteCompleted (
- new OpenWriteCompletedEventArgs (null, null, true, args [2]));
- }
- });
- object [] cb_args = new object [] {address, method, userToken};
- async_thread.Start (cb_args);
- }
- }
- // UploadDataAsync
- public void UploadDataAsync (Uri address, byte [] data)
- {
- UploadDataAsync (address, null, data);
- }
- public void UploadDataAsync (Uri address, string method, byte [] data)
- {
- UploadDataAsync (address, method, data, null);
- }
- public void UploadDataAsync (Uri address, string method, byte [] data, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
-
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- byte [] data2;
- try {
- data2 = UploadDataCore ((Uri) args [0], (string) args [1], (byte []) args [2], args [3]);
-
- OnUploadDataCompleted (
- new UploadDataCompletedEventArgs (data2, null, false, args [3]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnUploadDataCompleted (
- new UploadDataCompletedEventArgs (null, null, true, args [3]));
- }});
- object [] cb_args = new object [] {address, method, data, userToken};
- async_thread.Start (cb_args);
- }
- }
- // UploadFileAsync
- public void UploadFileAsync (Uri address, string fileName)
- {
- UploadFileAsync (address, null, fileName);
- }
- public void UploadFileAsync (Uri address, string method, string fileName)
- {
- UploadFileAsync (address, method, fileName, null);
- }
- public void UploadFileAsync (Uri address, string method, string fileName, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (fileName == null)
- throw new ArgumentNullException ("fileName");
- lock (this) {
- SetBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- byte [] data;
- try {
- data = UploadFileCore ((Uri) args [0], (string) args [1], (string) args [2], args [3]);
- OnUploadFileCompleted (
- new UploadFileCompletedEventArgs (data, null, false, args [3]));
- } catch (ThreadInterruptedException){
- OnUploadFileCompleted (
- new UploadFileCompletedEventArgs (null, null, true, args [3]));
- }
- });
- object [] cb_args = new object [] {address, method, fileName, userToken};
- async_thread.Start (cb_args);
- }
- }
- // UploadStringAsync
- public void UploadStringAsync (Uri address, string data)
- {
- UploadStringAsync (address, null, data);
- }
- public void UploadStringAsync (Uri address, string method, string data)
- {
- UploadStringAsync (address, method, data, null);
- }
- public void UploadStringAsync (Uri address, string method, string data, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (data == null)
- throw new ArgumentNullException ("data");
-
- lock (this) {
- SetBusy ();
- async = true;
-
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- try {
- string data2 = UploadString ((Uri) args [0], (string) args [1], (string) args [2]);
- OnUploadStringCompleted (
- new UploadStringCompletedEventArgs (data2, null, false, args [3]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnUploadStringCompleted (
- new UploadStringCompletedEventArgs (null, null, true, args [3]));
- }
- });
- object [] cb_args = new object [] {address, method, data, userToken};
- async_thread.Start (cb_args);
- }
- }
- // UploadValuesAsync
- public void UploadValuesAsync (Uri address, NameValueCollection values)
- {
- UploadValuesAsync (address, null, values);
- }
- public void UploadValuesAsync (Uri address, string method, NameValueCollection values)
- {
- UploadValuesAsync (address, method, values, null);
- }
- public void UploadValuesAsync (Uri address, string method, NameValueCollection values, object userToken)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- if (values == null)
- throw new ArgumentNullException ("values");
- lock (this) {
- CheckBusy ();
- async = true;
- async_thread = new Thread (delegate (object state) {
- object [] args = (object []) state;
- try {
- byte [] data = UploadValuesCore ((Uri) args [0], (string) args [1], (NameValueCollection) args [2], args [3]);
- OnUploadValuesCompleted (
- new UploadValuesCompletedEventArgs (data, null, false, args [3]));
- CompleteAsync ();
- } catch (ThreadInterruptedException){
- OnUploadValuesCompleted (
- new UploadValuesCompletedEventArgs (null, null, true, args [3]));
- }
- });
- object [] cb_args = new object [] {address, method, values, userToken};
- async_thread.Start (cb_args);
- }
- }
- protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
- {
- if (DownloadDataCompleted != null)
- DownloadDataCompleted (this, args);
- }
- protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
- {
- if (DownloadFileCompleted != null)
- DownloadFileCompleted (this, args);
- }
- protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
- {
- if (DownloadProgressChanged != null)
- DownloadProgressChanged (this, e);
- }
- protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
- {
- if (DownloadStringCompleted != null)
- DownloadStringCompleted (this, args);
- }
- protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
- {
- if (OpenReadCompleted != null)
- OpenReadCompleted (this, args);
- }
- protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
- {
- if (OpenWriteCompleted != null)
- OpenWriteCompleted (this, args);
- }
- protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
- {
- if (UploadDataCompleted != null)
- UploadDataCompleted (this, args);
- }
- protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
- {
- if (UploadFileCompleted != null)
- UploadFileCompleted (this, args);
- }
- protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
- {
- if (UploadProgressChanged != null)
- UploadProgressChanged (this, e);
- }
- protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
- {
- if (UploadStringCompleted != null)
- UploadStringCompleted (this, args);
- }
- protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
- {
- if (UploadValuesCompleted != null)
- UploadValuesCompleted (this, args);
- }
- [MonoNotSupported("")]
- protected virtual WebRequest GetWebRequest (Uri address)
- {
- throw new NotImplementedException ();
- }
- protected virtual WebResponse GetWebResponse (WebRequest request)
- {
- return request.GetResponse ();
- }
- protected virtual WebResponse GetWebResponse (WebRequest request, IAsyncResult result)
- {
- return request.EndGetResponse (result);
- }
- #endif
- }
- }
|