public async Task CompareExample() { var mw = new MultipartWriter("mixed", "61cfbe41-7ea6-4771-b1c5-b43564208ee5"); mw.Add(new HttpApplicationMultipart(CreateFirstResponse())); mw.Add(new HttpApplicationMultipart(CreateSecondResponse())); mw.Add(new HttpApplicationMultipart(CreateThirdResponse())); mw.Add(new HttpApplicationMultipart(CreateFourthResponse())); string output; using (var memoryStream = new MemoryStream()) { await mw.CopyToAsync(memoryStream).ConfigureAwait(false); memoryStream.Position = 0; output = Encoding.ASCII.GetString(memoryStream.ToArray()); } string input; using (var refTextStream = TestUtilities.GetNormalizedContentStream("MultipartResponse.txt")) { Assert.NotNull(refTextStream); input = await refTextStream.ReadAsStringAsync().ConfigureAwait(false); } Assert.Equal(input, output); }
public async Task WriteMultipart() { using (var writer = new MultipartWriter("mixed", Boundary)) { var headerDictionary = new HeaderDictionary { { "Content-Type", "application/json; charset=utf-8" } }; for (int i = 0; i < 1000; i++) { writer.Add(new HttpApplicationMultipart("2.0", 200, "Ok", new MemoryStream(Encoding.UTF8.GetBytes(i.ToString())), headerDictionary)); } await writer.CopyToAsync(Stream.Null, CancellationToken.None); } }
private async Task InvokeBatchAsync(HttpContext httpContext) { if (!httpContext.Request.IsMultiPartBatchRequest()) { httpContext.Response.StatusCode = StatusCodes.Status400BadRequest; await httpContext.Response.WriteAsync("Invalid Content-Type.").ConfigureAwait(false); return; } var boundary = httpContext.Request.GetMultipartBoundary(); if (string.IsNullOrEmpty(boundary)) { httpContext.Response.StatusCode = StatusCodes.Status400BadRequest; await httpContext.Response.WriteAsync("Invalid boundary in Content-Type.").ConfigureAwait(false); return; } var startContext = new BatchStartContext { Request = httpContext.Request }; var cancellationToken = httpContext.RequestAborted; await _options.Events.BatchStartAsync(startContext, cancellationToken).ConfigureAwait(false); Exception exception = null; var abort = false; var reader = new MultipartReader(boundary, httpContext.Request.Body); // PathString.StartsWithSegments that we use requires the base path to not end in a slash. var pathBase = httpContext.Request.PathBase; if (pathBase.HasValue && pathBase.Value.EndsWith("/")) { pathBase = new PathString(pathBase.Value.Substring(0, pathBase.Value.Length - 1)); } using (var writer = new MultipartWriter("batch", Guid.NewGuid().ToString())) { try { HttpApplicationRequestSection section; while ((section = await reader .ReadNextHttpApplicationRequestSectionAsync(pathBase, cancellationToken) .ConfigureAwait(false)) != null) { httpContext.RequestAborted.ThrowIfCancellationRequested(); var preparationContext = new BatchRequestPreparationContext { RequestFeature = section.RequestFeature, Features = CreateDefaultFeatures(httpContext.Features), State = startContext.State }; await _options.Events.BatchRequestPreparationAsync(preparationContext, cancellationToken) .ConfigureAwait(false); using (var state = new RequestState(section.RequestFeature, _factory, preparationContext.Features)) { using (httpContext.RequestAborted.Register(state.AbortRequest)) { var executedContext = new BatchRequestExecutedContext { Request = state.Context.Request, State = startContext.State }; try { var executingContext = new BatchRequestExecutingContext { Request = state.Context.Request, State = startContext.State }; await _options.Events .BatchRequestExecutingAsync(executingContext, cancellationToken) .ConfigureAwait(false); await _next.Invoke(state.Context).ConfigureAwait(false); var response = await state.ResponseTaskAsync().ConfigureAwait(false); executedContext.Response = state.Context.Response; writer.Add(new HttpApplicationMultipart(response)); } catch (Exception ex) { state.Abort(ex); executedContext.Exception = ex; } finally { await _options.Events.BatchRequestExecutedAsync(executedContext, cancellationToken) .ConfigureAwait(false); abort = executedContext.Abort; } if (abort) { break; } } } } } catch (Exception ex) { exception = ex; } finally { var endContext = new BatchEndContext { Exception = exception, State = startContext.State, IsAborted = abort, Response = httpContext.Response }; if (endContext.Exception != null) { endContext.Response.StatusCode = StatusCodes.Status500InternalServerError; } await _options.Events.BatchEndAsync(endContext, cancellationToken).ConfigureAwait(false); if (!endContext.IsHandled) { httpContext.Response.Headers.Add(HeaderNames.ContentType, writer.ContentType); await writer.CopyToAsync(httpContext.Response.Body, cancellationToken).ConfigureAwait(false); } } } }