internal static ODataBatchOperationResponseMessage CreateReadMessage(ODataBatchReaderStream batchReaderStream, int statusCode, ODataBatchOperationHeaders headers, IODataBatchOperationListener operationListener, IODataUrlResolver urlResolver)
 {
     return(new ODataBatchOperationResponseMessage(() => ODataBatchUtils.CreateBatchOperationReadStream(batchReaderStream, headers, operationListener), headers, operationListener, urlResolver, false)
     {
         statusCode = statusCode
     });
 }
Beispiel #2
0
        /// <summary>
        /// Creates an operation response message that can be used to write the operation content to.
        /// </summary>
        /// <param name="outputStream">The output stream underlying the operation message.</param>
        /// <param name="operationListener">The operation listener.</param>
        /// <param name="urlResolver">The (optional) URL resolver for the message to create.</param>
        /// <returns>An <see cref="ODataBatchOperationResponseMessage"/> that can be used to write the operation content.</returns>
        internal static ODataBatchOperationResponseMessage CreateWriteMessage(
            Stream outputStream,
            IODataBatchOperationListener operationListener,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();

            Func <Stream> streamCreatorFunc = () => ODataBatchUtils.CreateBatchOperationWriteStream(outputStream, operationListener);

            return(new ODataBatchOperationResponseMessage(streamCreatorFunc, /*headers*/ null, operationListener, urlResolver, /*writing*/ true));
        }
        /// <summary>
        /// Creates an operation request message that can be used to write the operation content to.
        /// </summary>
        /// <param name="outputStream">The output stream underlying the operation message.</param>
        /// <param name="method">The HTTP method to use for the message to create.</param>
        /// <param name="requestUrl">The request URL for the message to create.</param>
        /// <param name="operationListener">The operation listener.</param>
        /// <param name="urlResolver">The (optional) URL resolver for the message to create.</param>
        /// <returns>An <see cref="ODataBatchOperationRequestMessage"/> to write the request content to.</returns>
        internal static ODataBatchOperationRequestMessage CreateWriteMessage(
            Stream outputStream,
            string method,
            Uri requestUrl,
            IODataBatchOperationListener operationListener,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(outputStream != null, "outputStream != null");
            Debug.Assert(operationListener != null, "operationListener != null");

            Func <Stream> streamCreatorFunc = () => ODataBatchUtils.CreateBatchOperationWriteStream(outputStream, operationListener);

            return(new ODataBatchOperationRequestMessage(streamCreatorFunc, method, requestUrl, /*headers*/ null, operationListener, urlResolver, /*writing*/ true));
        }
        /// <summary>
        /// Creates an operation request message that can be used to read the operation content from.
        /// </summary>
        /// <param name="batchReaderStream">The batch stream underyling the operation response message.</param>
        /// <param name="method">The HTTP method to use for the message to create.</param>
        /// <param name="requestUrl">The request URL for the message to create.</param>
        /// <param name="headers">The headers to use for the operation request message.</param>
        /// <param name="operationListener">The operation listener.</param>
        /// <param name="urlResolver">The (optional) URL resolver for the message to create.</param>
        /// <returns>An <see cref="ODataBatchOperationRequestMessage"/> to read the request content from.</returns>
        internal static ODataBatchOperationRequestMessage CreateReadMessage(
            ODataBatchReaderStream batchReaderStream,
            string method,
            Uri requestUrl,
            ODataBatchOperationHeaders headers,
            IODataBatchOperationListener operationListener,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(batchReaderStream != null, "batchReaderStream != null");
            Debug.Assert(operationListener != null, "operationListener != null");

            Func <Stream> streamCreatorFunc = () => ODataBatchUtils.CreateBatchOperationReadStream(batchReaderStream, headers, operationListener);

            return(new ODataBatchOperationRequestMessage(streamCreatorFunc, method, requestUrl, headers, operationListener, urlResolver, /*writing*/ false));
        }
Beispiel #5
0
        /// <summary>
        /// Creates an operation response message that can be used to read the operation content from.
        /// </summary>
        /// <param name="batchReaderStream">The batch stream underyling the operation response message.</param>
        /// <param name="statusCode">The status code to use for the operation response message.</param>
        /// <param name="headers">The headers to use for the operation response message.</param>
        /// <param name="operationListener">The operation listener.</param>
        /// <param name="urlResolver">The (optional) URL resolver for the message to create.</param>
        /// <returns>An <see cref="ODataBatchOperationResponseMessage"/> that can be used to read the operation content.</returns>
        internal static ODataBatchOperationResponseMessage CreateReadMessage(
            ODataBatchReaderStream batchReaderStream,
            int statusCode,
            ODataBatchOperationHeaders headers,
            IODataBatchOperationListener operationListener,
            IODataUrlResolver urlResolver)
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(batchReaderStream != null, "batchReaderStream != null");
            Debug.Assert(operationListener != null, "operationListener != null");

            Func <Stream> streamCreatorFunc = () => ODataBatchUtils.CreateBatchOperationReadStream(batchReaderStream, headers, operationListener);
            ODataBatchOperationResponseMessage responseMessage =
                new ODataBatchOperationResponseMessage(streamCreatorFunc, headers, operationListener, urlResolver, /*writing*/ false);

            responseMessage.statusCode = statusCode;
            return(responseMessage);
        }
Beispiel #6
0
        private void ParseRequestLine(string requestLine, out string httpMethod, out Uri requestUri)
        {
            int index = requestLine.IndexOf(' ');

            if ((index <= 0) || ((requestLine.Length - 3) <= index))
            {
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidRequestLine(requestLine));
            }
            int num2 = requestLine.LastIndexOf(' ');

            if (((num2 < 0) || (((num2 - index) - 1) <= 0)) || ((requestLine.Length - 1) <= num2))
            {
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidRequestLine(requestLine));
            }
            httpMethod = requestLine.Substring(0, index);
            string uriString = requestLine.Substring(index + 1, (num2 - index) - 1);
            string strB      = requestLine.Substring(num2 + 1);

            if (string.CompareOrdinal("HTTP/1.1", strB) != 0)
            {
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidHttpVersionSpecified(strB, "HTTP/1.1"));
            }
            HttpUtils.ValidateHttpMethod(httpMethod);
            if (this.batchStream.ChangeSetBoundary == null)
            {
                if (string.CompareOrdinal(httpMethod, "GET") != 0)
                {
                    throw new ODataException(Strings.ODataBatch_InvalidHttpMethodForQueryOperation(httpMethod));
                }
            }
            else if (string.CompareOrdinal(httpMethod, "GET") == 0)
            {
                throw new ODataException(Strings.ODataBatch_InvalidHttpMethodForChangeSetRequest(httpMethod));
            }
            requestUri = new Uri(uriString, UriKind.RelativeOrAbsolute);
            requestUri = ODataBatchUtils.CreateOperationRequestUri(requestUri, this.inputContext.MessageReaderSettings.BaseUri, this.urlResolver);
        }
Beispiel #7
0
 private ODataBatchOperationRequestMessage CreateOperationRequestMessageImplementation(string method, Uri uri)
 {
     if (this.changeSetBoundary == null)
     {
         this.InterceptException(new Action(this.IncreaseBatchSize));
     }
     else
     {
         this.InterceptException(new Action(this.IncreaseChangeSetSize));
     }
     this.WritePendingMessageData(true);
     if (this.currentOperationContentId != null)
     {
         this.urlResolver.AddContentId(this.currentOperationContentId);
     }
     this.InterceptException(delegate {
         uri = ODataBatchUtils.CreateOperationRequestUri(uri, this.rawOutputContext.MessageWriterSettings.BaseUri, this.urlResolver);
     });
     this.CurrentOperationRequestMessage = ODataBatchOperationRequestMessage.CreateWriteMessage(this.rawOutputContext.OutputStream, method, uri, this, this.urlResolver);
     this.SetState(BatchWriterState.OperationCreated);
     this.WriteStartBoundaryForOperation();
     ODataBatchWriterUtils.WriteRequestPreamble(this.rawOutputContext.TextWriter, method, uri);
     return(this.CurrentOperationRequestMessage);
 }
 internal static ODataBatchOperationResponseMessage CreateWriteMessage(Stream outputStream, IODataBatchOperationListener operationListener, IODataUrlResolver urlResolver)
 {
     return(new ODataBatchOperationResponseMessage(() => ODataBatchUtils.CreateBatchOperationWriteStream(outputStream, operationListener), null, operationListener, urlResolver, true));
 }
Beispiel #9
0
        /// <summary>
        /// Parses the request line of a batch operation request.
        /// </summary>
        /// <param name="requestLine">The request line as a string.</param>
        /// <param name="httpMethod">The parsed HTTP method of the request.</param>
        /// <param name="requestUri">The parsed <see cref="Uri"/> of the request.</param>
        private void ParseRequestLine(string requestLine, out string httpMethod, out Uri requestUri)
        {
            Debug.Assert(!this.inputContext.ReadingResponse, "Must only be called for requests.");

            // Batch Request: POST /Customers HTTP/1.1
            // Since the uri can contain spaces, the only way to read the request url, is to
            // check for first space character and last space character and anything between
            // them.
            int firstSpaceIndex = requestLine.IndexOf(' ');

            // Check whether there are enough characters after the first space for the 2nd and 3rd segments
            // (and a whitespace in between)
            if (firstSpaceIndex <= 0 || requestLine.Length - 3 <= firstSpaceIndex)
            {
                // only 1 segment or empty first segment or not enough left for 2nd and 3rd segments
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidRequestLine(requestLine));
            }

            int lastSpaceIndex = requestLine.LastIndexOf(' ');

            if (lastSpaceIndex < 0 || lastSpaceIndex - firstSpaceIndex - 1 <= 0 || requestLine.Length - 1 <= lastSpaceIndex)
            {
                // only 2 segments or empty 2nd or 3rd segments
                // only 1 segment or empty first segment or not enough left for 2nd and 3rd segments
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidRequestLine(requestLine));
            }

            httpMethod = requestLine.Substring(0, firstSpaceIndex);                                                       // Request - Http method
            string uriSegment         = requestLine.Substring(firstSpaceIndex + 1, lastSpaceIndex - firstSpaceIndex - 1); // Request - Request uri
            string httpVersionSegment = requestLine.Substring(lastSpaceIndex + 1);                                        // Request - Http version

            // Validate HttpVersion
            if (string.CompareOrdinal(ODataConstants.HttpVersionInBatching, httpVersionSegment) != 0)
            {
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidHttpVersionSpecified(httpVersionSegment, ODataConstants.HttpVersionInBatching));
            }

            // NOTE: this method will throw if the method is not recognized.
            HttpUtils.ValidateHttpMethod(httpMethod);

            // Validate the HTTP method when reading a request
            if (this.batchStream.ChangeSetBoundary == null)
            {
                // only allow GET requests for query operations
                if (!HttpUtils.IsQueryMethod(httpMethod))
                {
                    throw new ODataException(Strings.ODataBatch_InvalidHttpMethodForQueryOperation(httpMethod));
                }
            }
            else
            {
                // allow all methods except for GET
                if (HttpUtils.IsQueryMethod(httpMethod))
                {
                    throw new ODataException(Strings.ODataBatch_InvalidHttpMethodForChangeSetRequest(httpMethod));
                }
            }

            requestUri = new Uri(uriSegment, UriKind.RelativeOrAbsolute);
            requestUri = ODataBatchUtils.CreateOperationRequestUri(requestUri, this.inputContext.MessageReaderSettings.BaseUri, this.urlResolver);
        }
        internal string ReadLine()
        {
            int numberOfBytesInBuffer = 0;

            byte[] lineBuffer = this.lineBuffer;
            ODataBatchReaderStreamScanResult noMatch = ODataBatchReaderStreamScanResult.NoMatch;

            while (noMatch != ODataBatchReaderStreamScanResult.Match)
            {
                int num2;
                int num3;
                int num4;
                noMatch = this.batchBuffer.ScanForLineEnd(out num3, out num4);
                switch (noMatch)
                {
                case ODataBatchReaderStreamScanResult.NoMatch:
                {
                    num2 = this.batchBuffer.NumberOfBytesInBuffer;
                    if (num2 > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref lineBuffer, numberOfBytesInBuffer, num2);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, lineBuffer, numberOfBytesInBuffer, num2);
                        numberOfBytesInBuffer += num2;
                    }
                    if (this.underlyingStreamExhausted)
                    {
                        noMatch = ODataBatchReaderStreamScanResult.Match;
                        this.batchBuffer.SkipTo(this.batchBuffer.CurrentReadPosition + num2);
                    }
                    else
                    {
                        this.underlyingStreamExhausted = this.batchBuffer.RefillFrom(this.inputContext.Stream, 0x1f40);
                    }
                    continue;
                }

                case ODataBatchReaderStreamScanResult.PartialMatch:
                {
                    num2 = num3 - this.batchBuffer.CurrentReadPosition;
                    if (num2 > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref lineBuffer, numberOfBytesInBuffer, num2);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, lineBuffer, numberOfBytesInBuffer, num2);
                        numberOfBytesInBuffer += num2;
                    }
                    if (this.underlyingStreamExhausted)
                    {
                        noMatch = ODataBatchReaderStreamScanResult.Match;
                        this.batchBuffer.SkipTo(num3 + 1);
                    }
                    else
                    {
                        this.underlyingStreamExhausted = this.batchBuffer.RefillFrom(this.inputContext.Stream, num3);
                    }
                    continue;
                }

                case ODataBatchReaderStreamScanResult.Match:
                {
                    num2 = num3 - this.batchBuffer.CurrentReadPosition;
                    if (num2 > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref lineBuffer, numberOfBytesInBuffer, num2);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, lineBuffer, numberOfBytesInBuffer, num2);
                        numberOfBytesInBuffer += num2;
                    }
                    this.batchBuffer.SkipTo(num4 + 1);
                    continue;
                }
                }
                throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataBatchReaderStream_ReadLine));
            }
            if (lineBuffer == null)
            {
                return(string.Empty);
            }
            return(this.CurrentEncoding.GetString(lineBuffer, 0, numberOfBytesInBuffer));
        }
        /// <summary>
        /// Reads a line (all bytes until a line feed) from the underlying stream.
        /// </summary>
        /// <returns>Returns the string that was read from the underyling stream (not including a terminating line feed).</returns>
        internal string ReadLine()
        {
            DebugUtils.CheckNoExternalCallers();
            Debug.Assert(this.batchEncoding != null, "Batch encoding should have been established on first call to SkipToBoundary.");
            Debug.Assert(this.lineBuffer != null && this.lineBuffer.Length == LineBufferLength, "Line buffer should have been created.");

            // The number of bytes in the line buffer that make up the line.
            int lineBufferSize = 0;

            // Start with the pre-allocated line buffer array.
            byte[] bytesForString = this.lineBuffer;

            ODataBatchReaderStreamScanResult scanResult = ODataBatchReaderStreamScanResult.NoMatch;

            while (scanResult != ODataBatchReaderStreamScanResult.Match)
            {
                int byteCount, lineEndStartPosition, lineEndEndPosition;
                scanResult = this.batchBuffer.ScanForLineEnd(out lineEndStartPosition, out lineEndEndPosition);
                switch (scanResult)
                {
                case ODataBatchReaderStreamScanResult.NoMatch:
                    // Copy all the bytes in the batchBuffer into the result byte[] and then continue
                    byteCount = this.batchBuffer.NumberOfBytesInBuffer;
                    if (byteCount > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref bytesForString, lineBufferSize, byteCount);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, bytesForString, lineBufferSize, byteCount);
                        lineBufferSize += byteCount;
                    }

                    if (this.underlyingStreamExhausted)
                    {
                        // Nothing more to read; stop looping
                        scanResult = ODataBatchReaderStreamScanResult.Match;
                        this.batchBuffer.SkipTo(this.batchBuffer.CurrentReadPosition + byteCount);
                    }
                    else
                    {
                        this.underlyingStreamExhausted = this.batchBuffer.RefillFrom(this.inputContext.Stream, /*preserveFrom*/ ODataBatchReaderStreamBuffer.BufferLength);
                    }

                    break;

                case ODataBatchReaderStreamScanResult.PartialMatch:
                    // We found the start of a line end in the buffer but could not verify whether we saw all of it.
                    // This can happen if a line end is represented as \r\n and we found \r at the very last position in the buffer.
                    // In this case we copy the bytes into the result byte[] and continue at the start of the line end; this will guarantee
                    // that the next scan will find the full line end, not find any additional bytes and then skip the full line end.
                    // It is safe to copy the string right here because we will also accept \r as a line end; we are just not sure whether there
                    // will be a subsequent \n.
                    // This can also happen if the last byte in the stream is \r.
                    byteCount = lineEndStartPosition - this.batchBuffer.CurrentReadPosition;
                    if (byteCount > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref bytesForString, lineBufferSize, byteCount);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, bytesForString, lineBufferSize, byteCount);
                        lineBufferSize += byteCount;
                    }

                    if (this.underlyingStreamExhausted)
                    {
                        // Nothing more to read; stop looping
                        scanResult = ODataBatchReaderStreamScanResult.Match;
                        this.batchBuffer.SkipTo(lineEndStartPosition + 1);
                    }
                    else
                    {
                        this.underlyingStreamExhausted = this.batchBuffer.RefillFrom(this.inputContext.Stream, /*preserveFrom*/ lineEndStartPosition);
                    }

                    break;

                case ODataBatchReaderStreamScanResult.Match:
                    // We found a line end in the buffer
                    Debug.Assert(lineEndStartPosition >= this.batchBuffer.CurrentReadPosition, "Line end must be at or after current position.");
                    Debug.Assert(lineEndEndPosition < this.batchBuffer.CurrentReadPosition + this.batchBuffer.NumberOfBytesInBuffer, "Line end must finish withing buffer range.");

                    byteCount = lineEndStartPosition - this.batchBuffer.CurrentReadPosition;
                    if (byteCount > 0)
                    {
                        ODataBatchUtils.EnsureArraySize(ref bytesForString, lineBufferSize, byteCount);
                        Buffer.BlockCopy(this.batchBuffer.Bytes, this.batchBuffer.CurrentReadPosition, bytesForString, lineBufferSize, byteCount);
                        lineBufferSize += byteCount;
                    }

                    this.batchBuffer.SkipTo(lineEndEndPosition + 1);
                    break;

                default:
                    throw new ODataException(Strings.General_InternalError(InternalErrorCodes.ODataBatchReaderStream_ReadLine));
                }
            }

            if (bytesForString == null)
            {
                return(string.Empty);
            }

            return(this.CurrentEncoding.GetString(bytesForString, 0, lineBufferSize));
        }
 internal static ODataBatchOperationRequestMessage CreateWriteMessage(Stream outputStream, string method, Uri requestUrl, IODataBatchOperationListener operationListener, IODataUrlResolver urlResolver)
 {
     return(new ODataBatchOperationRequestMessage(() => ODataBatchUtils.CreateBatchOperationWriteStream(outputStream, operationListener), method, requestUrl, null, operationListener, urlResolver, true));
 }
 internal static ODataBatchOperationRequestMessage CreateReadMessage(ODataBatchReaderStream batchReaderStream, string method, Uri requestUrl, ODataBatchOperationHeaders headers, IODataBatchOperationListener operationListener, IODataUrlResolver urlResolver)
 {
     return(new ODataBatchOperationRequestMessage(() => ODataBatchUtils.CreateBatchOperationReadStream(batchReaderStream, headers, operationListener), method, requestUrl, headers, operationListener, urlResolver, false));
 }