public async Task PutHttpResponseStream(HttpResponsePacket packet, IAsyncEnumerable <byte[]> stream) { if (packet == null) { throw new ArgumentNullException(nameof(packet)); } if (stream == null) { throw new ArgumentNullException(nameof(stream)); } var httpResponse = responseQueue[packet.Id].HttpResponse; if (packet.ContentType != null) { httpResponse.ContentType = $"{packet.ContentType.MediaType}; charset={packet.ContentType.CharSet}"; } httpResponse.StatusCode = (int)packet.StatusCode; foreach (var c in packet.Cookies.AsEnumerable()) { httpResponse.Cookies.Append(c.Name, c.Value, new Microsoft.AspNetCore.Http.CookieOptions { Domain = c.Domain, Expires = c.Expires, HttpOnly = c.HttpOnly, Path = c.Path, Secure = c.Secure }); } await foreach (var ba in stream) { await httpResponse.Body.WriteAsync(ba).ConfigureAwait(false); } responseQueue[packet.Id].Sync.Release(); }
private async Task WebRequest(HttpRequestPacket packet, TextMapCarrier _, Func <Stream, Task> WriteBody) { #endif HttpResponsePacket?response = null; var errorMessage = "Internal Server Error"; #if ZIPKIN using (tracer.StartActiveSpan("Transporter -> Server", context, SpanKind.Server, out _)) #endif { try { if (!(HttpWebRequest.Create(new Uri(Url(packet.Path), packet.QueryString)) is HttpWebRequest httpWebRequest)) { throw new Exception("Failed to create web request"); } httpWebRequest.Method = packet.Method; httpWebRequest.ContentType = packet.ContentType; httpWebRequest.KeepAlive = true; // https://stackoverflow.com/questions/734404/error-using-httpwebrequest-to-upload-files-with-put // TODO This caused a problem for UploadFile !!!! //foreach (var key in packet.Headers.Keys) //{ // httpWebRequest.Headers.Add(key, packet.Headers[key]); //} foreach (var key in packet.Headers.Keys.Intersect(new string[] { Strings.TransporterHeader, Strings.UserAgentHeader, Strings.IsWebSocketRequestHeader, Strings.SocketGuidHeader })) // TODO Others?? { httpWebRequest.Headers.Add(key, packet.Headers[key]); } // You could add authentication here as well if needed: //TODO // request.PreAuthenticate = true; // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested; // request.Headers.Add("Authorization", "Basic " + Convert.ToBase64String(System.Text.Encoding.Default.GetBytes("username" + ":" + "password"))); if (packet.BodyLength > 0) { httpWebRequest.ContentLength = packet.BodyLength; using (Stream requestStream = httpWebRequest.GetRequestStream()) { await WriteBody(requestStream).ConfigureAwait(false); } } if (packet.Headers.ContainsKey(Strings.IsWebSocketRequestHeader)) { httpWebRequest.Timeout = 60 * 50 * 1000; } // Required to accept cookies httpWebRequest.CookieContainer = new CookieContainer(); if (await httpWebRequest.GetResponseAsync().ConfigureAwait(false) is HttpWebResponse webResponse) { using (var ms = new MemoryStream()) { await webResponse.GetResponseStream().CopyToAsync(ms).ConfigureAwait(false); response = new HttpResponsePacket(id: packet.Id, content: ImmutableArray.Create <byte>(ms.ToArray()), contentLength: webResponse.ContentLength, statusCode: webResponse.StatusCode); response.Cookies.Add(webResponse.Cookies); if (!string.IsNullOrEmpty(webResponse.ContentType)) { response.ContentType = MediaTypeHeaderValue.Parse(webResponse.ContentType); } if (!string.IsNullOrEmpty(webResponse.ContentEncoding)) { response.ContentEncoding = webResponse.ContentEncoding; } } } } catch (WebException ex) { errorMessage = ex.Message; } } if (response == null) { response = new HttpResponsePacket(id: packet.Id, content: ImmutableArray.Create <byte>(Encoding.ASCII.GetBytes(errorMessage)), contentLength: errorMessage.Length, statusCode: HttpStatusCode.InternalServerError); } #if ZIPKIN using (tracer.StartActiveSpan("Server -> Transporter Response", context, SpanKind.Server, out var _)) #endif { var byteData = response.Content.ToArray(); response.Content = ImmutableArray <byte> .Empty; await connection.HubConnection.SendAsync(Strings.PutHttpResponseStream, response, ClientStreamData(byteData)).ConfigureAwait(false); } }