/// <summary> /// Run the end point /// </summary> /// <param name="adapter">The data adapter</param> public sealed override void Run(IDataAdapter adapter) { DataReader reader = new DataReader(new DataAdapterToStream(adapter)); while (true) { HttpRequestHeader request = HttpParser.ReadRequestHeader(reader, false, Logger); HttpRequestDataChunk req = request.ReadRequest(); Dictionary <string, string> headers = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); foreach (HttpHeader pair in req.Headers) { headers[pair.Name] = pair.Value; } HttpServerResponseData data = HandleRequest(req.Method, req.Path, req.Body, headers, req.Version, Logger); HttpResponseDataChunk response = new HttpResponseDataChunk(); response.Version = request.Version; response.ResponseCode = data.ResponseCode; response.Message = data.Message; List <HttpHeader> newHeaders = new List <HttpHeader>(); foreach (KeyValuePair <string, string> pair in data.Headers) { newHeaders.Add(new HttpHeader(pair.Key, pair.Value)); } if (!data.Headers.ContainsKey("content-length")) { newHeaders.Add(new HttpHeader("Content-Length", data.Body.Length.ToString())); } response.Headers = newHeaders.ToArray(); response.FinalChunk = true; if (request.Method.Equals("HEAD", StringComparison.OrdinalIgnoreCase)) { response.Body = new byte[0]; response.HeadResponse = true; } else { response.Body = data.Body; } adapter.Write(response.ToDataFrame()); if (data.CloseAfterSending || request.Version.IsVersionUnknown || request.Version.IsVersion10) { break; } } }
public override DataFrame Read() { try { if (_request == null) { _request = HttpParser.ReadRequestHeader(new DataReader(_stm), false, _logger); lock (_requestQueue) { _requestQueue.Enqueue(_request); } ProcessProxyRequestHeaders(_request); } if (_chunks == null) { _chunks = _request.ReadChunks(_config).GetEnumerator(); // If we can't move to the first chunk (headers) there is a serious issue if (!_chunks.MoveNext()) { throw new EndOfStreamException(); } } HttpRequestDataChunk chunk = _chunks.Current; if (!_chunks.MoveNext()) { _request = null; _chunks = null; } DataKey root = new DataKey("Root"); root.AddValue(new DynamicDataValue(DATA_NAME, chunk)); return(new DataFrame(root)); } catch (EndOfStreamException) { return(null); } }
public override void Write(DataFrame frame) { if (!_isTransparent) { DataKey rootKey = frame.Root; if (rootKey.Class == typeof(HttpRequestDataChunk).GUID) { HttpRequestDataChunk chunk = ObjectConverter.FromNode <HttpRequestDataChunk>(rootKey); // Enqueue the first chunk as a request if (chunk.ChunkNumber == 0) { lock (_requests) { _requests.Enqueue(chunk.ToHeader()); } } _adapter.Write(frame); } else { // If we can't use pre-parsed then queue the data up byte[] data = frame.ToArray(); lock (_requestStream) { _requestStream.Position = _requestStream.Length; _requestStream.Write(data, 0, data.Length); } _adapter.Write(frame); } } else { // In transparent mode just pass along _adapter.Write(frame); } }
public override DataFrame Read() { try { if (_request == null) { _request = HttpParser.ReadRequestHeader(new DataReader(_stm), false, _logger); } if (_chunks == null) { _chunks = _request.ReadChunks(_config).GetEnumerator(); // If we can't move to the first chunk (headers) there is a serious issue if (!_chunks.MoveNext()) { throw new EndOfStreamException(); } } HttpRequestDataChunk chunk = _chunks.Current; if (!_chunks.MoveNext()) { _request = null; _chunks = null; } MemoryStream stm = new MemoryStream(); DataWriter writer = new DataWriter(stm); chunk.WriteChunk(writer); return(new DataFrame(stm.ToArray())); } catch (EndOfStreamException) { return(null); } }
public override void Write(DataFrame frame) { Uri currUri = null; HttpRequestDataChunk chunk = frame.Root.GetValue(DATA_NAME).Value; if (chunk.ChunkNumber == 0) { int error = 0; string message = null; if (_currOutConn == null) { try { _logger.LogVerbose("Received new connection to {0}", chunk.Path); currUri = new Uri(chunk.Path, UriKind.Absolute); chunk.Path = currUri.PathAndQuery; // Upgrade to at least version 1.0 if (chunk.Version.IsVersionUnknown) { chunk.Version = HttpVersion.Version10; } // Add a Connection: close header? _currOutConn = new ProxyConnection(); _currOutConn.DataAdapter = new HttpProxyDataAdapter(currUri, _cancellationSource.Token); _currOutConn.Graph = ConnectClient(_currOutConn.DataAdapter); if (_currOutConn.Graph == null) { _currOutConn.DataAdapter.Close(); error = 404; message = "Not Found"; _currOutConn = null; } else { _currOutConn.ResponseReader = GetResponse(_currOutConn, currUri, chunk.Method.Equals("HEAD", StringComparison.OrdinalIgnoreCase)); _conns.Enqueue(_currOutConn); } } catch (UriFormatException) { error = 400; message = "Bad Request"; } if (error != 0) { ProxyConnection conn = new ProxyConnection(); conn.ResponseReader = new[] { BuildError(error, message, chunk.Method, chunk.Version) }; _conns.Enqueue(conn); } } } if (_currOutConn != null) { DataWriter writer = new DataWriter(new DataAdapterToStream(_currOutConn.DataAdapter.Coupling)); chunk.WriteChunk(writer); if (chunk.FinalChunk) { _currOutConn = null; } } else { // Do nothing } }