예제 #1
0
        void WriteRequestAsyncCB(IAsyncResult r)
        {
            WebAsyncResult result = (WebAsyncResult)r.AsyncState;

            try {
                cnc.EndWrite2(request, r);
                result.SetCompleted(false, 0);
                if (!initRead)
                {
                    initRead = true;
                    WebConnection.InitRead(cnc);
                }
            } catch (Exception e) {
                KillBuffer();
                nextReadCalled = true;
                cnc.Close(true);
                if (e is System.Net.Sockets.SocketException)
                {
                    e = new IOException("Error writing request", e);
                }
                result.SetCompleted(false, e);
            }
            complete_request_written = true;
            result.DoCallback();
        }
예제 #2
0
        public override WebResponse EndGetResponse(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            WebAsyncResult result = asyncResult as WebAsyncResult;

            if (result == null)
            {
                throw new ArgumentException("Invalid IAsyncResult", "asyncResult");
            }

            if (!result.WaitUntilComplete(timeout, false))
            {
                Abort();
                throw new WebException("The request timed out", WebExceptionStatus.Timeout);
            }

            if (result.GotException)
            {
                throw result.Exception;
            }

            return(result.Response);
        }
예제 #3
0
        void WriteAsyncCB(IAsyncResult r)
        {
            WebAsyncResult result = (WebAsyncResult)r.AsyncState;

            result.InnerAsyncResult = null;

            try {
                cnc.EndWrite(request, true, r);
                result.SetCompleted(false, 0);
                if (!initRead)
                {
                    initRead = true;
                    WebConnection.InitRead(cnc);
                }
            } catch (Exception e) {
                KillBuffer();
                nextReadCalled = true;
                cnc.Close(true);
                if (e is System.Net.Sockets.SocketException)
                {
                    e = new IOException("Error writing request", e);
                }
                result.SetCompleted(false, e);
            }

            if (allowBuffering && !sendChunked && request.ContentLength > 0 && totalWritten == request.ContentLength)
            {
                complete_request_written = true;
            }

            result.DoCallback();
        }
        private void WriteRequestAsyncCB(IAsyncResult r)
        {
            WebAsyncResult webAsyncResult = (WebAsyncResult)r.AsyncState;

            try
            {
                this.cnc.EndWrite2(this.request, r);
                webAsyncResult.SetCompleted(false, 0);
                if (!this.initRead)
                {
                    this.initRead = true;
                    WebConnection.InitRead(this.cnc);
                }
            }
            catch (Exception ex)
            {
                this.KillBuffer();
                this.nextReadCalled = true;
                this.cnc.Close(true);
                if (ex is System.Net.Sockets.SocketException)
                {
                    ex = new IOException("Error writing request", ex);
                }
                webAsyncResult.SetCompleted(false, ex);
            }
            this.complete_request_written = true;
            webAsyncResult.DoCallback();
        }
예제 #5
0
        internal int EndRead(HttpWebRequest request, IAsyncResult result)
        {
            lock (this) {
                if (Data.request != request)
                {
                    throw new ObjectDisposedException(typeof(NetworkStream).FullName);
                }
                if (nstream == null)
                {
                    throw new ObjectDisposedException(typeof(NetworkStream).FullName);
                }
            }

            int            nbytes  = 0;
            WebAsyncResult wr      = null;
            IAsyncResult   nsAsync = ((WebAsyncResult)result).InnerAsyncResult;

            if (chunkedRead && (nsAsync is WebAsyncResult))
            {
                wr = (WebAsyncResult)nsAsync;
                IAsyncResult inner = wr.InnerAsyncResult;
                if (inner != null && !(inner is WebAsyncResult))
                {
                    nbytes = nstream.EndRead(inner);
                }
            }
            else if (!(nsAsync is WebAsyncResult))
            {
                nbytes = nstream.EndRead(nsAsync);
                wr     = (WebAsyncResult)result;
            }

            if (chunkedRead)
            {
                bool done = (nbytes == 0);
                try {
                    chunkStream.WriteAndReadBack(wr.Buffer, wr.Offset, wr.Size, ref nbytes);
                    if (!done && nbytes == 0 && chunkStream.WantMore)
                    {
                        nbytes = EnsureRead(wr.Buffer, wr.Offset, wr.Size);
                    }
                } catch (Exception e) {
                    if (e is WebException)
                    {
                        throw e;
                    }

                    throw new WebException("Invalid chunked data.", e,
                                           WebExceptionStatus.ServerProtocolViolation, null);
                }

                if ((done || nbytes == 0) && chunkStream.ChunkLeft != 0)
                {
                    HandleError(WebExceptionStatus.ReceiveFailure, null, "chunked EndRead");
                    throw new WebException("Read error", null, WebExceptionStatus.ReceiveFailure, null);
                }
            }

            return((nbytes != 0) ? nbytes : -1);
        }
예제 #6
0
        public override Stream EndGetRequestStream(IAsyncResult asyncResult)
        {
            if (asyncResult == null)
            {
                throw new ArgumentNullException("asyncResult");
            }

            WebAsyncResult result = asyncResult as WebAsyncResult;

            if (result == null)
            {
                throw new ArgumentException("Invalid IAsyncResult");
            }

            asyncWrite = result;
            result.WaitUntilComplete();

            Exception e = result.Exception;

            if (e != null)
            {
                throw e;
            }

            return(result.WriteStream);
        }
예제 #7
0
        internal void SetResponseError(WebExceptionStatus status, Exception e, string where)
        {
            if (aborted)
            {
                return;
            }
            string         msg = String.Format("Error getting response stream ({0}): {1}", where, status);
            WebAsyncResult r   = asyncRead;

            if (r == null)
            {
                r = asyncWrite;
            }

            if (r != null)
            {
                WebException wexc;
                if (e is WebException)
                {
                    wexc = (WebException)e;
                }
                else
                {
                    wexc = new WebException(msg, e, status, null);
                }
                r.SetCompleted(false, wexc);
                r.DoCallback();
                asyncRead  = null;
                asyncWrite = null;
            }
        }
        void WriteCallbackWrapper(IAsyncResult r)
        {
            WebAsyncResult result = r as WebAsyncResult;

            if (result != null && result.AsyncWriteAll)
            {
                return;
            }

            if (r.AsyncState != null)
            {
                result = (WebAsyncResult)r.AsyncState;
                result.InnerAsyncResult = r;
                result.DoCallback();
            }
            else
            {
                try
                {
                    EndWrite(r);
                }
                catch
                {
                }
            }
        }
예제 #9
0
		bool Redirect (WebAsyncResult result, HttpStatusCode code)
		{
			redirects++;
			Exception e = null;
			string uriString = null;

			switch (code) {
			case HttpStatusCode.Ambiguous: // 300
				e = new WebException ("Ambiguous redirect.");
				break;
			case HttpStatusCode.MovedPermanently: // 301
			case HttpStatusCode.Redirect: // 302
			case HttpStatusCode.TemporaryRedirect: // 307
				/* MS follows the redirect for POST too
				if (method != "GET" && method != "HEAD") // 10.3
					return false;
				*/

				contentLength = -1;
				bodyBufferLength = 0;
				bodyBuffer = null;
				if (code != HttpStatusCode.TemporaryRedirect)
					method = "GET";
				uriString = webResponse.Headers ["Location"];
				break;
			case HttpStatusCode.SeeOther: //303
				method = "GET";
				uriString = webResponse.Headers ["Location"];
				break;
			case HttpStatusCode.NotModified: // 304
				return false;
			case HttpStatusCode.UseProxy: // 305
				e = new NotImplementedException ("Proxy support not available.");
				break;
			case HttpStatusCode.Unused: // 306
			default:
				e = new ProtocolViolationException ("Invalid status code: " + (int) code);
				break;
			}

			if (e != null)
				throw e;

			if (uriString == null)
				throw new WebException ("No Location header found for " + (int) code,
							WebExceptionStatus.ProtocolError);

			Uri prev = actualUri;
			try {
				actualUri = new Uri (actualUri, uriString);
			} catch (Exception) {
				throw new WebException (String.Format ("Invalid URL ({0}) for {1}",
									uriString, (int) code),
									WebExceptionStatus.ProtocolError);
			}

			hostChanged = (actualUri.Scheme != prev.Scheme || Host != prev.Authority);
			return true;
		}
예제 #10
0
        internal int EndRead(HttpWebRequest request, IAsyncResult result)
        {
            lock (this)
            {
                if (Data.request != request)
                {
                    throw new ObjectDisposedException(typeof(NetworkStream).FullName);
                }
                if (nstream == null)
                {
                    throw new ObjectDisposedException(typeof(NetworkStream).FullName);
                }
            }
            int            read             = 0;
            WebAsyncResult webAsyncResult   = null;
            IAsyncResult   innerAsyncResult = ((WebAsyncResult)result).InnerAsyncResult;

            if (chunkedRead && innerAsyncResult is WebAsyncResult)
            {
                webAsyncResult = (WebAsyncResult)innerAsyncResult;
                IAsyncResult innerAsyncResult2 = webAsyncResult.InnerAsyncResult;
                if (innerAsyncResult2 != null && !(innerAsyncResult2 is WebAsyncResult))
                {
                    read = nstream.EndRead(innerAsyncResult2);
                }
            }
            else if (!(innerAsyncResult is WebAsyncResult))
            {
                read           = nstream.EndRead(innerAsyncResult);
                webAsyncResult = (WebAsyncResult)result;
            }
            if (chunkedRead)
            {
                bool flag = read == 0;
                try
                {
                    chunkStream.WriteAndReadBack(webAsyncResult.Buffer, webAsyncResult.Offset, webAsyncResult.Size, ref read);
                    if (!flag && read == 0 && chunkStream.WantMore)
                    {
                        read = EnsureRead(webAsyncResult.Buffer, webAsyncResult.Offset, webAsyncResult.Size);
                    }
                }
                catch (Exception ex)
                {
                    if (ex is WebException)
                    {
                        throw ex;
                    }
                    throw new WebException("Invalid chunked data.", ex, WebExceptionStatus.ServerProtocolViolation, null);
                    IL_0160 :;
                }
                if ((flag || read == 0) && chunkStream.ChunkLeft != 0)
                {
                    HandleError(WebExceptionStatus.ReceiveFailure, null, "chunked EndRead");
                    throw new WebException("Read error", null, WebExceptionStatus.ReceiveFailure, null);
                }
            }
            return((read == 0) ? (-1) : read);
        }
예제 #11
0
        public override IAsyncResult BeginGetResponse(AsyncCallback callback, object state)
        {
            bool send = (method == "PUT" || method == "POST");

            if (send)
            {
                if ((!KeepAlive || (ContentLength == -1 && !SendChunked)) && !AllowWriteStreamBuffering)
                {
                    throw new ProtocolViolationException("Content-Length not set");
                }
            }

            CommonChecks(send);
            Monitor.Enter(this);
            getResponseCalled = true;
            if (asyncRead != null && !haveResponse)
            {
                Monitor.Exit(this);
                throw new InvalidOperationException("Cannot re-call start of asynchronous " +
                                                    "method while a previous call is still in progress.");
            }

            CheckIfForceWrite();
            asyncRead = new WebAsyncResult(this, callback, state);
            WebAsyncResult aread = asyncRead;

            initialMethod = method;
            if (haveResponse)
            {
                if (webResponse != null)
                {
                    Exception saved = saved_exc;
                    Monitor.Exit(this);
                    if (saved == null)
                    {
                        aread.SetCompleted(true, webResponse);
                    }
                    else
                    {
                        aread.SetCompleted(true, saved);
                    }
                    aread.DoCallback();
                    return(aread);
                }
            }

            if (!requestSent)
            {
                requestSent  = true;
                redirects    = 0;
                servicePoint = GetServicePoint();
                abortHandler = servicePoint.SendRequest(this, connectionGroup);
            }

            Monitor.Exit(this);
            return(aread);
        }
예제 #12
0
		public override void Abort ()
		{
			if (Interlocked.CompareExchange (ref aborted, 1, 0) == 1)
				return;

			if (haveResponse && finished_reading)
				return;

			haveResponse = true;
			if (abortHandler != null) {
				try {
					abortHandler (this, EventArgs.Empty);
				} catch (Exception) {}
				abortHandler = null;
			}

			if (asyncWrite != null) {
				WebAsyncResult r = asyncWrite;
				if (!r.IsCompleted) {
					try {
						WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled); 
						r.SetCompleted (false, wexc);
						r.DoCallback ();
					} catch {}
				}
				asyncWrite = null;
			}			

			if (asyncRead != null) {
				WebAsyncResult r = asyncRead;
				if (!r.IsCompleted) {
					try {
						WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled); 
						r.SetCompleted (false, wexc);
						r.DoCallback ();
					} catch {}
				}
				asyncRead = null;
			}			

			if (writeStream != null) {
				try {
					writeStream.Close ();
					writeStream = null;
				} catch {}
			}

			if (webResponse != null) {
				try {
					webResponse.Close ();
					webResponse = null;
				} catch {}
			}
		}		
예제 #13
0
		public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			if (method == null)
				throw new ProtocolViolationException ("Method is null.");

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			Monitor.Enter (locker);
			getResponseCalled = true;
			if (asyncRead != null && !haveResponse) {
				Monitor.Exit (locker);
				throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
							"method while a previous call is still in progress.");
			}

			CheckIfForceWrite ();
			asyncRead = new WebAsyncResult (this, callback, state);
			WebAsyncResult aread = asyncRead;
			initialMethod = method;
			if (haveResponse) {
				Exception saved = saved_exc;
				if (webResponse != null) {
					Monitor.Exit (locker);
					if (saved == null) {
						aread.SetCompleted (true, webResponse);
					} else {
						aread.SetCompleted (true, saved);
					}
					aread.DoCallback ();
					return aread;
				} else if (saved != null) {
					Monitor.Exit (locker);
					aread.SetCompleted (true, saved);
					aread.DoCallback ();
					return aread;
				}
			}
			
			if (!requestSent) {
				requestSent = true;
				redirects = 0;
				servicePoint = GetServicePoint ();
				abortHandler = servicePoint.SendRequest (this, connectionGroup);
			}

			Monitor.Exit (locker);
			return aread;
		}
        public override int Read(byte[] buffer, int offset, int size)
        {
            AsyncCallback  cb             = new AsyncCallback(this.ReadCallbackWrapper);
            WebAsyncResult webAsyncResult = (WebAsyncResult)this.BeginRead(buffer, offset, size, cb, null);

            if (!webAsyncResult.IsCompleted && !webAsyncResult.WaitUntilComplete(this.ReadTimeout, false))
            {
                this.nextReadCalled = true;
                this.cnc.Close(true);
                throw new WebException("The operation has timed out.", WebExceptionStatus.Timeout);
            }
            return(this.EndRead(webAsyncResult));
        }
예제 #15
0
        public override Stream GetRequestStream()
        {
            IAsyncResult asyncResult = BeginGetRequestStream(null, null);

            asyncWrite = (WebAsyncResult)asyncResult;
            if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false))
            {
                Abort();
                throw new WebException("The request timed out", WebExceptionStatus.Timeout);
            }

            return(EndGetRequestStream(asyncResult));
        }
예제 #16
0
        public override int Read(byte[] buffer, int offset, int size)
        {
            AsyncCallback  cb             = ReadCallbackWrapper;
            WebAsyncResult webAsyncResult = (WebAsyncResult)BeginRead(buffer, offset, size, cb, null);

            if (!webAsyncResult.IsCompleted && !webAsyncResult.WaitUntilComplete(ReadTimeout, exitContext: false))
            {
                nextReadCalled = true;
                cnc.Close(sendNext: true);
                throw new WebException("The operation has timed out.", WebExceptionStatus.Timeout);
            }
            return(EndRead(webAsyncResult));
        }
예제 #17
0
 private void ReadCallbackWrapper(IAsyncResult r)
 {
     if (r.AsyncState != null)
     {
         WebAsyncResult webAsyncResult = (WebAsyncResult)r.AsyncState;
         webAsyncResult.InnerAsyncResult = r;
         webAsyncResult.DoCallback();
     }
     else
     {
         EndRead(r);
     }
 }
예제 #18
0
        public override void EndWrite(IAsyncResult r)
        {
            if (r == null)
            {
                throw new ArgumentNullException("r");
            }

            WebAsyncResult result = r as WebAsyncResult;

            if (result == null)
            {
                throw new ArgumentException("Invalid IAsyncResult");
            }

            if (result.EndCalled)
            {
                return;
            }

            result.EndCalled = true;
            if (result.AsyncWriteAll)
            {
                result.WaitUntilComplete();
                if (result.GotException)
                {
                    throw result.Exception;
                }
                return;
            }

            if (allowBuffering && !sendChunked)
            {
                return;
            }

            if (result.GotException)
            {
                throw result.Exception;
            }

            if (sendChunked)
            {
                lock (locker) {
                    pendingWrites--;
                    if (pendingWrites == 0)
                    {
                        pending.Set();
                    }
                }
            }
        }
        public override void Write(byte[] buffer, int offset, int size)
        {
            AsyncCallback  cb             = new AsyncCallback(this.WriteCallbackWrapper);
            WebAsyncResult webAsyncResult = (WebAsyncResult)this.BeginWrite(buffer, offset, size, cb, null);

            if (!webAsyncResult.IsCompleted && !webAsyncResult.WaitUntilComplete(this.WriteTimeout, false))
            {
                this.KillBuffer();
                this.nextReadCalled = true;
                this.cnc.Close(true);
                throw new IOException("Write timed out.");
            }
            this.EndWrite(webAsyncResult);
        }
예제 #20
0
        public override void Write(byte[] buffer, int offset, int size)
        {
            AsyncCallback  cb             = WriteCallbackWrapper;
            WebAsyncResult webAsyncResult = (WebAsyncResult)BeginWrite(buffer, offset, size, cb, null);

            if (!webAsyncResult.IsCompleted && !webAsyncResult.WaitUntilComplete(WriteTimeout, exitContext: false))
            {
                KillBuffer();
                nextReadCalled = true;
                cnc.Close(sendNext: true);
                throw new IOException("Write timed out.");
            }
            EndWrite(webAsyncResult);
        }
예제 #21
0
        public override int Read(byte [] buffer, int offset, int size)
        {
            AsyncCallback  cb  = cb_wrapper;
            WebAsyncResult res = (WebAsyncResult)BeginRead(buffer, offset, size, cb, null);

            if (!res.IsCompleted && !res.WaitUntilComplete(ReadTimeout, false))
            {
                nextReadCalled = true;
                cnc.Close(true);
                throw new WebException("The operation has timed out.", WebExceptionStatus.Timeout);
            }

            return(EndRead(res));
        }
예제 #22
0
        public override IAsyncResult BeginGetRequestStream(AsyncCallback callback, object state)
        {
            if (aborted)
            {
                throw new WebException("The request was previosly aborted.");
            }

            bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
                          method == "TRACE" || method == "DELETE");

            if (method == null || !send)
            {
                throw new ProtocolViolationException("Cannot send data when method is: " + method);
            }

            CommonChecks(send);

            lock (locker)
            {
                if (asyncWrite != null)
                {
                    throw new InvalidOperationException("Cannot re-call start of asynchronous " +
                                                        "method while a previous call is still in progress.");
                }

                asyncWrite    = new WebAsyncResult(this, callback, state);
                initialMethod = method;
                if (haveRequest)
                {
                    if (writeStream != null)
                    {
                        asyncWrite.SetCompleted(true, writeStream);
                        asyncWrite.DoCallback();
                        return(asyncWrite);
                    }
                }

                gotRequestStream = true;
                WebAsyncResult result = asyncWrite;
                if (!requestSent)
                {
                    requestSent  = true;
                    redirects    = 0;
                    servicePoint = GetServicePoint();
                    abortHandler = servicePoint.SendRequest(this, connectionGroup);
                }
                return(result);
            }
        }
예제 #23
0
        public override void EndWrite(IAsyncResult r)
        {
            if (r == null)
            {
                throw new ArgumentNullException("r");
            }

            WebAsyncResult result = r as WebAsyncResult;

            if (result == null)
            {
                throw new ArgumentException("Invalid IAsyncResult");
            }

            if (result.EndCalled)
            {
                return;
            }

            result.EndCalled = true;

            if (allowBuffering && !sendChunked)
            {
                return;
            }

            if (result.GotException)
            {
                throw result.Exception;
            }

            try {
                cnc.EndWrite(result.InnerAsyncResult);
                result.SetCompleted(false, 0);
            } catch (Exception e) {
                result.SetCompleted(false, e);
            }

            if (sendChunked)
            {
                lock (locker) {
                    pendingWrites--;
                    if (pendingWrites == 0)
                    {
                        pending.Set();
                    }
                }
            }
        }
예제 #24
0
        public override void Write(byte [] buffer, int offset, int size)
        {
            AsyncCallback  cb  = cb_wrapper;
            WebAsyncResult res = (WebAsyncResult)BeginWrite(buffer, offset, size, cb, null);

            if (!res.IsCompleted && !res.WaitUntilComplete(WriteTimeout, false))
            {
                KillBuffer();
                nextReadCalled = true;
                cnc.Close(true);
                throw new IOException("Write timed out.");
            }

            EndWrite(res);
        }
예제 #25
0
        internal IAsyncResult BeginRead(HttpWebRequest request, byte[] buffer, int offset, int size, AsyncCallback cb, object state)
        {
            lock (this)
            {
                if (this.Data.request != request)
                {
                    throw new ObjectDisposedException(typeof(System.Net.Sockets.NetworkStream).FullName);
                }
                if (this.nstream == null)
                {
                    return(null);
                }
            }
            IAsyncResult asyncResult = null;

            if (this.chunkedRead)
            {
                if (!this.chunkStream.WantMore)
                {
                    goto IL_9A;
                }
            }
            try
            {
                asyncResult = this.nstream.BeginRead(buffer, offset, size, cb, state);
                cb          = null;
            }
            catch (Exception)
            {
                this.HandleError(WebExceptionStatus.ReceiveFailure, null, "chunked BeginRead");
                throw;
            }
IL_9A:
            if (this.chunkedRead)
            {
                WebAsyncResult webAsyncResult = new WebAsyncResult(cb, state, buffer, offset, size);
                webAsyncResult.InnerAsyncResult = asyncResult;
                if (asyncResult == null)
                {
                    webAsyncResult.SetCompleted(true, null);
                    webAsyncResult.DoCallback();
                }
                return(webAsyncResult);
            }
            return(asyncResult);
        }
예제 #26
0
        public override void Abort()
        {
            haveResponse = true;
            aborted      = true;
            if (asyncWrite != null)
            {
                WebAsyncResult r    = asyncWrite;
                WebException   wexc = new WebException("Aborted.", WebExceptionStatus.RequestCanceled);
                r.SetCompleted(false, wexc);
                r.DoCallback();
                asyncWrite = null;
            }

            if (asyncRead != null)
            {
                WebAsyncResult r    = asyncRead;
                WebException   wexc = new WebException("Aborted.", WebExceptionStatus.RequestCanceled);
                r.SetCompleted(false, wexc);
                r.DoCallback();
                asyncRead = null;
            }

            if (abortHandler != null)
            {
                try {
                    abortHandler(this, EventArgs.Empty);
                } catch (Exception) {}
                abortHandler = null;
            }

            if (writeStream != null)
            {
                try {
                    writeStream.Close();
                    writeStream = null;
                } catch {}
            }

            if (webResponse != null)
            {
                try {
                    webResponse.Close();
                    webResponse = null;
                } catch {}
            }
        }
예제 #27
0
        internal IAsyncResult BeginRead(HttpWebRequest request, byte [] buffer, int offset, int size, AsyncCallback cb, object state)
        {
            lock (this)
            {
                if (Data.request != request)
                {
                    throw new ObjectDisposedException(typeof(NetworkStream).FullName);
                }
                if (nstream == null)
                {
                    return(null);
                }
            }

            IAsyncResult result = null;

            if (!chunkedRead || chunkStream.WantMore)
            {
                try
                {
                    result = nstream.BeginRead(buffer, offset, size, cb, state);
                    cb     = null;
                }
                catch (Exception)
                {
                    HandleError(WebExceptionStatus.ReceiveFailure, null, "chunked BeginRead");
                    throw;
                }
            }

            if (chunkedRead)
            {
                WebAsyncResult wr = new WebAsyncResult(cb, state, buffer, offset, size);
                wr.InnerAsyncResult = result;
                if (result == null)
                {
                    // Will be completed from the data in ChunkStream
                    wr.SetCompleted(true, (Exception)null);
                    wr.DoCallback();
                }
                return(wr);
            }

            return(result);
        }
예제 #28
0
		public override IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state) 
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
					method == "TRACE");
			if (method == null || !send)
				throw new ProtocolViolationException ("Cannot send data when method is: " + method);

			if (contentLength == -1 && !sendChunked && !allowBuffering && KeepAlive)
				throw new ProtocolViolationException ("Content-Length not set");

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			lock (locker)
			{
				if (asyncWrite != null) {
					throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
								"method while a previous call is still in progress.");
				}
	
				asyncWrite = new WebAsyncResult (this, callback, state);
				initialMethod = method;
				if (haveRequest) {
					if (writeStream != null) {
						asyncWrite.SetCompleted (true, writeStream);
						asyncWrite.DoCallback ();
						return asyncWrite;
					}
				}
				
				gotRequestStream = true;
				WebAsyncResult result = asyncWrite;
				if (!requestSent) {
					requestSent = true;
					redirects = 0;
					servicePoint = GetServicePoint ();
					abortHandler = servicePoint.SendRequest (this, connectionGroup);
				}
				return result;
			}
		}
예제 #29
0
        private void WriteCallbackWrapper(IAsyncResult r)
        {
            WebAsyncResult webAsyncResult = r as WebAsyncResult;

            if (webAsyncResult == null || !webAsyncResult.AsyncWriteAll)
            {
                if (r.AsyncState != null)
                {
                    webAsyncResult = (WebAsyncResult)r.AsyncState;
                    webAsyncResult.InnerAsyncResult = r;
                    webAsyncResult.DoCallback();
                }
                else
                {
                    EndWrite(r);
                }
            }
        }
예제 #30
0
		void HandleNtlmAuth (WebAsyncResult r)
		{
			WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
			if (wce != null) {
				WebConnection cnc = wce.Connection;
				cnc.PriorityRequest = this;
				bool isProxy = (proxy != null && !proxy.IsBypassed (actualUri));
				ICredentials creds = (!isProxy) ? credentials : proxy.Credentials;
				if (creds != null) {
					cnc.NtlmCredential = creds.GetCredential (requestUri, "NTLM");
					cnc.UnsafeAuthenticatedConnectionSharing = unsafe_auth_blah;
				}
			}
			r.Reset ();
			finished_reading = false;
			haveResponse = false;
			webResponse.ReadAll ();
			webResponse = null;
		}
예제 #31
0
		void GetResponseAsyncCB2 (WebAsyncResult aread)
		{
			if (haveResponse) {
				Exception saved = saved_exc;
				if (webResponse != null) {
					Monitor.Exit (locker);
					if (saved == null) {
						aread.SetCompleted (true, webResponse);
					} else {
						aread.SetCompleted (true, saved);
					}
					aread.DoCallback ();
					return;
				} else if (saved != null) {
					Monitor.Exit (locker);
					aread.SetCompleted (true, saved);
					aread.DoCallback ();
					return;
				}
			}

			if (!requestSent) {
				requestSent = true;
				redirects = 0;
				servicePoint = GetServicePoint ();
				abortHandler = servicePoint.SendRequest (this, connectionGroup);
			}

			Monitor.Exit (locker);
		}
예제 #32
0
		internal WebAsyncResult WriteRequestAsync (AsyncCallback callback, object state)
		{
			if (requestWritten)
				return null;

			requestWritten = true;
			if (sendChunked)
				return null;

			if (!allowBuffering || writeBuffer == null)
				return null;

			byte[] bytes = writeBuffer.GetBuffer ();
			int length = (int)writeBuffer.Length;
			if (request.ContentLength != -1 && request.ContentLength < length) {
				nextReadCalled = true;
				cnc.Close (true);
				throw new WebException ("Specified Content-Length is less than the number of bytes to write", null,
					WebExceptionStatus.ServerProtocolViolation, null);
			}

			var result = new WebAsyncResult (callback, state);
			result.InnerAsyncResult = SetHeadersAsync (true, WriteRequestAsyncCB, result);
			if (result.InnerAsyncResult == null)
				WriteRequestAsyncCB (result);
			return result;
		}
예제 #33
0
		public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			if (method == null)
				throw new ProtocolViolationException ("Method is null.");

#if !NET_2_0
			bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
						method == "TRACE" || method == "DELETE");
			if (send && contentLength < 0 && !sendChunked && !allowBuffering && KeepAlive)
				throw new ProtocolViolationException ("Buffering is disabled, ContentLength is negative and SendChunked is disabled.");

			if (!send && (contentLength > -1 || sendChunked))
				throw new ProtocolViolationException ("ContentLength can't be set for non-write operations.");
#endif

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			Monitor.Enter (locker);
			getResponseCalled = true;
			if (asyncRead != null && !haveResponse) {
				Monitor.Exit (locker);
				throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
							"method while a previous call is still in progress.");
			}

			CheckIfForceWrite ();
			asyncRead = new WebAsyncResult (this, callback, state);
			WebAsyncResult aread = asyncRead;
			initialMethod = method;
			if (haveResponse) {
				Exception saved = saved_exc;
				if (webResponse != null) {
					Monitor.Exit (locker);
					if (saved == null) {
						aread.SetCompleted (true, webResponse);
					} else {
						aread.SetCompleted (true, saved);
					}
					aread.DoCallback ();
					return aread;
				} else if (saved != null) {
					Monitor.Exit (locker);
					aread.SetCompleted (true, saved);
					aread.DoCallback ();
					return aread;
				}
			}
			
			if (!requestSent) {
				requestSent = true;
				redirects = 0;
				servicePoint = GetServicePoint ();
				abortHandler = servicePoint.SendRequest (this, connectionGroup);
			}

			Monitor.Exit (locker);
			return aread;
		}
예제 #34
0
		void SetWriteStreamCB (IAsyncResult ar)
		{
			WebAsyncResult result = ar as WebAsyncResult;

			if (result.Exception != null) {
				WebException wexc = result.Exception as WebException;
				if (wexc != null) {
					SetWriteStreamError (wexc.Status, wexc);
					return;
				}
				SetWriteStreamError (WebExceptionStatus.SendFailure, result.Exception);
				return;
			}
		
			haveRequest = true;

			if (bodyBuffer != null) {
				// The body has been written and buffered. The request "user"
				// won't write it again, so we must do it.
				if (auth_state.NtlmAuthState != NtlmAuthState.Challenge && proxy_auth_state.NtlmAuthState != NtlmAuthState.Challenge) {
					// FIXME: this is a blocking call on the thread pool that could lead to thread pool exhaustion
					writeStream.Write (bodyBuffer, 0, bodyBufferLength);
					bodyBuffer = null;
					writeStream.Close ();
				}
			} else if (method != "HEAD" && method != "GET" && method != "MKCOL" && method != "CONNECT" &&
					method != "TRACE") {
				if (getResponseCalled && !writeStream.RequestWritten)
					// FIXME: this is a blocking call on the thread pool that could lead to thread pool exhaustion
					writeStream.WriteRequest ();
			}

			if (asyncWrite != null) {
				asyncWrite.SetCompleted (false, writeStream);
				asyncWrite.DoCallback ();
				asyncWrite = null;
			}
		}
예제 #35
0
		public override void Abort ()
		{
			if (Interlocked.CompareExchange (ref aborted, 1, 0) == 1)
				return;

			if (haveResponse && finished_reading)
				return;

			haveResponse = true;
			if (abortHandler != null) {
				try {
					abortHandler (this, EventArgs.Empty);
				} catch (Exception) {}
				abortHandler = null;
			}

			if (asyncWrite != null) {
				WebAsyncResult r = asyncWrite;
				if (!r.IsCompleted) {
					try {
						WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled); 
						r.SetCompleted (false, wexc);
						r.DoCallback ();
					} catch {}
				}
				asyncWrite = null;
			}			

			if (asyncRead != null) {
				WebAsyncResult r = asyncRead;
				if (!r.IsCompleted) {
					try {
						WebException wexc = new WebException ("Aborted.", WebExceptionStatus.RequestCanceled); 
						r.SetCompleted (false, wexc);
						r.DoCallback ();
					} catch {}
				}
				asyncRead = null;
			}			

			if (writeStream != null) {
				try {
					writeStream.Close ();
					writeStream = null;
				} catch {}
			}

			if (webResponse != null) {
				try {
					webResponse.Close ();
					webResponse = null;
				} catch {}
			}
		}		
예제 #36
0
		internal void WriteRequest ()
		{
			if (requestWritten)
				return;

			requestWritten = true;
			if (sendChunked)
				return;

			if (!allowBuffering || writeBuffer == null)
				return;

			byte [] bytes = writeBuffer.GetBuffer ();
			int length = (int) writeBuffer.Length;
			if (request.ContentLength != -1 && request.ContentLength < length) {
				nextReadCalled = true;
				cnc.Close (true);
				throw new WebException ("Specified Content-Length is less than the number of bytes to write", null,
							WebExceptionStatus.ServerProtocolViolation, null);
			}

			if (!headersSent) {
				string method = request.Method;
				bool no_writestream = (method == "GET" || method == "CONNECT" || method == "HEAD" ||
							method == "TRACE");
				if (!no_writestream)
					request.InternalContentLength = length;

				byte[] requestHeaders = request.GetRequestHeaders ();
				WebAsyncResult ar = new WebAsyncResult (null, null);
				SetHeadersAsync (requestHeaders, ar);
				ar.AsyncWaitHandle.WaitOne ();
				if (ar.Exception != null)
					throw ar.Exception;
			}

			if (cnc.Data.StatusCode != 0 && cnc.Data.StatusCode != 100)
				return;
				
			IAsyncResult result = null;
			if (length > 0)
				result = cnc.BeginWrite (request, bytes, 0, length, null, null);
			
			if (!initRead) {
				initRead = true;
				WebConnection.InitRead (cnc);
			}

			if (length > 0) 
				complete_request_written = cnc.EndWrite (request, result);
			else
				complete_request_written = true;
		}
예제 #37
0
		internal void SetResponseError (WebExceptionStatus status, Exception e, string where)
		{
			if (Aborted)
				return;
			lock (locker) {
			string msg = String.Format ("Error getting response stream ({0}): {1}", where, status);
			WebAsyncResult r = asyncRead;
			if (r == null)
				r = asyncWrite;

			WebException wexc;
			if (e is WebException) {
				wexc = (WebException) e;
			} else {
				wexc = new WebException (msg, e, status, null); 
			}
			if (r != null) {
				if (!r.IsCompleted) {
					r.SetCompleted (false, wexc);
					r.DoCallback ();
				} else if (r == asyncWrite) {
					saved_exc = wexc;
				}
				haveResponse = true;
				asyncRead = null;
				asyncWrite = null;
			} else {
				haveResponse = true;
				saved_exc = wexc;
			}
			}
		}
예제 #38
0
		internal void SetResponseData (WebConnectionData data)
		{
			lock (locker) {
			if (Aborted) {
				if (data.stream != null)
					data.stream.Close ();
				return;
			}

			WebException wexc = null;
			try {
				webResponse = new HttpWebResponse (actualUri, method, data, cookieContainer);
			} catch (Exception e) {
				wexc = new WebException (e.Message, e, WebExceptionStatus.ProtocolError, null); 
				if (data.stream != null)
					data.stream.Close ();
			}

			if (wexc == null && (method == "POST" || method == "PUT")) {
				CheckSendError (data);
				if (saved_exc != null)
					wexc = (WebException) saved_exc;
			}

			WebAsyncResult r = asyncRead;

			bool forced = false;
			if (r == null && webResponse != null) {
				// This is a forced completion (302, 204)...
				forced = true;
				r = new WebAsyncResult (null, null);
				r.SetCompleted (false, webResponse);
			}

			if (r != null) {
				if (wexc != null) {
					haveResponse = true;
					if (!r.IsCompleted)
						r.SetCompleted (false, wexc);
					r.DoCallback ();
					return;
				}

				bool redirected;
				try {
					redirected = CheckFinalStatus (r);
					if (!redirected) {
						if (ntlm_auth_state != NtlmAuthState.None && authCompleted && webResponse != null
							&& (int)webResponse.StatusCode < 400) {
							WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
							if (wce != null) {
								WebConnection cnc = wce.Connection;
								cnc.NtlmAuthenticated = true;
							}
						}

						// clear internal buffer so that it does not
						// hold possible big buffer (bug #397627)
						if (writeStream != null)
							writeStream.KillBuffer ();

						haveResponse = true;
						r.SetCompleted (false, webResponse);
						r.DoCallback ();
					} else {
						if (webResponse != null) {
							if (ntlm_auth_state != NtlmAuthState.None) {
								HandleNtlmAuth (r);
								return;
							}
							webResponse.Close ();
						}
						finished_reading = false;
						haveResponse = false;
						webResponse = null;
						r.Reset ();
						servicePoint = GetServicePoint ();
						abortHandler = servicePoint.SendRequest (this, connectionGroup);
					}
				} catch (WebException wexc2) {
					if (forced) {
						saved_exc = wexc2;
						haveResponse = true;
					}
					r.SetCompleted (false, wexc2);
					r.DoCallback ();
					return;
				} catch (Exception ex) {
					wexc = new WebException (ex.Message, ex, WebExceptionStatus.ProtocolError, null); 
					if (forced) {
						saved_exc = wexc;
						haveResponse = true;
					}
					r.SetCompleted (false, wexc);
					r.DoCallback ();
					return;
				}
			}
			}
		}
예제 #39
0
		// Returns true if redirected
		bool CheckFinalStatus (WebAsyncResult result)
		{
			if (result.GotException)
				throw result.Exception;

			Exception throwMe = result.Exception;
			bodyBuffer = null;

			HttpWebResponse resp = result.Response;
			WebExceptionStatus protoError = WebExceptionStatus.ProtocolError;
			HttpStatusCode code = 0;
			if (throwMe == null && webResponse != null) {
				code = webResponse.StatusCode;
				if (!authCompleted && ((code == HttpStatusCode.Unauthorized && credentials != null) ||
				     (ProxyQuery && code == HttpStatusCode.ProxyAuthenticationRequired))) {
					if (!usedPreAuth && CheckAuthorization (webResponse, code)) {
						// Keep the written body, so it can be rewritten in the retry
						if (InternalAllowBuffering) {
							bodyBuffer = writeStream.WriteBuffer;
							bodyBufferLength = writeStream.WriteBufferLength;
							return true;
						} else if (method != "PUT" && method != "POST") {
							return true;
						}
						
						writeStream.InternalClose ();
						writeStream = null;
						webResponse.Close ();
						webResponse = null;

						throw new WebException ("This request requires buffering " +
									"of data for authentication or " +
									"redirection to be sucessful.");
					}
				}

				if ((int) code >= 400) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
					webResponse.ReadAll ();
				} else if ((int) code == 304 && allowAutoRedirect) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
				} else if ((int) code >= 300 && allowAutoRedirect && redirects >= maxAutoRedirect) {
					throwMe = new WebException ("Max. redirections exceeded.", null,
								    protoError, webResponse);
					webResponse.ReadAll ();
				}
			}

			if (throwMe == null) {
				bool b = false;
				int c = (int) code;
				if (allowAutoRedirect && c >= 300) {
					if (InternalAllowBuffering && writeStream.WriteBufferLength > 0) {
						bodyBuffer = writeStream.WriteBuffer;
						bodyBufferLength = writeStream.WriteBufferLength;
					}
					b = Redirect (result, code);
				}

				if (resp != null && c >= 300 && c != 304)
					resp.ReadAll ();

				return b;
			}

			if (writeStream != null) {
				writeStream.InternalClose ();
				writeStream = null;
			}

			webResponse = null;

			throw throwMe;
		}
		// Returns true if redirected
		bool CheckFinalStatus (WebAsyncResult result)
		{
			if (result.GotException) {
				bodyBuffer = null;
				throw result.Exception;
			}

			Exception throwMe = result.Exception;

			HttpWebResponse resp = result.Response;
			WebExceptionStatus protoError = WebExceptionStatus.ProtocolError;
			HttpStatusCode code = 0;
			if (throwMe == null && webResponse != null) {
				code = webResponse.StatusCode;
				if ((!auth_state.IsCompleted && code == HttpStatusCode.Unauthorized && credentials != null) ||
					(ProxyQuery && !proxy_auth_state.IsCompleted && code == HttpStatusCode.ProxyAuthenticationRequired)) {
					if (!usedPreAuth && CheckAuthorization (webResponse, code)) {
						// Keep the written body, so it can be rewritten in the retry
						if (MethodWithBuffer) {
							if (AllowWriteStreamBuffering) {
								if (writeStream.WriteBufferLength > 0) {
									bodyBuffer = writeStream.WriteBuffer;
									bodyBufferLength = writeStream.WriteBufferLength;
								}

								return true;
							}

							//
							// Buffering is not allowed but we have alternative way to get same content (we
							// need to resent it due to NTLM Authentication).
					 		//
							if (ResendContentFactory != null) {
								using (var ms = new MemoryStream ()) {
									ResendContentFactory (ms);
									bodyBuffer = ms.ToArray ();
									bodyBufferLength = bodyBuffer.Length;
								}
								return true;
							}
						} else if (method != "PUT" && method != "POST") {
							bodyBuffer = null;
							return true;
						}

						if (!ThrowOnError)
							return false;
							
						writeStream.InternalClose ();
						writeStream = null;
						webResponse.Close ();
						webResponse = null;
						bodyBuffer = null;
							
						throw new WebException ("This request requires buffering " +
									"of data for authentication or " +
									"redirection to be sucessful.");
					}
				}

				bodyBuffer = null;
				if ((int) code >= 400) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
					webResponse.ReadAll ();
				} else if ((int) code == 304 && allowAutoRedirect) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
				} else if ((int) code >= 300 && allowAutoRedirect && redirects >= maxAutoRedirect) {
					throwMe = new WebException ("Max. redirections exceeded.", null,
								    protoError, webResponse);
					webResponse.ReadAll ();
				}
			}

			bodyBuffer = null;
			if (throwMe == null) {
				bool b = false;
				int c = (int) code;
				if (allowAutoRedirect && c >= 300) {
					b = Redirect (result, code, webResponse);
					if (InternalAllowBuffering && writeStream.WriteBufferLength > 0) {
						bodyBuffer = writeStream.WriteBuffer;
						bodyBufferLength = writeStream.WriteBufferLength;
					}
					if (b && !unsafe_auth_blah) {
						auth_state.Reset ();
						proxy_auth_state.Reset ();
					}
				}

				if (resp != null && c >= 300 && c != 304)
					resp.ReadAll ();

				return b;
			}
				
			if (!ThrowOnError)
				return false;

			if (writeStream != null) {
				writeStream.InternalClose ();
				writeStream = null;
			}

			webResponse = null;

			throw throwMe;
		}
		internal void SetWriteStream (WebConnectionStream stream)
		{
			if (Aborted)
				return;
			
			writeStream = stream;
			if (bodyBuffer != null) {
				webHeaders.RemoveInternal ("Transfer-Encoding");
				contentLength = bodyBufferLength;
				writeStream.SendChunked = false;
			}

			writeStream.SetHeadersAsync (false, result => {
				if (result.GotException) {
					SetWriteStreamError (result.Exception);
					return;
				}

				haveRequest = true;

				SetWriteStreamInner (inner => {
					if (inner.GotException) {
						SetWriteStreamError (inner.Exception);
						return;
					}

					if (asyncWrite != null) {
						asyncWrite.SetCompleted (inner.CompletedSynchronously, writeStream);
						asyncWrite.DoCallback ();
						asyncWrite = null;
					}
				});
			});
		}
예제 #42
0
		internal void SetHeadersAsync (byte[] buffer, WebAsyncResult result)
		{
			if (headersSent)
				return;

			headers = buffer;
			long cl = request.ContentLength;
			string method = request.Method;
			bool no_writestream = (method == "GET" || method == "CONNECT" || method == "HEAD" ||
						method == "TRACE");
			bool webdav = (method == "PROPFIND" || method == "PROPPATCH" || method == "MKCOL" ||
			               method == "COPY" || method == "MOVE" || method == "LOCK" ||
			               method == "UNLOCK");
			if (sendChunked || cl > -1 || no_writestream || webdav) {

				headersSent = true;

				try {
					result.InnerAsyncResult = cnc.BeginWrite (request, headers, 0, headers.Length, new AsyncCallback(SetHeadersCB), result);
					if (result.InnerAsyncResult == null) {
						// when does BeginWrite return null? Is the case when the request is aborted?
						if (!result.IsCompleted)
							result.SetCompleted (true, 0);
						result.DoCallback ();
					}
				} catch (Exception exc) {
					result.SetCompleted (true, exc);
					result.DoCallback ();
				}
			} else {
				result.SetCompleted (true, 0);
				result.DoCallback ();
			}
		}
예제 #43
0
		bool Redirect (WebAsyncResult result, HttpStatusCode code)
		{
			redirects++;
			Exception e = null;
			string uriString = null;

			switch (code) {
			case HttpStatusCode.Ambiguous: // 300
				e = new WebException ("Ambiguous redirect.");
				break;
			case HttpStatusCode.MovedPermanently: // 301
			case HttpStatusCode.Redirect: // 302
			case HttpStatusCode.TemporaryRedirect: // 307
				/* MS follows the redirect for POST too
				if (method != "GET" && method != "HEAD") // 10.3
					return false;
				*/

				contentLength = -1;
				bodyBufferLength = 0;
				bodyBuffer = null;
				if (code != HttpStatusCode.TemporaryRedirect)
					method = "GET";
				uriString = webResponse.Headers ["Location"];
				break;
			case HttpStatusCode.SeeOther: //303
				method = "GET";
				uriString = webResponse.Headers ["Location"];
				break;
			case HttpStatusCode.NotModified: // 304
				return false;
			case HttpStatusCode.UseProxy: // 305
				e = new NotImplementedException ("Proxy support not available.");
				break;
			case HttpStatusCode.Unused: // 306
			default:
				e = new ProtocolViolationException ("Invalid status code: " + (int) code);
				break;
			}

			if (e != null)
				throw e;

			if (uriString == null)
				throw new WebException ("No Location header found for " + (int) code,
							WebExceptionStatus.ProtocolError);

			Uri prev = actualUri;
			try {
				actualUri = new Uri (actualUri, uriString);
			} catch (Exception) {
				throw new WebException (String.Format ("Invalid URL ({0}) for {1}",
									uriString, (int) code),
									WebExceptionStatus.ProtocolError);
			}

			hostChanged = (actualUri.Scheme != prev.Scheme || Host != prev.Authority);
			return true;
		}
예제 #44
0
		internal void SetWriteStream (WebConnectionStream stream)
		{
			if (Aborted)
				return;
			
			writeStream = stream;
			if (bodyBuffer != null) {
				webHeaders.RemoveInternal ("Transfer-Encoding");
				contentLength = bodyBufferLength;
				writeStream.SendChunked = false;
			}

			SendRequestHeaders (false);

			haveRequest = true;
			
			if (bodyBuffer != null) {
				// The body has been written and buffered. The request "user"
				// won't write it again, so we must do it.
				if (ntlm_auth_state != NtlmAuthState.Challenge) {
					writeStream.Write (bodyBuffer, 0, bodyBufferLength);
					bodyBuffer = null;
					writeStream.Close ();
				}
			} else if (method != "HEAD" && method != "GET" && method != "MKCOL" && method != "CONNECT" &&
					method != "TRACE") {
				if (getResponseCalled && !writeStream.RequestWritten)
					writeStream.WriteRequest ();
			}

			if (asyncWrite != null) {
				asyncWrite.SetCompleted (false, stream);
				asyncWrite.DoCallback ();
				asyncWrite = null;
			}
		}
예제 #45
0
		public override IAsyncResult BeginGetRequestStream (AsyncCallback callback, object state) 
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			bool send = !(method == "GET" || method == "CONNECT" || method == "HEAD" ||
					method == "TRACE");
			if (method == null || !send)
				throw new ProtocolViolationException ("Cannot send data when method is: " + method);

			if (contentLength == -1 && !sendChunked && !allowBuffering && KeepAlive)
				throw new ProtocolViolationException ("Content-Length not set");

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			lock (locker)
			{
				if (getResponseCalled)
					throw new InvalidOperationException ("The operation cannot be performed once the request has been submitted.");

				if (asyncWrite != null) {
					throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
								"method while a previous call is still in progress.");
				}
	
				asyncWrite = new WebAsyncResult (this, callback, state);
				initialMethod = method;
				if (haveRequest) {
					if (writeStream != null) {
						asyncWrite.SetCompleted (true, writeStream);
						asyncWrite.DoCallback ();
						return asyncWrite;
					}
				}
				
				gotRequestStream = true;
				WebAsyncResult result = asyncWrite;
				if (!requestSent) {
					requestSent = true;
					redirects = 0;
					servicePoint = GetServicePoint ();
					abortHandler = servicePoint.SendRequest (this, connectionGroup);
				}
				return result;
			}
		}
예제 #46
0
		void HandleNtlmAuth (WebAsyncResult r)
		{
			WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
			if (wce != null) {
				WebConnection cnc = wce.Connection;
				cnc.PriorityRequest = this;
				bool isProxy = (proxy != null && !proxy.IsBypassed (actualUri));
				ICredentials creds = (!isProxy) ? credentials : proxy.Credentials;
				if (creds != null) {
					cnc.NtlmCredential = creds.GetCredential (requestUri, "NTLM");
					cnc.UnsafeAuthenticatedConnectionSharing = unsafe_auth_blah;
				}
			}
			r.Reset ();
			finished_reading = false;
			haveResponse = false;
			webResponse.ReadAll ();
			webResponse = null;
		}
예제 #47
0
		public override Stream GetRequestStream()
		{
			IAsyncResult asyncResult = asyncWrite;
			if (asyncResult == null) {
				asyncResult = BeginGetRequestStream (null, null);
				asyncWrite = (WebAsyncResult) asyncResult;
			}

			if (!asyncResult.IsCompleted && !asyncResult.AsyncWaitHandle.WaitOne (timeout, false)) {
				Abort ();
				throw new WebException ("The request timed out", WebExceptionStatus.Timeout);
			}

			return EndGetRequestStream (asyncResult);
		}
예제 #48
0
		// Returns true if redirected
		bool CheckFinalStatus (WebAsyncResult result)
		{
			if (result.GotException) {
				bodyBuffer = null;
				throw result.Exception;
			}

			Exception throwMe = result.Exception;

			HttpWebResponse resp = result.Response;
			WebExceptionStatus protoError = WebExceptionStatus.ProtocolError;
			HttpStatusCode code = 0;
			if (throwMe == null && webResponse != null) {
				code = webResponse.StatusCode;
				if (!authCompleted && ((code == HttpStatusCode.Unauthorized && credentials != null) ||
				     (ProxyQuery && code == HttpStatusCode.ProxyAuthenticationRequired))) {
					if (!usedPreAuth && CheckAuthorization (webResponse, code)) {
						// Keep the written body, so it can be rewritten in the retry
						if (InternalAllowBuffering) {
							// NTLM: This is to avoid sending data in the 'challenge' request
							// We save it in the first request (first 401), don't send anything
							// in the challenge request and send it in the response request along
							// with the buffers kept form the first request.
							if (ntlm_auth_state != NtlmAuthState.Response) {
								bodyBuffer = writeStream.WriteBuffer;
								bodyBufferLength = writeStream.WriteBufferLength;
							}
							return true;
						} else if (method != "PUT" && method != "POST") {
							bodyBuffer = null;
							return true;
						}

						if (!ThrowOnError)
							return false;
							
						writeStream.InternalClose ();
						writeStream = null;
						webResponse.Close ();
						webResponse = null;
						bodyBuffer = null;
							
						throw new WebException ("This request requires buffering " +
									"of data for authentication or " +
									"redirection to be sucessful.");
					}
				}

				bodyBuffer = null;
				if ((int) code >= 400) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
					webResponse.ReadAll ();
				} else if ((int) code == 304 && allowAutoRedirect) {
					string err = String.Format ("The remote server returned an error: ({0}) {1}.",
								    (int) code, webResponse.StatusDescription);
					throwMe = new WebException (err, null, protoError, webResponse);
				} else if ((int) code >= 300 && allowAutoRedirect && redirects >= maxAutoRedirect) {
					throwMe = new WebException ("Max. redirections exceeded.", null,
								    protoError, webResponse);
					webResponse.ReadAll ();
				}
			}

			bodyBuffer = null;
			if (throwMe == null) {
				bool b = false;
				int c = (int) code;
				if (allowAutoRedirect && c >= 300) {
					if (InternalAllowBuffering && writeStream.WriteBufferLength > 0) {
						bodyBuffer = writeStream.WriteBuffer;
						bodyBufferLength = writeStream.WriteBufferLength;
					}
					b = Redirect (result, code);
					if (b && ntlm_auth_state != 0)
						ntlm_auth_state = 0;
				}

				if (resp != null && c >= 300 && c != 304)
					resp.ReadAll ();

				return b;
			}
				
			if (!ThrowOnError)
				return false;

			if (writeStream != null) {
				writeStream.InternalClose ();
				writeStream = null;
			}

			webResponse = null;

			throw throwMe;
		}
예제 #49
0
		public override IAsyncResult BeginRead (byte [] buffer, int offset, int size,
							AsyncCallback cb, object state)
		{
			if (!isRead)
				throw new NotSupportedException ("this stream does not allow reading");

			if (buffer == null)
				throw new ArgumentNullException ("buffer");

			int length = buffer.Length;
			if (offset < 0 || length < offset)
				throw new ArgumentOutOfRangeException ("offset");
			if (size < 0 || (length - offset) < size)
				throw new ArgumentOutOfRangeException ("size");

			lock (locker) {
				pendingReads++;
				pending.Reset ();
			}

			WebAsyncResult result = new WebAsyncResult (cb, state, buffer, offset, size);
			if (totalRead >= contentLength) {
				result.SetCompleted (true, -1);
				result.DoCallback ();
				return result;
			}
			
			int remaining = readBufferSize - readBufferOffset;
			if (remaining > 0) {
				int copy = (remaining > size) ? size : remaining;
				Buffer.BlockCopy (readBuffer, readBufferOffset, buffer, offset, copy);
				readBufferOffset += copy;
				offset += copy;
				size -= copy;
				totalRead += copy;
				if (size == 0 || totalRead >= contentLength) {
					result.SetCompleted (true, copy);
					result.DoCallback ();
					return result;
				}
				result.NBytes = copy;
			}

			if (cb != null)
				cb = cb_wrapper;

			if (contentLength != Int64.MaxValue && contentLength - totalRead < size)
				size = (int)(contentLength - totalRead);

			if (!read_eof) {
				result.InnerAsyncResult = cnc.BeginRead (request, buffer, offset, size, cb, result);
			} else {
				result.SetCompleted (true, result.NBytes);
				result.DoCallback ();
			}
			return result;
		}
예제 #50
0
		public override Stream EndGetRequestStream (IAsyncResult asyncResult)
		{
			if (asyncResult == null)
				throw new ArgumentNullException ("asyncResult");

			WebAsyncResult result = asyncResult as WebAsyncResult;
			if (result == null)
				throw new ArgumentException ("Invalid IAsyncResult");

			asyncWrite = result;
			result.WaitUntilComplete ();

			Exception e = result.Exception;
			if (e != null)
				throw e;

			return result.WriteStream;
		}
예제 #51
0
		public override IAsyncResult BeginWrite (byte [] buffer, int offset, int size,
							AsyncCallback cb, object state)
		{
			if (request.Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			if (isRead)
				throw new NotSupportedException ("this stream does not allow writing");

			if (buffer == null)
				throw new ArgumentNullException ("buffer");

			int length = buffer.Length;
			if (offset < 0 || length < offset)
				throw new ArgumentOutOfRangeException ("offset");
			if (size < 0 || (length - offset) < size)
				throw new ArgumentOutOfRangeException ("size");

			if (sendChunked) {
				lock (locker) {
					pendingWrites++;
					pending.Reset ();
				}
			}

			WebAsyncResult result = new WebAsyncResult (cb, state);
			AsyncCallback callback = new AsyncCallback (WriteAsyncCB);

			if (sendChunked) {
				requestWritten = true;

				string cSize = String.Format ("{0:X}\r\n", size);
				byte[] head = Encoding.ASCII.GetBytes (cSize);
				int chunkSize = 2 + size + head.Length;
				byte[] newBuffer = new byte [chunkSize];
				Buffer.BlockCopy (head, 0, newBuffer, 0, head.Length);
				Buffer.BlockCopy (buffer, offset, newBuffer, head.Length, size);
				Buffer.BlockCopy (crlf, 0, newBuffer, head.Length + size, crlf.Length);

				if (allowBuffering) {
					if (writeBuffer == null)
						writeBuffer = new MemoryStream ();
					writeBuffer.Write (buffer, offset, size);
					totalWritten += size;
				}

				buffer = newBuffer;
				offset = 0;
				size = chunkSize;
			} else {
				CheckWriteOverflow (request.ContentLength, totalWritten, size);

				if (allowBuffering) {
					if (writeBuffer == null)
						writeBuffer = new MemoryStream ();
					writeBuffer.Write (buffer, offset, size);
					totalWritten += size;

					if (request.ContentLength <= 0 || totalWritten < request.ContentLength) {
						result.SetCompleted (true, 0);
						result.DoCallback ();
						return result;
					}

					result.AsyncWriteAll = true;
					requestWritten = true;
					buffer = writeBuffer.GetBuffer ();
					offset = 0;
					size = (int)totalWritten;
				}
			}

			try {
				result.InnerAsyncResult = cnc.BeginWrite (request, buffer, offset, size, callback, result);
				if (result.InnerAsyncResult == null) {
					if (!result.IsCompleted)
						result.SetCompleted (true, 0);
					result.DoCallback ();
				}
			} catch (Exception) {
				if (!IgnoreIOErrors)
					throw;
				result.SetCompleted (true, 0);
				result.DoCallback ();
			}
			totalWritten += size;
			return result;
		}
예제 #52
0
		public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			if (method == null)
				throw new ProtocolViolationException ("Method is null.");

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			Monitor.Enter (locker);
			getResponseCalled = true;
			if (asyncRead != null && !haveResponse) {
				Monitor.Exit (locker);
				throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
							"method while a previous call is still in progress.");
			}

			CheckIfForceWrite ();
			asyncRead = new WebAsyncResult (this, callback, state);
			WebAsyncResult aread = asyncRead;
			initialMethod = method;
			if (haveResponse) {
				Exception saved = saved_exc;
				if (webResponse != null) {
					Monitor.Exit (locker);
					if (saved == null) {
						aread.SetCompleted (true, webResponse);
					} else {
						aread.SetCompleted (true, saved);
					}
					aread.DoCallback ();
					return aread;
				} else if (saved != null) {
					Monitor.Exit (locker);
					aread.SetCompleted (true, saved);
					aread.DoCallback ();
					return aread;
				}
			}
			
			if (!requestSent) {
				requestSent = true;
				redirects = 0;
				servicePoint = GetServicePoint ();
				abortHandler = servicePoint.SendRequest (this, connectionGroup);
			}

			Monitor.Exit (locker);
			return aread;
		}
예제 #53
0
		bool Redirect (WebAsyncResult result, HttpStatusCode code, WebResponse response)
		{
			redirects++;
			Exception e = null;
			string uriString = null;
			switch (code) {
			case HttpStatusCode.Ambiguous: // 300
				e = new WebException ("Ambiguous redirect.");
				break;
			case HttpStatusCode.MovedPermanently: // 301
			case HttpStatusCode.Redirect: // 302
				if (method == "POST")
					RewriteRedirectToGet ();
				break;
			case HttpStatusCode.TemporaryRedirect: // 307
				break;
			case HttpStatusCode.SeeOther: //303
				RewriteRedirectToGet ();
				break;
			case HttpStatusCode.NotModified: // 304
				return false;
			case HttpStatusCode.UseProxy: // 305
				e = new NotImplementedException ("Proxy support not available.");
				break;
			case HttpStatusCode.Unused: // 306
			default:
				e = new ProtocolViolationException ("Invalid status code: " + (int) code);
				break;
			}

			if (method != "GET" && !InternalAllowBuffering)
				e = new WebException ("The request requires buffering data to succeed.", null, WebExceptionStatus.ProtocolError, webResponse);

			if (e != null)
				throw e;

			contentLength = -1;
			uriString = webResponse.Headers ["Location"];

			if (uriString == null)
				throw new WebException ("No Location header found for " + (int) code,
							WebExceptionStatus.ProtocolError);

			Uri prev = actualUri;
			try {
				actualUri = new Uri (actualUri, uriString);
			} catch (Exception) {
				throw new WebException (String.Format ("Invalid URL ({0}) for {1}",
									uriString, (int) code),
									WebExceptionStatus.ProtocolError);
			}

			hostChanged = (actualUri.Scheme != prev.Scheme || Host != prev.Authority);
			return true;
		}
예제 #54
0
		internal IAsyncResult BeginRead (HttpWebRequest request, byte [] buffer, int offset, int size, AsyncCallback cb, object state)
		{
			Stream s = null;
			lock (this) {
				if (Data.request != request)
					throw new ObjectDisposedException (typeof (NetworkStream).FullName);
				if (nstream == null)
					return null;
				s = nstream;
			}

			IAsyncResult result = null;
			if (!chunkedRead || (!chunkStream.DataAvailable && chunkStream.WantMore)) {
				try {
					result = s.BeginRead (buffer, offset, size, cb, state);
					cb = null;
				} catch (Exception) {
					HandleError (WebExceptionStatus.ReceiveFailure, null, "chunked BeginRead");
					throw;
				}
			}

			if (chunkedRead) {
				WebAsyncResult wr = new WebAsyncResult (cb, state, buffer, offset, size);
				wr.InnerAsyncResult = result;
				if (result == null) {
					// Will be completed from the data in ChunkStream
					wr.SetCompleted (true, (Exception) null);
					wr.DoCallback ();
				}
				return wr;
			}

			return result;
		}
예제 #55
0
		void SetWriteStreamCB2 (IAsyncResult ar)
		{
			var result = (WebAsyncResult)ar;
			if (result != null && result.GotException) {
				SetWriteStreamErrorCB (result.Exception);
				return;
			}

			if (asyncWrite != null) {
				asyncWrite.SetCompleted (false, writeStream);
				asyncWrite.DoCallback ();
				asyncWrite = null;
			}
		}
예제 #56
0
		internal void SetWriteStream (WebConnectionStream stream)
		{
			if (Aborted)
				return;
			
			writeStream = stream;
			if (bodyBuffer != null) {
				webHeaders.RemoveInternal ("Transfer-Encoding");
				contentLength = bodyBufferLength;
				writeStream.SendChunked = false;
			}

			byte[] requestHeaders = GetRequestHeaders ();
			WebAsyncResult result = new WebAsyncResult (new AsyncCallback (SetWriteStreamCB), null);
			writeStream.SetHeadersAsync (requestHeaders, result);
		}
예제 #57
0
		bool HandleNtlmAuth (WebAsyncResult r)
		{
			bool isProxy = webResponse.StatusCode == HttpStatusCode.ProxyAuthenticationRequired;
			if ((isProxy ? proxy_auth_state.NtlmAuthState : auth_state.NtlmAuthState) == NtlmAuthState.None)
				return false;

			WebConnectionStream wce = webResponse.GetResponseStream () as WebConnectionStream;
			if (wce != null) {
				WebConnection cnc = wce.Connection;
				cnc.PriorityRequest = this;
				ICredentials creds = !isProxy ? credentials : proxy.Credentials;
				if (creds != null) {
					cnc.NtlmCredential = creds.GetCredential (requestUri, "NTLM");
					cnc.UnsafeAuthenticatedConnectionSharing = unsafe_auth_blah;
				}
			}
			r.Reset ();
			finished_reading = false;
			haveResponse = false;
			webResponse.ReadAll ();
			webResponse = null;
			return true;
		}
예제 #58
0
		public override IAsyncResult BeginGetResponse (AsyncCallback callback, object state)
		{
			if (Aborted)
				throw new WebException ("The request was canceled.", WebExceptionStatus.RequestCanceled);

			if (method == null)
				throw new ProtocolViolationException ("Method is null.");

			string transferEncoding = TransferEncoding;
			if (!sendChunked && transferEncoding != null && transferEncoding.Trim () != "")
				throw new ProtocolViolationException ("SendChunked should be true.");

			Monitor.Enter (locker);
			getResponseCalled = true;
			if (asyncRead != null && !haveResponse) {
				Monitor.Exit (locker);
				throw new InvalidOperationException ("Cannot re-call start of asynchronous " +
							"method while a previous call is still in progress.");
			}

			asyncRead = new WebAsyncResult (this, callback, state);
			WebAsyncResult aread = asyncRead;
			initialMethod = method;

			aread.InnerAsyncResult = CheckIfForceWrite (GetResponseAsyncCB, aread);
			if (aread.InnerAsyncResult == null)
				GetResponseAsyncCB2 (aread);
			else
				Monitor.Exit (locker);
			return aread;
		}
예제 #59
0
		internal WebAsyncResult SetHeadersAsync (bool setInternalLength, AsyncCallback callback, object state)
		{
			if (headersSent)
				return null;

			string method = request.Method;
			bool no_writestream = (method == "GET" || method == "CONNECT" || method == "HEAD" ||
			                      method == "TRACE");
			bool webdav = (method == "PROPFIND" || method == "PROPPATCH" || method == "MKCOL" ||
			              method == "COPY" || method == "MOVE" || method == "LOCK" ||
			              method == "UNLOCK");

			if (setInternalLength && !no_writestream && writeBuffer != null)
				request.InternalContentLength = writeBuffer.Length;

			if (sendChunked || request.ContentLength > -1 || no_writestream || webdav) {
				headersSent = true;
				headers = request.GetRequestHeaders ();

				var result = new WebAsyncResult (callback, state);
				result.InnerAsyncResult = cnc.BeginWrite (request, headers, 0, headers.Length, new AsyncCallback (SetHeadersCB), result);
				if (result.InnerAsyncResult != null)
					return result;
			}

			return null;
		}