private TReturn Request <TReturn>(string address, string providerType, ContentType contentType, object data, bool getResponseData) { HttpWebRequest request = WebRequest.CreateHttp(address); request.Method = "POST"; switch (contentType) { case ContentType.Bytes: request.ContentType = "application/octet-stream"; break; case ContentType.Json: request.ContentType = "application/json; charset=utf-8"; break; case ContentType.JsonNameless: request.ContentType = "application/jsonnameless; charset=utf-8"; break; } request.Accept = request.ContentType; request.Timeout = Timeout.Infinite; if (!String.IsNullOrWhiteSpace(providerType)) { request.Headers.Add("Provider-Type", providerType); } CookieContainer cookieContainer = new CookieContainer(); if (cookies != null) { cookieContainer.Add(cookies); } request.CookieContainer = cookieContainer; request.SendChunked = true; using (var postStream = request.GetRequestStream()) { ContentTypeSerializer.Serialize(contentType, postStream, data); } try { var response = (HttpWebResponse)request.GetResponse(); if (getResponseData) { using (Stream stream = response.GetResponseStream()) { var result = ContentTypeSerializer.Deserialize <TReturn>(contentType, stream); return(result); } } response.Close(); response.Dispose(); } catch (WebException ex) { if (ex.Response != null) { Exception innerException; using (Stream exStream = ex.Response.GetResponseStream()) { innerException = ContentTypeSerializer.DeserializeException(contentType, exStream); } ex.Response.Close(); ex.Response.Dispose(); throw innerException; } throw; } this.cookies = GetCookiesFromContainer(cookieContainer); return(default);
protected override TReturn CallInternal <TReturn>(bool isStream, Type interfaceType, string methodName, object[] arguments) { var data = new CQRSRequestData() { ProviderType = interfaceType.Name, ProviderMethod = methodName }; data.AddProviderArguments(arguments); switch (networkType) { case NetworkType.Internal: data.AddClaims(); break; case NetworkType.Api: break; default: throw new NotImplementedException(); } var stopwatch = Stopwatch.StartNew(); var client = new TcpClient(endpoint.AddressFamily); var bufferOwner = BufferArrayPool <byte> .Rent(TcpRawCommon.BufferLength); var buffer = bufferOwner.AsMemory(); Stream stream = null; Stream requestBodyStream = null; FinalBlockStream requestBodyCryptoStream = null; Stream responseBodyStream = null; try { client.Connect(endpoint.Address, endpoint.Port); stream = client.GetStream(); //Request Header var requestHeaderLength = TcpRawCommon.BufferHeader(buffer, data.ProviderType, contentType); #if NETSTANDARD2_0 stream.Write(bufferOwner, 0, requestHeaderLength); #else stream.Write(buffer.Span.Slice(0, requestHeaderLength)); #endif requestBodyStream = new TcpRawProtocolBodyStream(stream, null, true); if (encryptionKey != null) { requestBodyCryptoStream = SymmetricEncryptor.Encrypt(encryptionAlgorithm, encryptionKey, requestBodyStream, true, true); ContentTypeSerializer.Serialize(contentType, requestBodyCryptoStream, data); requestBodyCryptoStream.FlushFinalBlock(); requestBodyCryptoStream.Dispose(); requestBodyCryptoStream = null; } else { ContentTypeSerializer.Serialize(contentType, requestBodyStream, data); requestBodyStream.Flush(); } requestBodyStream.Dispose(); requestBodyStream = null; //Response Header var headerPosition = 0; var headerLength = 0; var requestHeaderEnd = false; while (!requestHeaderEnd) { if (headerLength == buffer.Length) { throw new Exception($"{nameof(TcpRawCQRSClient)} Header Too Long"); } #if NETSTANDARD2_0 var bytesRead = stream.Read(bufferOwner, headerPosition, buffer.Length - headerPosition); #else var bytesRead = stream.Read(buffer.Span.Slice(headerPosition, buffer.Length - headerPosition)); #endif if (bytesRead == 0) { throw new EndOfStreamException(); } headerLength += bytesRead; requestHeaderEnd = TcpRawCommon.ReadToHeaderEnd(buffer, ref headerPosition, headerLength); } var responseHeader = TcpRawCommon.ReadHeader(buffer, headerPosition, headerLength); responseBodyStream = new TcpRawProtocolBodyStream(stream, responseHeader.BodyStartBuffer, false); if (encryptionKey != null) { responseBodyStream = SymmetricEncryptor.Decrypt(encryptionAlgorithm, encryptionKey, responseBodyStream, false, false); } if (responseHeader.IsError) { var responseException = ContentTypeSerializer.DeserializeException(contentType, responseBodyStream); throw responseException; } stopwatch.Stop(); _ = Log.TraceAsync($"{nameof(TcpRawCQRSClient)} Query: {interfaceType.GetNiceName()}.{data.ProviderMethod} {stopwatch.ElapsedMilliseconds}"); if (isStream) { return((TReturn)(object)responseBodyStream); //TODO better way to convert type??? } else { var model = ContentTypeSerializer.Deserialize <TReturn>(contentType, responseBodyStream); responseBodyStream.Dispose(); client.Dispose(); return(model); } } catch { try { //crypto stream can error, we want to throw the actual error if (responseBodyStream != null) { responseBodyStream.Dispose(); } } catch { } if (requestBodyStream != null) { requestBodyStream.Dispose(); } if (requestBodyCryptoStream != null) { requestBodyCryptoStream.Dispose(); } if (stream != null) { stream.Dispose(); } client.Dispose(); throw; } finally { BufferArrayPool <byte> .Return(bufferOwner); } }
protected override TReturn CallInternal <TReturn>(bool isStream, Type interfaceType, string methodName, object[] arguments) { var data = new CQRSRequestData() { ProviderType = interfaceType.Name, ProviderMethod = methodName }; data.AddProviderArguments(arguments); HttpAuthHeaders authHeaders = null; switch (networkType) { case NetworkType.Internal: data.AddClaims(); break; case NetworkType.Api: if (apiAuthorizer != null) { authHeaders = apiAuthorizer.BuildAuthHeaders(); } break; default: throw new NotImplementedException(); } var stopwatch = Stopwatch.StartNew(); var client = new TcpClient(endpoint.AddressFamily); client.NoDelay = true; var bufferOwner = BufferArrayPool <byte> .Rent(HttpCommon.BufferLength); var buffer = bufferOwner.AsMemory(); Stream stream = null; Stream requestBodyStream = null; Stream responseBodyStream = null; try { client.Connect(endpoint.Address, endpoint.Port); stream = client.GetStream(); //Request Header var requestHeaderLength = HttpCommon.BufferHeader(buffer, data.ProviderType, contentType, serviceUrl, authHeaders); #if NETSTANDARD2_0 stream.Write(bufferOwner, 0, requestHeaderLength); #else stream.Write(buffer.Span.Slice(0, requestHeaderLength)); #endif requestBodyStream = new HttpProtocolBodyStream(null, stream, null, true); ContentTypeSerializer.Serialize(contentType, requestBodyStream, data); requestBodyStream.Flush(); requestBodyStream.Dispose(); requestBodyStream = null; //Response Header var headerPosition = 0; var headerLength = 0; var headerEnd = false; while (!headerEnd) { if (headerLength == buffer.Length) { throw new Exception($"{nameof(HttpCQRSClient)} Header Too Long"); } #if NETSTANDARD2_0 var bytesRead = stream.Read(bufferOwner, headerPosition, buffer.Length - headerPosition); #else var bytesRead = stream.Read(buffer.Span.Slice(headerPosition, buffer.Length - headerPosition)); #endif if (bytesRead == 0) { throw new EndOfStreamException(); } headerLength += bytesRead; headerEnd = HttpCommon.ReadToHeaderEnd(buffer, ref headerPosition, headerLength); } var responseHeader = HttpCommon.ReadHeader(buffer, headerPosition, headerLength); //Response Body responseBodyStream = new HttpProtocolBodyStream(null, stream, responseHeader.BodyStartBuffer, false); if (responseHeader.IsError) { var responseException = ContentTypeSerializer.DeserializeException(contentType, responseBodyStream); throw responseException; } stopwatch.Stop(); _ = Log.TraceAsync($"{nameof(HttpCQRSClient)} Query: {interfaceType.GetNiceName()}.{data.ProviderMethod} {stopwatch.ElapsedMilliseconds}"); if (isStream) { return((TReturn)(object)responseBodyStream); } else { var model = ContentTypeSerializer.Deserialize <TReturn>(contentType, responseBodyStream); responseBodyStream.Dispose(); client.Dispose(); return(model); } } catch { if (responseBodyStream != null) { responseBodyStream.Dispose(); } if (requestBodyStream != null) { requestBodyStream.Dispose(); } if (stream != null) { stream.Dispose(); } client.Dispose(); throw; } finally { BufferArrayPool <byte> .Return(bufferOwner); } }