/// <exception cref="InvalidDataException"></exception>
        private HttpResponse <string> ParseNextSubresponseFrom(PeekableStreamReader reader, string boundary)
        {
            var currentLine = reader.ReadFirstNonEmptyLine();

            if (currentLine != BatchSerializeHelper.GetOpenBoundaryString(boundary))
            {
                throw new InvalidDataException("Response boundary missed");
            }

            currentLine = reader.ReadFirstNonEmptyLineOrThrow("Content type header not found");
            //  if (currentLine?.Trim() != HttpHelper.HttpRequestContentTypeHeaderString)
            if (!currentLine.Trim().StartsWith(HttpHelper.ContentTypeHeader))
            {
                throw new InvalidDataException("Content type has invalid format");
            }

            currentLine = reader.ReadFirstNonEmptyLineOrThrow("Status code is missed");

            var resultCode = BatchSerializeHelper.GetResultCodeOrThrow(currentLine);



            var content = BatchSerializeHelper.ReadUntilBoundaryOrThrow(reader, boundary);

            return(new HttpResponse <string>(
                       new ResponseInfo((HttpStatusCode)resultCode),
                       content));
        }
        public void ReadUntilBoundary_boundaryNotExist_throws()
        {
            string content = "before1\r\nbefore2";

            Assert.Throws <InvalidDataException>(
                () => BatchSerializeHelper.ReadUntilBoundaryOrThrow(GetReaderFor(content), "someBoundary"));
        }
        /// <exception cref="InvalidDataException"></exception>
        public IHttpResponse Deserialize(ResponseInfo responseInfo, Stream dataStream)
        {
            var contentType = responseInfo.GetHeaderValueOrNull(HttpHelper.ContentTypeHeader);

            if (string.IsNullOrWhiteSpace(contentType))
            {
                throw new InvalidDataException("Content-Type header missed");
            }

            var boundary = BatchSerializeHelper.GetBoundaryStringOrThrow(contentType);

            var subresponses = new List <IHttpResponse>(_subresponseDeserializers.Length);

            using (var reader = new PeekableStreamReader(dataStream))
            {
                if (reader.ReadUntilFirstNonEmptyLine())
                {
                    while (true)
                    {
                        var subrequest = ParseNextSubresponseFrom(reader, boundary);
                        subresponses.Add(subrequest);
                        if (reader.PeekLine() == BatchSerializeHelper.GetCloseBoundaryString(boundary))
                        {
                            break;
                        }
                    }
                }
            }
            if (subresponses.Count > _subresponseDeserializers.Length)
            {
                throw new InvalidDataException($"Actual and items count is greater than expected. Actual: {subresponses.Count}, expected: {_subresponseDeserializers.Length}");
            }

            return(new HttpResponse <IHttpResponse[]>(responseInfo, subresponses.ToArray()));
        }
        public void WriteTo(Stream stream, Uri host)
        {
            foreach (var request in SubRequests)
            {
                var sb = new StringBuilder();
                sb.AppendLine(BatchSerializeHelper.GetOpenBoundaryString(_boundary));
                sb.AppendLine(HttpHelper.HttpRequestContentTypeHeaderString);
                sb.AppendLine();
                sb.AppendLine($"{request.Method.Name} {request.QueryAbsolutePath} {HttpHelper.Http11VersionCaption}");
                sb.AppendLine($"Host: {host.Authority}");
                stream.WriteUtf8(sb.ToString());

                if (request.Content != null)
                {
                    stream.WriteUtf8($"{HttpHelper.ContentTypeHeader}: {request.Content.ContentType}\r\n\r\n");
                    request.Content.WriteTo(stream, host);
                }
                else
                {
                    stream.WriteUtf8("\r\n");
                }
                stream.WriteUtf8("\r\n");
            }
            stream.WriteUtf8(BatchSerializeHelper.GetCloseBoundaryString(_boundary));
        }
        public void ReadUntilBoundary_boundaryIsNotLast_ResultsAreCorrect(string beforeBoundary, string afterBoundary)
        {
            string boundary = "theBoundary";
            var    text     = $"{beforeBoundary}\r\n--{boundary}\r\n{afterBoundary}";
            var    actual   = BatchSerializeHelper.ReadUntilBoundaryOrThrow(GetReaderFor(text), boundary);

            Assert.AreEqual(beforeBoundary, actual);
        }
        public void ReadUntilBoundary_boundaryIsLast_ResultsAreCorrect()
        {
            string boundary = "theBoundary";
            string content  = "before1\r\nbefore2";
            var    text     = $"{content}\r\n--{boundary}--\r\nsome string after";
            var    actual   = BatchSerializeHelper.ReadUntilBoundaryOrThrow(GetReaderFor(text), boundary);

            Assert.AreEqual(content, actual);
        }
        public void GetBoundaryStringOrThrow_SearchesForSpecifiedBoundary(string contentTypeString, string boundary)
        {
            var actual = BatchSerializeHelper.GetBoundaryStringOrThrow(contentTypeString);

            Assert.AreEqual(boundary, actual);
        }
 public void GetResultCodeOrThrow_StringIsInvalid_Throws(string str)
 {
     Assert.Throws <InvalidDataException>(() => BatchSerializeHelper.GetResultCodeOrThrow(str));
 }
        public void GetResultCodeOrThrow_StringIsCorrect_SpecifiedCodeFound(string str, int code)
        {
            var actualCode = BatchSerializeHelper.GetResultCodeOrThrow(str);

            Assert.AreEqual(code, actualCode);
        }
 public void GetBoundaryStringOrThrow_ContentTypeStringIsInvalid_Throws(string contentTypeString)
 {
     Assert.Throws <InvalidDataException>(() => BatchSerializeHelper.GetBoundaryStringOrThrow(contentTypeString));
 }