public override async Task <bool> ProcessSharkData(BlockData block) { if (block.Type == BlockType.CONNECTED) { if (_request.IsConnect) { var resp = new HttpProxyResponse { Status = HttpProxyStatus.CONNECTION_ESTABLISHED }; var respData = Encoding.ASCII.GetBytes(resp.ToString()); await WriteAsync(respData); await FlushAsync(); } else { var headerBlock = new BlockData() { Id = Id, BlockNumber = 0, Type = BlockType.DATA }; headerBlock.Data = _request.GenerateHttpHeader(); Shark.EncryptBlock(ref headerBlock); await Shark.WriteBlock(headerBlock); } Logger.LogInformation($"{_request.HostData} connected, {Id}"); #pragma warning disable CS4014 ProcessData(_request.IsConnect ? 0 : 1); #pragma warning restore CS4014 } else if (block.Type == BlockType.CONNECT_FAILED) { var resp = new HttpProxyResponse { Status = HttpProxyStatus.BAD_GATEWAY }; var respData = Encoding.ASCII.GetBytes(resp.ToString()); await WriteAsync(respData); await FlushAsync(); _pipe.Reader.Complete(); Logger.LogWarning($"Connect to {_request.HostData} failed, {Id}"); return(false); } else if (block.Type == BlockType.DATA) { await WriteAsync(block.Data); await FlushAsync(); } return(!_httpFailed); }
private async Task <HostData> ProcessRequest() { var resp = new HttpProxyResponse(); var reader = _pipe.Reader; var valid = false; var firstLineDone = false; var noValidData = false; var headerParsed = false; ReadResult result; while (true) { result = await reader.ReadAsync(); var buffer = result.Buffer; var position = buffer.PositionOf((byte)'\n'); // check first char valid if (!firstLineDone && buffer.Length > 0) { var start = buffer.Start; if (buffer.TryGet(ref start, out ReadOnlyMemory <byte> mem, false)) { var first = mem.Span[0]; if (first < 'A' || first > 'Z') { break; } } } while (position != null) { var line = Encoding.UTF8.GetString(buffer.Slice(0, position.Value).ToArray()).Replace("\r", ""); buffer = buffer.Slice(buffer.GetPosition(1, position.Value)); if (!firstLineDone) { valid = _request.ParseFirstLine(line); firstLineDone = true; } else if (valid) { if (string.IsNullOrEmpty(line)) { headerParsed = true; break; } _request.ParseHeader(line); } position = buffer.PositionOf((byte)'\n'); } reader.AdvanceTo(buffer.Start); if (headerParsed) { break; } if (result.IsCompleted) { noValidData = true; break; } } if (valid && !noValidData) { Logger.LogInformation($"Connecting to {_request.HostData}, {Id}"); return(_request.HostData); } else if (noValidData) { resp.Status = HttpProxyStatus.BAD_GATEWAY; var respData = Encoding.ASCII.GetBytes(resp.ToString()); await WriteAsync(respData); await FlushAsync(); reader.Complete(); throw new InvalidOperationException("Http proxy failed, data ended"); } else { resp.Status = HttpProxyStatus.NOT_IMPLEMENTED; var respData = Encoding.ASCII.GetBytes(resp.ToString()); await WriteAsync(respData); await FlushAsync(); reader.Complete(); throw new InvalidOperationException("Http proxy failed, not supported"); } }