Пример #1
0
 private static void WriteResponse(HTTPResponse Response)
 {
     Console.ForegroundColor = ConsoleColor.Blue;
     Console.WriteLine("Response:");
     Console.WriteLine(Response.RawHTTPHeader + Environment.NewLine);
     Console.ForegroundColor = ConsoleColor.Gray;
     Console.WriteLine(Response.Content.ToUTF8String() + Environment.NewLine);
 }
Пример #2
0
        public Task<HTTPClient> Execute(HTTPRequestBuilder HTTPRequest, Action<HTTPResponse> HTTPResponseDelegate)
        {
            return Task<HTTPClient>.Factory.StartNew(() =>
            {

                #region Data

                Boolean _EndOfHTTPHeader    = false;
                long    _Length             = 0;
                long    EndOfHeaderPosition = 6;

                #endregion

                #region Client initialisieren und mit dem Server verbinden

                // Init TcpClient
                if (TCPClient == null)
                    TCPClient = new TcpClient(this.RemoteIPAddress.ToString(), this.RemotePort.ToInt32());
                    //TCPClient.ReceiveTimeout = 5000;

                // Open stream for reading and writting
                if (TCPStream == null)
                    TCPStream = TCPClient.GetStream();

                #endregion

                #region Send Request

                var _RequestBytes = (HTTPRequest.EntireRequestHeader + Environment.NewLine + Environment.NewLine).ToUTF8Bytes();
                TCPStream.Write(_RequestBytes, 0, _RequestBytes.Length);

                var _MemoryStream = new MemoryStream();
                var _Buffer       = new Byte[65535];
                var sw            = new Stopwatch();

                #endregion

                #region Wait for the server to react!

                sw.Start();

                while (!TCPStream.DataAvailable || sw.ElapsedMilliseconds > 20000)
                    Thread.Sleep(1);

                if (!TCPStream.DataAvailable && sw.ElapsedMilliseconds > 20000)
                {
                    TCPClient.Close();
                    throw new ApplicationException("Could not read from the TCP stream!");
                }

                sw.Stop();

                #endregion

                #region Read

                TCPStream.ReadTimeout = 2;

                while (!_EndOfHTTPHeader || TCPStream.DataAvailable || !TCPClient.Connected)
                {

                    #region Read the entire stream into the memory <= Rethink this someday!

                    while (TCPStream.DataAvailable)
                        _MemoryStream.Write(_Buffer, 0, TCPStream.Read(_Buffer, 0, _Buffer.Length));

                    #endregion

                    #region Walk through the stream and search for two consecutive newlines indicating the end of the HTTP header

                    _Length = _MemoryStream.Length;

                    if (_Length > 4)
                    {

                        _MemoryStream.Seek(0, SeekOrigin.Begin);

                        int state = 0;
                        int _int  = 0;
                        _EndOfHTTPHeader = false;

                        while (!_EndOfHTTPHeader || _int == -1)
                        {

                            _int = _MemoryStream.ReadByte();

                            switch (state)
                            {
                                case 0 : if (_int == 0x0d) state = 1; else state = 0; break;
                                case 1 : if (_int == 0x0a) state = 2; else state = 0; break;
                                case 2 : if (_int == 0x0d) state = 3; else state = 0; break;
                                case 3 : if (_int == 0x0a) _EndOfHTTPHeader = true; else state = 0; break;
                                default : state = 0; break;
                            }

                        }

                        if (_EndOfHTTPHeader)
                            break;

                    }

                    #endregion

                }

                if (_EndOfHTTPHeader == false)
                    throw new ApplicationException("Could not find the end of the HTTP protocol header!");

                EndOfHeaderPosition = _MemoryStream.Position - 3;

                #endregion

                #region Copy HTTP header data

                var HeaderBytes = new Byte[EndOfHeaderPosition - 1];
                _MemoryStream.Seek(0, SeekOrigin.Begin);
                _MemoryStream.Read(HeaderBytes, 0, HeaderBytes.Length);

                #endregion

                var _HTTPResponse = new HTTPResponse(HeaderBytes.ToUTF8String());

                #region Read 'Content-Length' bytes...

                // Copy only the number of bytes given within
                // the HTTP header element 'Content-Length'!
                if (_HTTPResponse.ContentLength.HasValue)
                {

                    _MemoryStream.Seek(4, SeekOrigin.Current);
                    var _Read        = _MemoryStream.Read(_Buffer, 0, _Buffer.Length);
                    var _StillToRead = (Int32) _HTTPResponse.ContentLength.Value - _Read;
                    _HTTPResponse.ContentStream.Write(_Buffer, 0, _Read);
                    var _CurrentBufferSize = 0;

                    var Retries = 0;

                    while (Retries < 10)
                    {

                        while (TCPStream.DataAvailable)
                        {
                            _CurrentBufferSize = Math.Min(_Buffer.Length, (Int32) _StillToRead);
                            _Read              = TCPStream.Read(_Buffer, 0, _CurrentBufferSize);
                            _HTTPResponse.ContentStream.Write(_Buffer, 0, _Read);
                            _StillToRead -= _Read;
                            Retries = 0;
                        }

                        if (_StillToRead <= 0)
                            break;

                        Thread.Sleep(10);
                        Retries++;

                    }

                    _HTTPResponse.ContentStreamToArray();

                }

                #endregion

                #region ...or read till timeout!

                else
                {

                    _MemoryStream.Seek(4, SeekOrigin.Current);
                    _HTTPResponse.ContentStream.Write(_Buffer, 0, _MemoryStream.Read(_Buffer, 0, _Buffer.Length));

                    var Retries = 0;

                    while (Retries < 10)
                    {

                        while (TCPStream.DataAvailable)
                        {
                            _HTTPResponse.ContentStream.Write(_Buffer, 0, TCPStream.Read(_Buffer, 0, _Buffer.Length));
                            Retries = 0;
                        }

                        Thread.Sleep(10);
                        Retries++;

                    }

                    _HTTPResponse.ContentStreamToArray();

                }

                #endregion

                #region Close connection if requested!

                if (_HTTPResponse.Connection == "close")
                {
                    TCPClient.Close();
                    TCPClient = null;
                    TCPStream = null;
                }

                #endregion

                #region Call HTTPResponse delegates

                if (HTTPResponseDelegate != null)
                    HTTPResponseDelegate(_HTTPResponse);

                #endregion

                return this;

            }, TaskCreationOptions.AttachedToParent);
        }