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);
        }
Example #2
0
 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);
     }
 }
Example #3
0
        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);
                    }
                }
            }
        }