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); } } }
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)"); } } }