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);
        }
예제 #2
0
        private MultipartWriter GetMultipartWriter(RevisionInternal rev, string boundary)
        {
            // Find all the attachments with "follows" instead of a body, and put 'em in a multipart stream.
            // It's important to scan the _attachments entries in the same order in which they will appear
            // in the JSON, because CouchDB expects the MIME bodies to appear in that same order
            var bodyStream  = default(MultipartWriter);
            var attachments = rev.GetAttachments();

            foreach (var a in attachments)
            {
                var attachment = a.Value.AsDictionary <string, object>();
                if (attachment != null && attachment.GetCast <bool>("follows"))
                {
                    if (bodyStream == null)
                    {
                        // Create the HTTP multipart stream:
                        bodyStream = new MultipartWriter("multipart/related", boundary);
                        bodyStream.SetNextPartHeaders(new Dictionary <string, string> {
                            { "Content-Type", "application/json" }
                        });

                        // Use canonical JSON encoder so that _attachments keys will be written in the
                        // same order that this for loop is processing the attachments.
                        var json = Manager.GetObjectMapper().WriteValueAsBytes(rev.GetProperties(), true);
                        if (CanSendCompressedRequests)
                        {
                            bodyStream.AddGZippedData(json);
                        }
                        else
                        {
                            bodyStream.AddData(json);
                        }
                    }

                    // Add attachment as another MIME part:
                    var disposition     = String.Format("attachment; filename={0}", Misc.QuoteString(a.Key));
                    var contentType     = attachment.GetCast <string>("type");
                    var contentEncoding = attachment.GetCast <string>("encoding");
                    bodyStream.SetNextPartHeaders(new NonNullDictionary <string, string> {
                        { "Content-Disposition", disposition },
                        { "Content-Type", contentType },
                        { "Content-Encoding", contentEncoding }
                    });

                    var attachmentObj = default(AttachmentInternal);
                    try {
                        attachmentObj = LocalDatabase.AttachmentForDict(attachment, a.Key);
                    } catch (CouchbaseLiteException) {
                        return(null);
                    }

                    bodyStream.AddStream(attachmentObj.ContentStream, attachmentObj.Length);
                }
            }

            return(bodyStream);
        }
예제 #3
0
        public CompareFaceResult CompareFaceByFile(string image1Path, string image2Path)
        {
            string          uri       = string.Format(FrsConstantV2.FACE_COMPARE_URI, this.projectId);
            MultipartWriter multipart = new MultipartWriter();

            multipart.WriteStart();
            multipart.WriteFile("image1_file", image1Path, image1Path);
            multipart.WriteFile("image2_file", image2Path, image2Path);
            byte[]          data     = multipart.WriteClose();
            HttpWebResponse response = this.accessService.Post(uri, null, data, multipart.GetContentType());

            return(HttpUtils.ResponseToObj <CompareFaceResult>(response));
        }
예제 #4
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);
     }
 }
예제 #5
0
        //File
        public DetectFaceResult DetectFaceByFile(string imagePath, string attributes)
        {
            string          uri       = string.Format(FrsConstant.FACE_DETECT_URI, this.projectId);
            MultipartWriter multipart = new MultipartWriter();

            multipart.WriteStart();
            multipart.WriteFile("image_file", imagePath, imagePath);
            if (null != attributes)
            {
                multipart.WriteProperty("attributes", attributes);
            }
            byte[]          data     = multipart.WriteClose();
            HttpWebResponse response = this.accessService.Post(uri, null, data, multipart.GetContentType());

            return(HttpUtils.ResponseToObj <DetectFaceResult>(response));
        }
        private static MultipartWriter MultipartWriterForRev(Database db, RevisionInternal rev, string contentType)
        {
            var writer = new MultipartWriter(contentType, null);

            writer.SetNextPartHeaders(new Dictionary <string, string> {
                { "Content-Type", "application/json" }
            });
            writer.AddData(rev.GetBody().AsJson());
            var attachments = rev.GetAttachments();

            if (attachments == null)
            {
                return(writer);
            }

            foreach (var entry in attachments)
            {
                var attachment = entry.Value.AsDictionary <string, object>();
                if (attachment != null && attachment.GetCast <bool>("follows", false))
                {
                    var disposition = String.Format("attachment; filename={0}", Database.Quote(entry.Key));
                    writer.SetNextPartHeaders(new Dictionary <string, string> {
                        { "Content-Disposition", disposition }
                    });

                    var attachObj = default(AttachmentInternal);
                    try {
                        attachObj = db.AttachmentForDict(attachment, entry.Key);
                    } catch (CouchbaseLiteException) {
                        return(null);
                    }

                    var fileURL = attachObj.ContentUrl;
                    if (fileURL != null)
                    {
                        writer.AddFileUrl(fileURL);
                    }
                    else
                    {
                        writer.AddStream(attachObj.ContentStream);
                    }
                }
            }

            return(writer);
        }
예제 #7
0
        public void TestMultipartWriterGzipped()
        {
            var mp    = new MultipartWriter("foo/bar", "BOUNDARY");
            var data1 = Enumerable.Repeat((byte)'*', 100);

            mp.SetNextPartHeaders(new Dictionary <string, string> {
                { "Content-Type", "star-bellies" }
            });
            mp.AddGZippedData(data1);
            var output = mp.AllOutput();

            // Compression flags & OS type will differ depending on which platform this test is run on
            // So we need to compare for "almost" equality.  In this particular output the compression
            // flags are on byte 97 and the os type is in byte 98
            var expectedOutput = GetType().GetResourceAsStream("MultipartStars.mime").ReadAllBytes();

            Assert.AreEqual(expectedOutput.Take(96), output.Take(96));
            Assert.AreEqual(expectedOutput.Skip(98), output.Skip(98));
        }
        public LiveDetectResult LiveDetectByFile(string videoPath, string actions, string actionTime)
        {
            string          uri       = string.Format(FrsConstant.LIVE_DETECT_URI, this.projectId);
            MultipartWriter multipart = new MultipartWriter();

            multipart.WriteStart();
            multipart.WriteFile("video_file", "video_file", videoPath);
            if (null != actions)
            {
                multipart.WriteProperty("actions", actions);
            }
            if (null != actionTime)
            {
                multipart.WriteProperty("action_time", actionTime);
            }
            byte[]          data     = multipart.WriteClose();
            HttpWebResponse response = this.accessService.Post(uri, null, data, multipart.GetContentType());

            return(HttpUtils.ResponseToObj <LiveDetectResult>(response));
        }
예제 #9
0
        //FILE
        public AddFaceResult AddFaceByFile(string faceSetName, string externalImageId, string imagePath, AddExternalFields addExternalFields)
        {
            string          uri       = string.Format(FrsConstantV2.FACE_ADD_URI, this.projectId, faceSetName);
            MultipartWriter multipart = new MultipartWriter();

            multipart.WriteStart();
            multipart.WriteFile("image_file", imagePath, imagePath);
            if (null != externalImageId)
            {
                multipart.WriteProperty("external_image_id", externalImageId);
            }
            if (null != addExternalFields)
            {
                multipart.WriteProperty("external_fields", addExternalFields.GetString());
            }
            byte[]          data     = multipart.WriteClose();
            HttpWebResponse response = this.accessService.Post(uri, null, data, multipart.GetContentType());

            return(HttpUtils.ResponseToObj <AddFaceResult>(response));
        }
예제 #10
0
        public SearchFaceResult SearchFaceByFile(string faceSetName, string imagePath, int topN, double threshold,
                                                 SearchSort searchSort, SearchReturnFields searchReturnFields, string filter)
        {
            string          uri       = string.Format(FrsConstantV2.FACE_SEARCH_URI, this.projectId, faceSetName);
            MultipartWriter multipart = new MultipartWriter();

            multipart.WriteStart();
            multipart.WriteFile("image_file", imagePath, imagePath);
            //top n
            if (-1 != topN)
            {
                multipart.WriteProperty("top_n", topN.ToString());
            }
            //threshold
            if (Math.Abs(threshold) > 0)
            {
                multipart.WriteProperty("threshold", threshold.ToString());
            }
            //search sort
            if (null != searchSort)
            {
                multipart.WriteProperty("sort", searchSort.GetString());
            }
            //return fields
            if (null != searchReturnFields)
            {
                multipart.WriteProperty("return_fields", searchReturnFields.GetString());
            }
            //filter
            if (null != filter)
            {
                multipart.WriteProperty("filter", filter);
            }
            byte[]          data     = multipart.WriteClose();
            HttpWebResponse response = this.accessService.Post(uri, null, data, multipart.GetContentType());

            return(HttpUtils.ResponseToObj <SearchFaceResult>(response));
        }
예제 #11
0
        public void TestMultipartWriter()
        {
            const string expectedOutput = "\r\n--BOUNDARY\r\nContent-Length: 16\r\n\r\n<part the first>\r\n--BOUNDARY\r\nContent-Length: " +
                                          "10\r\nContent-Type: something\r\n\r\n<2nd part>\r\n--BOUNDARY--";

            for (var bufSize = 1; bufSize < expectedOutput.Length - 1; ++bufSize)
            {
                var mp = new MultipartWriter("foo/bar", "BOUNDARY");
                Assert.AreEqual("foo/bar; boundary=\"BOUNDARY\"", mp.ContentType);
                Assert.AreEqual("BOUNDARY", mp.Boundary);
                mp.AddData(Encoding.UTF8.GetBytes("<part the first>"));
                mp.SetNextPartHeaders(new Dictionary <string, string> {
                    { "Content-Type", "something" }
                });
                mp.AddData(Encoding.UTF8.GetBytes("<2nd part>"));
                Assert.AreEqual(expectedOutput.Length, mp.Length);

                var output = mp.AllOutput();
                Assert.IsNotNull(output);
                Assert.AreEqual(expectedOutput, Encoding.UTF8.GetString(output.ToArray()));
                mp.Close();
            }
        }
예제 #12
0
        /// <summary>
        /// Creates and sets a multipart writer given the list of data to send
        /// </summary>
        /// <param name="parts">The list of data to transmit</param>
        /// <param name="type">The base type of the multipart writer</param>
        public void SetMultipartBody(IList <object> parts, string type)
        {
            var    mp = new MultipartWriter(type, null);
            object nextPart;

            foreach (var part in parts)
            {
                if (!(part is IEnumerable <byte>))
                {
                    nextPart = Manager.GetObjectMapper().WriteValueAsBytes(part);
                    mp.SetNextPartHeaders(new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    });
                }
                else
                {
                    nextPart = part;
                }

                mp.AddData((IEnumerable <byte>)nextPart);
            }

            MultipartWriter = mp;
        }
 void GivenAMultipartWriter(string boundary, Encoding encoding)
 {
     WriterStream = new MemoryStream();
     Writer       = new MultipartWriter(boundary, WriterStream, encoding);
 }
예제 #14
0
        /// <summary>
        /// Writes the response in one-step, and then closes the response stream
        /// </summary>
        /// <returns><c>true</c>, if written successfully, <c>false</c> otherwise.</returns>
        public bool WriteToContext()
        {
            bool syncWrite = true;

            if (_requestMethod != "HEAD")
            {
                if (JsonBody != null)
                {
                    if (!Chunked && !Headers.ContainsKey("Content-Type"))
                    {
                        var accept = _requestHeaders["Accept"];
                        if (accept != null)
                        {
                            if (accept.Contains("*/*") || accept.Contains("application/json"))
                            {
                                _responseWriter.AddHeader("Content-Type", "application/json");
                            }
                            else if (accept.Contains("text/plain"))
                            {
                                _responseWriter.AddHeader("Content-Type", "text/plain; charset=utf-8");
                            }
                            else
                            {
                                Reset();
                                _responseWriter.AddHeader("Content-Type", "application/json");
                                InternalStatus = StatusCode.NotAcceptable;
                            }
                        }
                    }

                    var json = default(byte[]);
                    try {
                        json = JsonBody.AsJson().ToArray();
                    } catch (Exception e) {
                        Log.To.Router.E(TAG, "Invalid body on response", e);
                        json = null;
                    }

                    if (!Chunked)
                    {
                        _responseWriter.ContentEncoding = Encoding.UTF8;
                        _responseWriter.ContentLength   = json.Length;
                    }

                    if (!WriteToStream(json))
                    {
                        return(false);
                    }
                }
                else if (BinaryBody != null)
                {
                    this["Content-Type"]            = BaseContentType;
                    _responseWriter.ContentEncoding = Encoding.UTF8;
                    var data = BinaryBody.ToArray();
                    if (!Chunked)
                    {
                        _responseWriter.ContentLength = data.LongLength;
                    }

                    if (!WriteToStream(data))
                    {
                        return(false);
                    }
                }
                else if (MultipartWriter != null)
                {
                    _responseWriter.ContentLength = MultipartWriter.Length;
                    MultipartWriter.WriteAsync(_responseWriter.OutputStream).ContinueWith(t =>
                    {
                        if (t.IsCompleted && t.Result)
                        {
                            TryClose();
                        }
                        else
                        {
                            Log.To.Router.I(TAG, "Multipart async write did not finish properly");
                        }
                    });
                    syncWrite = false;
                }
            }

            if (syncWrite)
            {
                TryClose();
            }

            return(true);
        }
예제 #15
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);
                    }
                }
            }
        }