| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553 |
- //
- // 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.
- //
- //
- // Notes on CancelAsync and Async methods:
- //
- // WebClient.CancelAsync is implemented by calling Thread.Interrupt
- // in our helper thread. The various async methods have to cancel
- // any ongoing requests by calling request.Abort () at that point.
- // In a few places (UploadDataCore, UploadValuesCore,
- // UploadFileCore) we catch the ThreadInterruptedException and
- // abort the request there.
- //
- // Higher level routines (the async callbacks) also need to catch
- // the exception and raise the OnXXXXCompleted events there with
- // the "canceled" flag set to true.
- //
- // In a few other places where these helper routines are not used
- // (OpenReadAsync for example) catching the ThreadAbortException
- // also must abort the request.
- //
- // The Async methods currently differ in their implementation from
- // the .NET implementation in that we manually catch any other
- // exceptions and correctly raise the OnXXXXCompleted passing the
- // Exception that caused the problem. The .NET implementation
- // does not seem to have a mechanism to flag errors that happen
- // during downloads though. We do this because we still need to
- // catch the exception on these helper threads, or we would
- // otherwise kill the application (on the 2.x profile, uncaught
- // exceptions in threads terminate the application).
- //
- 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;
- #if NET_2_0
- bool async;
- 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 ();
- #if NET_2_0
- async = false;
- #endif
- return DownloadDataCore (address, null);
- } finally {
- is_busy = false;
- }
- }
- byte [] DownloadDataCore (Uri address, object userToken)
- {
- WebRequest request = null;
-
- try {
- request = SetupRequest (address);
- 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 ();
- #if NET_2_0
- async = false;
- #endif
- 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;
- #if NET_2_0
- long notify_total = 0;
- #endif
- while ((nread = st.Read (buffer, 0, length)) != 0){
- #if NET_2_0
- if (async){
- notify_total += nread;
- OnDownloadProgressChanged (
- new DownloadProgressChangedEventArgs (notify_total, response.ContentLength, 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 ();
- #if NET_2_0
- async = false;
- #endif
- 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 ();
- #if NET_2_0
- async = false;
- #endif
- WebRequest request = SetupRequest (address, method, true);
- 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, bool is_upload)
- {
- if (method != null)
- return method;
- #if NET_2_0
- if (address.Scheme == Uri.UriSchemeFtp)
- return (is_upload) ? "STOR" : "RETR";
- #endif
- return (is_upload) ? "POST" : "GET";
- }
- // 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 ();
- #if NET_2_0
- async = false;
- #endif
- return UploadDataCore (address, method, data, null);
- } catch (WebException) {
- throw;
- } 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, true);
- 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 ();
- #if NET_2_0
- async = false;
- #endif
- 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, true);
- 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 ();
- #if NET_2_0
- async = false;
- #endif
- 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, true);
- 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 '&'
-
- byte [] buf = tmpStream.GetBuffer ();
- rqStream.Write (buf, 0, length);
- 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)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- return encoding.GetString (DownloadData (CreateUri (address)));
- }
- public string DownloadString (Uri address)
- {
- if (address == null)
- throw new ArgumentNullException ("address");
- return encoding.GetString (DownloadData (CreateUri (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
- }
- #if NET_2_0
- Uri CreateUri (Uri address)
- {
- string query = address.Query;
- if (String.IsNullOrEmpty (query))
- query = GetQueryString (true);
- if (baseAddress == null && query == null)
- return address;
- if (baseAddress == null)
- return new Uri (address.ToString () + query, (query != null));
- if (query == null)
- return new Uri (baseAddress, address.ToString ());
- return new Uri (baseAddress, address.ToString () + query, (query != null));
- }
- #endif
- string GetQueryString (bool add_qmark)
- {
- if (queryString == null || queryString.Count == 0)
- return null;
- StringBuilder sb = new StringBuilder ();
- if (add_qmark)
- sb.Append ('?');
- foreach (string key in queryString)
- sb.AppendFormat ("{0}={1}&", key, UrlEncode (queryString [key]));
- if (sb.Length != 0)
- sb.Length--; // removes last '&' or the '?' if empty.
- if (sb.Length == 0)
- return null;
- return sb.ToString ();
- }
- Uri MakeUri (string path)
- {
- string query = GetQueryString (true);
- 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, bool is_upload)
- {
- WebRequest request = SetupRequest (uri);
- request.Method = DetermineMethod (uri, method, is_upload);
- 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){
- // total += nread;
- OnDownloadProgressChanged (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]));
- } catch (ThreadInterruptedException){
- OnDownloadDataCompleted (
- new DownloadDataCompletedEventArgs (null, null, true, args [1]));
- throw;
- } catch (Exception e){
- OnDownloadDataCompleted (
- new DownloadDataCompletedEventArgs (null, e, false, args [1]));
- }
- });
- 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]));
- } catch (ThreadInterruptedException){
- OnDownloadFileCompleted (
- new AsyncCompletedEventArgs (null, true, args [2]));
- } catch (Exception e){
- OnDownloadFileCompleted (
- new AsyncCompletedEventArgs (e, false, 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]));
- } catch (ThreadInterruptedException){
- OnDownloadStringCompleted (
- new DownloadStringCompletedEventArgs (null, null, true, args [1]));
- } catch (Exception e){
- OnDownloadStringCompleted (
- new DownloadStringCompletedEventArgs (null, e, false, 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]));
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
-
- OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, null, true, args [1]));
- } catch (Exception e){
- OnOpenReadCompleted (new OpenReadCompletedEventArgs (null, e, false, 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");
- 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], true);
- Stream stream = request.GetRequestStream ();
- OnOpenWriteCompleted (
- new OpenWriteCompletedEventArgs (stream, null, false, args [2]));
- } catch (ThreadInterruptedException){
- if (request != null)
- request.Abort ();
- OnOpenWriteCompleted (
- new OpenWriteCompletedEventArgs (null, null, true, args [2]));
- } catch (Exception e){
- OnOpenWriteCompleted (
- new OpenWriteCompletedEventArgs (null, e, false, 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]));
- } catch (ThreadInterruptedException){
- OnUploadDataCompleted (
- new UploadDataCompletedEventArgs (null, null, true, args [3]));
- } catch (Exception e){
- OnUploadDataCompleted (
- new UploadDataCompletedEventArgs (null, e, false, 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]));
- } catch (Exception e){
- OnUploadFileCompleted (
- new UploadFileCompletedEventArgs (null, e, false, 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]));
- } catch (ThreadInterruptedException){
- OnUploadStringCompleted (
- new UploadStringCompletedEventArgs (null, null, true, args [3]));
- } catch (Exception e){
- OnUploadStringCompleted (
- new UploadStringCompletedEventArgs (null, e, false, 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]));
- } catch (ThreadInterruptedException){
- OnUploadValuesCompleted (
- new UploadValuesCompletedEventArgs (null, null, true, args [3]));
- } catch (Exception e){
- OnUploadValuesCompleted (
- new UploadValuesCompletedEventArgs (null, e, false, args [3]));
- }});
- object [] cb_args = new object [] {address, method, values, userToken};
- async_thread.Start (cb_args);
- }
- }
- protected virtual void OnDownloadDataCompleted (DownloadDataCompletedEventArgs args)
- {
- CompleteAsync ();
- if (DownloadDataCompleted != null)
- DownloadDataCompleted (this, args);
- }
- protected virtual void OnDownloadFileCompleted (AsyncCompletedEventArgs args)
- {
- CompleteAsync ();
- if (DownloadFileCompleted != null)
- DownloadFileCompleted (this, args);
- }
- protected virtual void OnDownloadProgressChanged (DownloadProgressChangedEventArgs e)
- {
- if (DownloadProgressChanged != null)
- DownloadProgressChanged (this, e);
- }
- protected virtual void OnDownloadStringCompleted (DownloadStringCompletedEventArgs args)
- {
- CompleteAsync ();
- if (DownloadStringCompleted != null)
- DownloadStringCompleted (this, args);
- }
- protected virtual void OnOpenReadCompleted (OpenReadCompletedEventArgs args)
- {
- CompleteAsync ();
- if (OpenReadCompleted != null)
- OpenReadCompleted (this, args);
- }
- protected virtual void OnOpenWriteCompleted (OpenWriteCompletedEventArgs args)
- {
- CompleteAsync ();
- if (OpenWriteCompleted != null)
- OpenWriteCompleted (this, args);
- }
- protected virtual void OnUploadDataCompleted (UploadDataCompletedEventArgs args)
- {
- CompleteAsync ();
- if (UploadDataCompleted != null)
- UploadDataCompleted (this, args);
- }
- protected virtual void OnUploadFileCompleted (UploadFileCompletedEventArgs args)
- {
- CompleteAsync ();
- if (UploadFileCompleted != null)
- UploadFileCompleted (this, args);
- }
- protected virtual void OnUploadProgressChanged (UploadProgressChangedEventArgs e)
- {
- if (UploadProgressChanged != null)
- UploadProgressChanged (this, e);
- }
- protected virtual void OnUploadStringCompleted (UploadStringCompletedEventArgs args)
- {
- CompleteAsync ();
- if (UploadStringCompleted != null)
- UploadStringCompleted (this, args);
- }
- protected virtual void OnUploadValuesCompleted (UploadValuesCompletedEventArgs args)
- {
- CompleteAsync ();
- 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
- }
- }
|