Ejemplo n.º 1
0
		public void           Initialize(Stream stream)
		{

			int         headersplit     = -1;
			Boolean     headerfound     = false;
			int        ContentLength   = -1;
			byte[]      readbytes       = null;
			List<byte>     allbytes        = new List<byte>();

			while (readbytes == null || readbytes.Length > 0)
			{
				//find the header first. Due to wacky initialization bytes are stored globally until header is found;
				readbytes = http_function.ReadFromStream(stream, _maxReadLength);

				if (headerfound == false)
				{
					allbytes.AddRange(readbytes);

					//check for header!
					headersplit = http_function.FindHeaderBodySplit(allbytes.ToArray());
					if (headersplit > 0)
					{
						//Creates the header object and writes the intital
						//bytes to body if there are any
						HandleInitialBytes(allbytes.ToArray(),headersplit);
						CreateUri();
						headerfound = true;


						//Optimizations based on header
						// I can't measure how effective they are... yet.

						//Post data is not included in a head or get request.
						//So we know we are done regaurdless of the
						//Content-Length.
						if(_header.Verb == "HEAD" || _header.Verb == "GET" || _header.Verb == "CONNECT")
							break;

						//If we have a Content-Length then we have a definate
						//place to end the read.
						if (_header.Values.ContainsKey("Content-Length"))
						{
							ContentLength = _header.ContentLength;
							if(ContentLength == 0)
								_cancel = true;
							else
								_timeOut = _timeOut * 2;
						}

						//Allow a little more time for the server to process post data
						//Might come in handy when uploading files.
						if (_header.Verb == "POST") {
							if(!_header.Values.ContainsKey("Content-Length"))
							{
								http_exception ex = new http_exception(this,"Content-Length is mandatory!",null,411);
								ex.add_header("Connection","close");
								throw ex;
							}
							_timeOut = _timeOut * 2;
						}

						//When there is a transfer-encoding there is usually no
						//Content-Length and the file size is unknown so
						//there is no exact point where we no we can end this read
						//For good measure we are giving a little more time.
						if (_header.Values.ContainsKey("Transfer-Encoding"))
							if (_header.GetValue("Transfer-Encoding").ToLower() == "chunked")
								_timeOut = _timeOut * 2;
					}
				}

				else //headerfound == false
				{
					// Make sure that bytes is not empty very important.
					if (readbytes.Length > 0)
					{
						//Writing bytes to body file!
						AppendBytesToFile(readbytes);
						// Part of a hard timeout implemented as a death counter
						// in ProxyTransaction.
						if(Activity!=null){Activity(this,new EventArgs());}
					}
				}
			}

			if (headerfound == false | _header == null)
			{
				if(allbytes.Count == 0)
				{
					throw new http_exception(this,"Zero bytes have been recieved!", null,408);
				}
				else
				{
					throw new http_exception(this,"The request/response did not seem to have the http head/body dilimeter (CRLFCRLF)", null,400);
				}
			}
		}
Ejemplo n.º 2
0
        public virtual void           Initialize(TcpClient client,Stream networkStream)
        {
            _connection                 = client;
            _neworkStream               = networkStream;
            _neworkStream.WriteTimeout  = 10000;
            _neworkStream.ReadTimeout   = 10000;

            int         headersplit     = -1;
            Boolean     headerfound     = false;
            long        ContentLength   = -1;
            int         constpasses     = 0;
            byte[]      readbytes       = null;
            List<byte>  allbytes		= new List<byte>();

            while (client.Client.Connected && !client.Client.Poll(1, SelectMode.SelectError))
            {
				if (_cancel)
					break;
                
               if (client.Available > 0)
                {
                    //find the header first. Due to wacky initialization bytes are stored globally until header is found;
                   readbytes = http_function.ReadFromStream(networkStream, _maxReadLength);

                    if (headerfound == false)
                    {
                        allbytes.AddRange(readbytes);

                        //check for header!
                        headersplit = http_function.FindHeaderBodySplit(allbytes.ToArray());
                        if (headersplit > 0)
                        {
                            //Creates the header object and writes the intital
                            //bytes to body if there are any
                            HandleInitialBytes(allbytes.ToArray(),headersplit);
							CreateUri();
                            headerfound = true;


                            //Optimizations based on header
                            // I can't measure how effective they are... yet.

                            //Post data is not included in a head or get request.
                            //So we know we are done regardless of the
                            //Content-Length.
							if(_header.Verb == "GET" || _header.Verb == "CONNECT" || _header.Verb == "HEAD" )
                                _cancel = true;

                            //If we have a Content-Length then we have a definate
                            //place to end the read.
                            if (_header.Values.ContainsKey("Content-Length"))
                            {
                                ContentLength = Convert.ToInt64(_header.Values["Content-Length"]);
                                if(ContentLength == 0)
                                    _cancel = true;
                                //_timeOut = _timeOut * 2;
                            }
                            
                            //Allow a little more time for the server to process post data
                            //Might come in handy when uploading files.
							if (_header.Verb == "POST") {
								if(!_header.Values.ContainsKey("Content-Length"))
								{
									http_exception ex = new http_exception(this,"Content-Length is mandatory!",null,411);
									ex.add_header("Connection","close");
									throw ex;
								}
								//_timeOut = _timeOut * 2;
							}

							if(!string.IsNullOrEmpty(_header.Verb) && string.IsNullOrEmpty(this.Host)) {
								throw new Exception("request requires a host!");
							}

                            //When there is a transfer-encoding there is usually no
                            //Content-Length and the file size is unknown so
                            //there is no exact point where we no we can end this read
                            //For good measure we are giving a little more time.
                            //if (_header.Values.ContainsKey("Transfer-Encoding"))
                            //    if (_header.GetValue("Transfer-Encoding").ToLower() == "chunked")
                            //        _timeOut = _timeOut * 2;
                        }
                    }
                    
                    else //headerfound == false
                    {
                        // Make sure that bytes is not empty very important.
                        if (readbytes.Length > 0)
                        {
                            //Writing bytes to body file!
                            AppendBytesToFile(readbytes);
                            // Part of a hard timeout implemented as a death counter
                            // in ProxyTransaction.
                            if(Activity!=null){Activity(this,new EventArgs());}
							constpasses = 0;

                        }
                    }
                }
                else //client.Available <= 0
                {
                   
                    if (headerfound)
                    {
                        if (ContentLength == 0 )
                        {
                            _cancel = true;

                        }
                        //There is a Content-Length and it's greater than 0 but Body.Length is
                        //less than Content-Length. Basically we are in mid-transfer
                        else if (ContentLength > 0)
                        {
                            if (Body.Length < ContentLength)
                            {
								Thread.Sleep(10);
								constpasses = constpasses + 1;
                            } 
							else if(Body.Length == ContentLength) {
								_cancel = true;
							}
                        }
                        //There is no Content-Length so we are using the timeout.
                        else if(ContentLength < 0)
                        {
							if(_header.Httpversion == "HTTP/1.0")
								_cancel = true;
							Thread.Sleep(10);
                            constpasses = constpasses + 1;
                        }
                    }
					else {
						Thread.Sleep(10);
						constpasses = constpasses +1;
					}
                    //Checking for timeout situation.
                    if (constpasses >= (_timeOut / 10))
                    {
						Exception ex = new Exception("Read Timeout!");
						_errors.Add(ex);
						//if (ReadTimeOut != null) { ReadTimeOut(this, new EventArgs()); }
						//throw ex;
                        _cancel = true;
                    }
                }
            }
			if(! headerfound && _header.Connection.ToLower() != "close")
				if(!client.Client.Connected || client.Client.Poll(1, SelectMode.SelectError))
					throw new Exception("hr: Client Disconnected!");

			if(headerfound && _header != null && _header.Verb != "HEAD" && _header.Statuscode != " 206" && _header.Values.ContainsKey("Content-Length")) {
				if(Convert.ToInt32(_body.Length) != _header.ContentLength) {
#if DEBUG
					Console.Error.WriteLine(String.Format("Entity size mismatch {0}/{1}",_header.ContentLength,_body.Length));
#endif
					_header.ContentLength = Convert.ToInt32(_body.Length);
				}
			}

            if (headerfound == false || _header == null)
            {
                if(allbytes.Count == 0)
                {
                    throw new Exception("Zero bytes have been recieved!");

                }
                else
                {
                    throw new Exception("The request/response did not seem to have the http head/body dilimeter (CRLFCRLF)");
                }
            }
        }