/// <summary> /// Extends <see cref="HttpClient"/> by adding a method that can serialize and /// transmit a <b>cadence-proxy</b> proxy request message. /// </summary> /// <typeparam name="TRequest">The request message type.</typeparam> /// <param name="client">The HTTP client.</param> /// <param name="request">The message to be sent.</param> /// <returns>The <see cref="HttpResponse"/>.</returns> public async static Task <HttpResponseMessage> SendRequestAsync <TRequest>(this HttpClient client, TRequest request) where TRequest : ProxyRequest { Covenant.Requires <ArgumentNullException>(request != null); if (client == null) { throw new TaskCanceledException(); } var stream = request.SerializeAsStream(); try { var content = new StreamContent(stream); content.Headers.ContentType = new MediaTypeHeaderValue(ProxyMessage.ContentType); var httpRequest = new HttpRequestMessage(HttpMethod.Put, "/") { Content = content }; return(await client.SendAsync(httpRequest)); } finally { MemoryStreamPool.Free(stream); } }
/// <summary> /// <para> /// Extends <see cref="HttpClient"/> by adding a method that can serialize and /// transmit a <b>cadence-proxy</b> reply to a proxy request message. /// </para> /// <note> /// This method ensures that the reply message's <see cref="ProxyReply.RequestId"/> /// matches the request's <see cref="ProxyRequest.RequestId"/> before sending the /// reply. /// </note> /// </summary> /// <typeparam name="TRequest">The request message type.</typeparam> /// <typeparam name="TReply">The reply message type.</typeparam> /// <param name="client">The HTTP client.</param> /// <param name="request">The request being responsed to.</param> /// <param name="reply">The reply message.</param> /// <returns>The <see cref="HttpResponse"/>.</returns> public async static Task <HttpResponseMessage> SendReplyAsync <TRequest, TReply>(this HttpClient client, TRequest request, TReply reply) where TRequest : ProxyRequest where TReply : ProxyReply { Covenant.Requires <ArgumentNullException>(request != null); Covenant.Requires <ArgumentNullException>(reply != null); Covenant.Requires <ArgumentException>(reply.Type == request.ReplyType, $"Reply message type [{reply.Type}] is not a suitable response for a [{request.Type}] request."); reply.RequestId = request.RequestId; var stream = reply.SerializeAsStream(); try { var content = new StreamContent(stream); content.Headers.ContentType = new MediaTypeHeaderValue(ProxyMessage.ContentType); var httpRequest = new HttpRequestMessage(HttpMethod.Put, "/") { Content = content }; return(await client.SendAsync(httpRequest)); } finally { MemoryStreamPool.Free(stream); } }
/// <summary> /// Handles requests to the test <b>"/echo"</b> endpoint path. /// </summary> /// <param name="context">The request context.</param> /// <returns>The tracking <see cref="Task"/>.</returns> private async Task OnEchoRequestAsync(HttpContext context) { var request = context.Request; var response = context.Response; var requestMessage = ProxyMessage.Deserialize <ProxyMessage>(request.Body); var clonedMessage = requestMessage.Clone(); response.ContentType = ProxyMessage.ContentType; var stream = clonedMessage.SerializeAsStream(); try { await stream.CopyToAsync(response.Body); } finally { MemoryStreamPool.Free(stream); } }