Пример #1
0
        private bool ParseBatchPart(bool isResponse, TextReader reader, InMemoryWebRequest part, string boundary, string endboundary)
        {
            bool   result = false;
            string line;

            if (isResponse)
            {
                part.ParseResponseStatus(reader);
            }
            else
            {
                part.ParseRequestVerb(reader);
            }

            if (isResponse)
            {
                part.ResponseHeaders.Clear();
                InMemoryWebRequest.ParseHeaders(reader, part.ResponseHeaders);
            }
            else
            {
                InMemoryWebRequest.ParseHeaders(reader, part.RequestHeaders);
                InMemoryWebRequest.ApplyHeadersToProperties(part);
            }

            StringBuilder sb       = new StringBuilder();
            string        lastLine = null;

            while ((line = reader.ReadLine()) != null)
            {
                if (line == boundary)
                {
                    break;
                }
                if (line == endboundary)
                {
                    result = true;
                    break;
                }
                if (lastLine != null)
                {
                    sb.AppendLine(lastLine);
                }
                lastLine = line;
            }
            // The last line must not end with a newline - the batch adds it there, but it's not actually part of the content
            sb.Append(lastLine);
            if (isResponse)
            {
                part.SetResponseStream(new MemoryStream(Encoding.UTF8.GetBytes(sb.ToString())));
            }
            else
            {
                part.SetRequestStreamAsText(sb.ToString());
            }
            return(result);
        }
Пример #2
0
        public Stream ProcessRequestForMessage(Stream messageBody)
        {
            this.response = new StringBuilder();
            WebOperationContext c = WebOperationContext.Current;

            if (InternalProcessRequestOverride != null)
            {
                InMemoryWebRequest request  = new InMemoryWebRequest();
                InMemoryWebRequest response = null;

                try
                {
                    request.HttpMethod       = c.IncomingRequest.Method;
                    request.RequestUriString = c.IncomingRequest.UriTemplateMatch.RequestUri.AbsoluteUri.Substring(c.IncomingRequest.UriTemplateMatch.BaseUri.AbsoluteUri.Length);
                    foreach (string headerKey in c.IncomingRequest.Headers.AllKeys)
                    {
                        request.RequestHeaders[headerKey] = c.IncomingRequest.Headers[headerKey];
                    }
                    InMemoryWebRequest.ApplyHeadersToProperties(request);
                    request.SetRequestStream(messageBody);

                    response = InternalProcessRequestOverride(request);
                }
                catch (Exception e)
                {
                    response = new InMemoryWebRequest();
                    response.SetResponseStatusCode(500);
                    response.SetResponseStreamAsText(CreateErrorPayload(e));
                }

                c.OutgoingResponse.StatusCode = (HttpStatusCode)response.ResponseStatusCode;
                foreach (var header in response.ResponseHeaders)
                {
                    c.OutgoingResponse.Headers[header.Key] = header.Value;
                }

                if (response.GetResponseStream() != null)
                {
                    MemoryStream body = new MemoryStream();
                    System.Data.Test.Astoria.TestUtil.CopyStream(response.GetResponseStream(), body);
                    body.Position = 0;
                    return(body);
                }
                else
                {
                    return(null);
                }
            }

            if (InternalInspectRequestPayload != null)
            {
                MemoryStream ms = new MemoryStream();
                test.TestUtil.CopyStream(messageBody, ms);
                messageBody          = ms;
                messageBody.Position = 0;
                InternalInspectRequestPayload(messageBody);
                messageBody.Position = 0;
            }

            Append("<error xmlns='http://docs.oasis-open.org/odata/ns/metadata'>");
            Append("<message>");
            Append(c.IncomingRequest.Method + " " + c.IncomingRequest.UriTemplateMatch.RequestUri.OriginalString);
            Append("\r\n");
            Append(c.IncomingRequest.Headers.ToString());
            Append("\r\n");
            AppendXmlStream(messageBody);
            Append("</message>");
            Append("</error>");

            lastPlayback = this.response.ToString();

            string result = lastPlayback;

            if (InternalOverridingPlayback != null)
            {
                result = ProcessOverridingPlayback(c);

                // For batch request, i need to send the exact content id otherwise the client chokes
                int startIndex = lastPlayback.IndexOf("Content-ID: ");
                if (startIndex != -1)
                {
                    // advance the index to the start of the content id
                    startIndex += "Content-ID: ".Length;
                    int endIndex  = lastPlayback.IndexOf(Environment.NewLine, startIndex);
                    int contentID = Int32.Parse(lastPlayback.Substring(startIndex, endIndex - startIndex));

                    int resultStartIndex = result.IndexOf("Content-ID: ") + "Content-ID: ".Length;
                    int resultEndIndex   = result.IndexOf(Environment.NewLine, resultStartIndex);
                    result = result.Substring(0, resultStartIndex) + contentID + result.Substring(resultEndIndex);
                }
            }
            else
            {
                if (c.IncomingRequest.ContentType != null)
                {
                    c.OutgoingResponse.ContentType = c.IncomingRequest.ContentType;
                }
                else
                {
                    // Took a breaking change, since the content type now must be correct.
                    // In V1/V2, astoria client used to parse error payloads even when response content type value was application/atom+xml
                    // After integration, it must be application/xml.
                    c.OutgoingResponse.ContentType = AstoriaUnitTests.Data.SerializationFormatData.Atom.MimeTypes[2];
                }

                if (c.IncomingRequest.Method == "POST")
                {
                    c.OutgoingResponse.Location = "http://www.microsoft.com/";
                }
            }

            return((result == null) ? null : new MemoryStream(Encoding.ASCII.GetBytes(result)));
        }