コード例 #1
0
        /// <summary>
        /// Returns the http method name given the batch stream state
        /// </summary>
        /// <param name="state">state of the batch stream.</param>
        /// <returns>returns the http method name</returns>
        private static string GetHttpMethodName(BatchStreamState state)
        {
            Debug.Assert(
                state == BatchStreamState.Get ||
                state == BatchStreamState.Post ||
                state == BatchStreamState.Put ||
                state == BatchStreamState.Delete ||
                state == BatchStreamState.Merge,
                "Expecting BatchStreamState (" + state + ") to be Delete, Get, Post or Put");

            switch (state)
            {
            case BatchStreamState.Delete:
                return(XmlConstants.HttpMethodDelete);

            case BatchStreamState.Get:
                return(XmlConstants.HttpMethodGet);

            case BatchStreamState.Post:
                return(XmlConstants.HttpMethodPost);

            case BatchStreamState.Merge:
                return(XmlConstants.HttpMethodMerge);

            default:
                Debug.Assert(BatchStreamState.Put == state, "BatchStreamState.Put == state");
                return(XmlConstants.HttpMethodPut);
            }
        }
コード例 #2
0
#pragma warning restore 649
#endif

        internal BatchStream(Stream stream, string boundary, Encoding batchEncoding, bool requestStream)
        {
            Debug.Assert(null != stream, "null stream");

            this.reader        = stream;
            this.byteBuffer    = new byte[DefaultBufferSize];
            this.batchBoundary = VerifyBoundary(boundary);
            this.batchState    = BatchStreamState.StartBatch;
            this.batchEncoding = batchEncoding;
            this.checkPreamble = (null != batchEncoding);
            this.batchRequest  = requestStream;
        }
コード例 #3
0
#pragma warning restore 649

        internal BatchStream(Stream stream, string boundary, Encoding batchEncoding, bool requestStream)
        {
            Debug.Assert(null != stream, "null stream");

            this.reader = stream;
            this.byteBuffer = new byte[DefaultBufferSize];
            this.batchBoundary = VerifyBoundary(boundary);
            this.batchState = BatchStreamState.StartBatch;
            this.batchEncoding = batchEncoding;
            this.checkPreamble = null != batchEncoding;
            this.batchRequest = requestStream;
        }
コード例 #4
0
 internal static InvalidOperationException BatchStreamContentUnexpected(BatchStreamState state)
 {
     return(InvalidOperation(Strings.BatchStream_ContentUnexpected(state.ToString())));
 }
コード例 #5
0
        /// <summary>
        /// Returns the http method name given the batch stream state
        /// </summary>
        /// <param name="state">state of the batch stream.</param>
        /// <returns>returns the http method name</returns>
        private static string GetHttpMethodName(BatchStreamState state)
        {
            Debug.Assert(
                state == BatchStreamState.Get ||
                state == BatchStreamState.Post ||
                state == BatchStreamState.Put ||
                state == BatchStreamState.Delete ||
                state == BatchStreamState.Merge,
                "Expecting BatchStreamState (" + state + ") to be Delete, Get, Post or Put");

            switch (state)
            {
                case BatchStreamState.Delete:
                    return XmlConstants.HttpMethodDelete;
                case BatchStreamState.Get:
                    return XmlConstants.HttpMethodGet;
                case BatchStreamState.Post:
                    return XmlConstants.HttpMethodPost;
                case BatchStreamState.Merge:
                    return XmlConstants.HttpMethodMerge;
                default:
                    Debug.Assert(BatchStreamState.Put == state, "BatchStreamState.Put == state");
                    return XmlConstants.HttpMethodPut;
            }
        }
コード例 #6
0
        internal bool MoveNext()
        {
            #region dispose previous content stream
            if (null == this.reader || this.disposeWithContentStreamDispose)
            {
                return(false);
            }

            if (null != this.contentStream)
            {
                this.contentStream.Dispose();
            }

            Debug.Assert(0 <= this.byteLength, "negative byteLength");
            Debug.Assert(0 <= this.batchLength, "negative batchLength");
            #endregion

            #region initialize start state to EndBatch or EndChangeSet
            switch (this.batchState)
            {
            case BatchStreamState.EndBatch:
                Debug.Assert(null == this.batchBoundary, "non-null batch boundary");
                Debug.Assert(null == this.changesetBoundary, "non-null changesetBoundary boundary");
                throw Error.BatchStreamInvalidBatchFormat();

            case BatchStreamState.Get:
            case BatchStreamState.GetResponse:
                this.ClearPreviousOperationInformation();
                goto case BatchStreamState.StartBatch;

            case BatchStreamState.StartBatch:
            case BatchStreamState.EndChangeSet:
                Debug.Assert(null != this.batchBoundary, "null batch boundary");
                Debug.Assert(null == this.changesetBoundary, "non-null changeset boundary");
                this.batchState  = BatchStreamState.EndBatch;
                this.batchLength = Int32.MaxValue;
                break;

            case BatchStreamState.BeginChangeSet:
                Debug.Assert(null != this.batchBoundary, "null batch boundary");
                Debug.Assert(null != this.contentHeaders, "null contentHeaders");
                Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                this.contentHeaders    = null;
                this.changesetEncoding = null;
                this.batchState        = BatchStreamState.EndChangeSet;
                break;

            case BatchStreamState.ChangeResponse:
            case BatchStreamState.Delete:
                Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                this.ClearPreviousOperationInformation();
                this.batchState = BatchStreamState.EndChangeSet;
                break;

            case BatchStreamState.Post:
            case BatchStreamState.Put:
            case BatchStreamState.Merge:
                Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                this.batchState = BatchStreamState.EndChangeSet;
                break;

            default:
                Debug.Assert(false, "unknown state");
                throw Error.BatchStreamInvalidBatchFormat();
            }

            Debug.Assert(null == this.contentHeaders, "non-null content headers");
            Debug.Assert(null == this.contentStream, "non-null content stream");
#if ASTORIA_SERVER
            Debug.Assert(null == this.contentUri, "non-null content uri");
#endif
#if ASTORIA_CLIENT
            Debug.Assert(null == this.statusCode, "non-null statusCode");
#endif

            Debug.Assert(
                this.batchState == BatchStreamState.EndBatch ||
                this.batchState == BatchStreamState.EndChangeSet,
                "unexpected state at start");
            #endregion

            #region read --delimiter
            string delimiter = this.ReadLine();
            if (String.IsNullOrEmpty(delimiter))
            {
                delimiter = this.ReadLine();
            }

            if (String.IsNullOrEmpty(delimiter))
            {
                throw Error.BatchStreamInvalidBatchFormat();
            }

            if (delimiter.EndsWith("--", StringComparison.Ordinal))
            {
                delimiter = delimiter.Substring(0, delimiter.Length - 2);

                if ((null != this.changesetBoundary) && (delimiter == this.changesetBoundary))
                {
                    Debug.Assert(this.batchState == BatchStreamState.EndChangeSet, "bad changeset boundary state");

                    this.changesetBoundary = null;
                    return(true);
                }
                else if (delimiter == this.batchBoundary)
                {
                    if (BatchStreamState.EndChangeSet == this.batchState)
                    {
                        throw Error.BatchStreamMissingEndChangesetDelimiter();
                    }

                    this.changesetBoundary = null;
                    this.batchBoundary     = null;
                    if (this.byteLength != 0)
                    {
                        throw Error.BatchStreamMoreDataAfterEndOfBatch();
                    }

                    return(false);
                }
                else
                {
                    throw Error.BatchStreamInvalidDelimiter(delimiter);
                }
            }
            else if ((null != this.changesetBoundary) && (delimiter == this.changesetBoundary))
            {
                Debug.Assert(this.batchState == BatchStreamState.EndChangeSet, "bad changeset boundary state");
            }
            else if (delimiter == this.batchBoundary)
            {
                if (this.batchState != BatchStreamState.EndBatch)
                {
                    if (this.batchState == BatchStreamState.EndChangeSet)
                    {
                        throw Error.BatchStreamMissingEndChangesetDelimiter();
                    }
                    else
                    {
                        throw Error.BatchStreamInvalidBatchFormat();
                    }
                }
            }
            else
            {
                throw Error.BatchStreamInvalidDelimiter(delimiter);
            }

            #endregion

            #region read header with values in this form (([^:]*:.*)\r\n)*\r\n
            this.ReadContentHeaders();
            #endregion

            #region should start changeset?
            string contentType;
            bool   readHttpHeaders = false;
            if (this.contentHeaders.TryGetValue(XmlConstants.HttpContentType, out contentType))
            {
                if (String.Equals(contentType, XmlConstants.MimeApplicationHttp, StringComparison.OrdinalIgnoreCase))
                {
                    if (this.contentHeaders.Count != 2)
                    {
                        throw Error.BatchStreamInvalidNumberOfHeadersAtOperationStart(
                                  XmlConstants.HttpContentType,
                                  XmlConstants.HttpContentTransferEncoding);
                    }

                    string transferEncoding;
                    if (!this.contentHeaders.TryGetValue(XmlConstants.HttpContentTransferEncoding, out transferEncoding) ||
                        XmlConstants.BatchRequestContentTransferEncoding != transferEncoding)
                    {
                        throw Error.BatchStreamMissingOrInvalidContentEncodingHeader(
                                  XmlConstants.HttpContentTransferEncoding,
                                  XmlConstants.BatchRequestContentTransferEncoding);
                    }

                    readHttpHeaders = true;
                }
                else if (BatchStreamState.EndBatch == this.batchState)
                {
                    string   boundary;
                    Encoding encoding;
                    if (GetBoundaryAndEncodingFromMultipartMixedContentType(contentType, out boundary, out encoding))
                    {
                        this.changesetBoundary = VerifyBoundary(boundary);
                        this.changesetEncoding = encoding;
                        this.batchState        = BatchStreamState.BeginChangeSet;
                    }
                    else
                    {
                        throw Error.BatchStreamInvalidContentTypeSpecified(
                                  XmlConstants.HttpContentType,
                                  contentType,
                                  XmlConstants.MimeApplicationHttp,
                                  XmlConstants.MimeMultiPartMixed);
                    }

                    if (this.contentHeaders.Count > 2 ||
                        (this.contentHeaders.Count == 2 && !this.contentHeaders.ContainsKey(XmlConstants.HttpContentLength)))
                    {
                        throw Error.BatchStreamInvalidNumberOfHeadersAtChangeSetStart(XmlConstants.HttpContentType, XmlConstants.HttpContentLength);
                    }
                }
                else
                {
                    throw Error.BatchStreamInvalidContentTypeSpecified(
                              XmlConstants.HttpContentType,
                              contentType,
                              XmlConstants.MimeApplicationHttp,
                              XmlConstants.MimeMultiPartMixed);
                }
            }
            else
            {
                throw Error.BatchStreamMissingContentTypeHeader(XmlConstants.HttpContentType);
            }
            #endregion

            #region what is the operation and uri?
            if (readHttpHeaders)
            {
                this.ReadHttpHeaders();

                this.contentHeaders.TryGetValue(XmlConstants.HttpContentType, out contentType);
            }
            #endregion

            #region does content have a fixed length?
            string text   = null;
            int    length = -1;
            if (this.contentHeaders.TryGetValue(XmlConstants.HttpContentLength, out text))
            {
                length = Int32.Parse(text, CultureInfo.InvariantCulture);
                if (length < 0)
                {
                    throw Error.BatchStreamInvalidContentLengthSpecified(text);
                }

                if (this.batchState == BatchStreamState.BeginChangeSet)
                {
                    this.batchLength = length;
                }
                else if (length != 0)
                {
                    Debug.Assert(
                        this.batchState == BatchStreamState.Delete ||
                        this.batchState == BatchStreamState.Get ||
                        this.batchState == BatchStreamState.Post ||
                        this.batchState == BatchStreamState.Put ||
                        this.batchState == BatchStreamState.Merge,
                        "unexpected contentlength location");
                    this.contentStream = new StreamWithLength(this, length);
                }
            }
            else
            {
                if (this.batchState == BatchStreamState.EndBatch)
                {
                    this.batchLength = Int32.MaxValue;
                }

                if (this.batchState != BatchStreamState.BeginChangeSet)
                {
                    this.contentStream = new StreamWithDelimiter(this);
                }
            }

            #endregion

            Debug.Assert(
                this.batchState == BatchStreamState.BeginChangeSet ||
                (this.batchRequest && (this.batchState == BatchStreamState.Delete ||
                                       this.batchState == BatchStreamState.Get ||
                                       this.batchState == BatchStreamState.Post ||
                                       this.batchState == BatchStreamState.Put ||
                                       this.batchState == BatchStreamState.Merge)) ||
                (!this.batchRequest && (this.batchState == BatchStreamState.GetResponse ||
                                        this.batchState == BatchStreamState.ChangeResponse)),
                "unexpected state at return");

            #region enforce if contentStream is expected, caller needs to enforce if contentStream is not expected
            if (null == this.contentStream)
            {
                switch (this.batchState)
                {
                case BatchStreamState.BeginChangeSet:
                case BatchStreamState.Delete:
                case BatchStreamState.Get:
                case BatchStreamState.ChangeResponse:
                case BatchStreamState.GetResponse:
                    break;

                case BatchStreamState.Post:
                case BatchStreamState.Put:
                case BatchStreamState.Merge:
                default:
                    throw Error.BatchStreamContentExpected(this.batchState);
                }
            }
            #endregion

            #region enforce if contentType not is expected, caller needs to enforce if contentType is expected
            if (!String.IsNullOrEmpty(contentType))
            {
                switch (this.batchState)
                {
                case BatchStreamState.BeginChangeSet:
                case BatchStreamState.Post:
                case BatchStreamState.Put:
                case BatchStreamState.Merge:
                case BatchStreamState.GetResponse:
                case BatchStreamState.ChangeResponse:
                    break;

                case BatchStreamState.Get:
                case BatchStreamState.Delete:
                default:
                    throw Error.BatchStreamContentUnexpected(this.batchState);
                }
            }
            #endregion

            return(true);
        }
コード例 #7
0
        private void ReadHttpHeaders()
        {
            string line = this.ReadLine();

            int index1 = line.IndexOf(' ');

            if ((index1 <= 0) || ((line.Length - 3) <= index1))
            {
                throw Error.BatchStreamInvalidMethodHeaderSpecified(line);
            }

            int index2 = (this.batchRequest ? line.LastIndexOf(' ') : line.IndexOf(' ', index1 + 1));

            if ((index2 < 0) || (index2 - index1 - 1 <= 0) || ((line.Length - 1) <= index2))
            {
                throw Error.BatchStreamInvalidMethodHeaderSpecified(line);
            }

            string segment1 = line.Substring(0, index1);
            string segment2 = line.Substring(index1 + 1, index2 - index1 - 1);
            string segment3 = line.Substring(index2 + 1);

            #region validate HttpVersion
            string httpVersion = this.batchRequest ? segment3 : segment1;
            if (httpVersion != XmlConstants.HttpVersionInBatching)
            {
                throw Error.BatchStreamInvalidHttpVersionSpecified(httpVersion, XmlConstants.HttpVersionInBatching);
            }
            #endregion

            this.ReadContentHeaders();

            BatchStreamState state;
            if (this.batchRequest)
            {
                state = GetStateBasedOnHttpMethodName(segment1);
#if ASTORIA_SERVER
                this.contentUri = segment2;
#endif
            }
            else
            {
                state = (BatchStreamState.EndBatch == this.batchState) ? BatchStreamState.GetResponse : BatchStreamState.ChangeResponse;
#if ASTORIA_CLIENT
                this.statusCode = segment2;
#endif
            }

            #region validate state change
            Debug.Assert(
                BatchStreamState.EndBatch == this.batchState ||
                BatchStreamState.EndChangeSet == this.batchState,
                "unexpected BatchStreamState");

            if (this.batchState == BatchStreamState.EndBatch)
            {
                if ((this.batchRequest && (state == BatchStreamState.Get)) ||
                    (!this.batchRequest && (state == BatchStreamState.GetResponse)))
                {
                    this.batchState = state;
                }
                else
                {
                    throw Error.BatchStreamOnlyGETOperationsCanBeSpecifiedInBatch();
                }
            }
            else if (this.batchState == BatchStreamState.EndChangeSet)
            {
                if ((this.batchRequest && ((BatchStreamState.Post == state) || (BatchStreamState.Put == state) || (BatchStreamState.Delete == state) || (BatchStreamState.Merge == state))) ||
                    (!this.batchRequest && (state == BatchStreamState.ChangeResponse)))
                {
                    this.batchState = state;
                }
                else
                {
                    this.batchState = BatchStreamState.Post;

                    throw Error.BatchStreamGetMethodNotSupportInChangeset();
                }
            }
            else
            {
                throw Error.BatchStreamInvalidOperationHeaderSpecified();
            }
            #endregion
        }
コード例 #8
0
        internal bool MoveNext()
        {
            // dispose previous content stream
            if (null == this.reader || this.disposeWithContentStreamDispose)
            {
                return false;
            }

            if (null != this.contentStream)
            {
                this.contentStream.Dispose();
            }

            Debug.Assert(0 <= this.byteLength, "negative byteLength");
            Debug.Assert(0 <= this.batchLength, "negative batchLength");

            // initialize start state to EndBatch or EndChangeSet
            switch (this.batchState)
            {
                case BatchStreamState.EndBatch:
                    Debug.Assert(null == this.batchBoundary, "non-null batch boundary");
                    Debug.Assert(null == this.changesetBoundary, "non-null changesetBoundary boundary");
                    throw Error.BatchStreamInvalidBatchFormat();

                case BatchStreamState.Get:
                case BatchStreamState.GetResponse:
                    this.ClearPreviousOperationInformation();
                    goto case BatchStreamState.StartBatch;

                case BatchStreamState.StartBatch:
                case BatchStreamState.EndChangeSet:
                    Debug.Assert(null != this.batchBoundary, "null batch boundary");
                    Debug.Assert(null == this.changesetBoundary, "non-null changeset boundary");
                    this.batchState = BatchStreamState.EndBatch;
                    this.batchLength = int.MaxValue;
                    break;

                case BatchStreamState.BeginChangeSet:
                    Debug.Assert(null != this.batchBoundary, "null batch boundary");
                    Debug.Assert(null != this.contentHeaders, "null contentHeaders");
                    Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                    this.contentHeaders = null;
                    this.changesetEncoding = null;
                    this.batchState = BatchStreamState.EndChangeSet;
                    break;

                case BatchStreamState.ChangeResponse:
                case BatchStreamState.Delete:
                    Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                    this.ClearPreviousOperationInformation();
                    this.batchState = BatchStreamState.EndChangeSet;
                    break;

                case BatchStreamState.Post:
                case BatchStreamState.Put:
                case BatchStreamState.Merge:
                    Debug.Assert(null != this.changesetBoundary, "null changeset boundary");
                    this.batchState = BatchStreamState.EndChangeSet;
                    break;

                default:
                    Debug.Assert(false, "unknown state");
                    throw Error.BatchStreamInvalidBatchFormat();
            }

            Debug.Assert(null == this.contentHeaders, "non-null content headers");
            Debug.Assert(null == this.contentStream, "non-null content stream");
            Debug.Assert(null == this.statusCode, "non-null statusCode");
            Debug.Assert(
                this.batchState == BatchStreamState.EndBatch ||
                this.batchState == BatchStreamState.EndChangeSet,
                "unexpected state at start");

            // read --delimiter
            string delimiter = this.ReadLine();
            if (string.IsNullOrEmpty(delimiter))
            {   
                delimiter = this.ReadLine();
            }

            if (string.IsNullOrEmpty(delimiter))
            {
                throw Error.BatchStreamInvalidBatchFormat();
            }

            if (delimiter.EndsWith("--", StringComparison.Ordinal))
            {
                delimiter = delimiter.Substring(0, delimiter.Length - 2);

                if ((null != this.changesetBoundary) && (delimiter == this.changesetBoundary))
                {
                    Debug.Assert(this.batchState == BatchStreamState.EndChangeSet, "bad changeset boundary state");

                    this.changesetBoundary = null;
                    return true;
                }
                else if (delimiter == this.batchBoundary)
                {
                    if (BatchStreamState.EndChangeSet == this.batchState)
                    {   
                        throw Error.BatchStreamMissingEndChangesetDelimiter();
                    }

                    this.changesetBoundary = null;
                    this.batchBoundary = null;
                    if (this.byteLength != 0)
                    {
                        throw Error.BatchStreamMoreDataAfterEndOfBatch();
                    }

                    return false;
                }
                else
                {
                    throw Error.BatchStreamInvalidDelimiter(delimiter);
                }
            }
            else if ((null != this.changesetBoundary) && (delimiter == this.changesetBoundary))
            {
                Debug.Assert(this.batchState == BatchStreamState.EndChangeSet, "bad changeset boundary state");
            }
            else if (delimiter == this.batchBoundary)
            {
                if (this.batchState != BatchStreamState.EndBatch)
                {
                    if (this.batchState == BatchStreamState.EndChangeSet)
                    {   
                        throw Error.BatchStreamMissingEndChangesetDelimiter();
                    }
                    else
                    {
                        throw Error.BatchStreamInvalidBatchFormat();
                    }
                }
            }
            else
            {   
                throw Error.BatchStreamInvalidDelimiter(delimiter);
            }

            // read header with values in this form (([^:]*:.*)\r\n)*\r\n
            this.ReadContentHeaders();

            // should start changeset?
            string contentType;
            bool readHttpHeaders = false;
            if (this.contentHeaders.TryGetValue(XmlConstants.HttpContentType, out contentType))
            {
                if (string.Equals(contentType, XmlConstants.MimeApplicationHttp, StringComparison.OrdinalIgnoreCase))
                {
                    if (this.contentHeaders.Count != 2)
                    {
                        throw Error.BatchStreamInvalidNumberOfHeadersAtOperationStart(
                            XmlConstants.HttpContentType,
                            XmlConstants.HttpContentTransferEncoding);
                    }

                    string transferEncoding;
                    if (!this.contentHeaders.TryGetValue(XmlConstants.HttpContentTransferEncoding, out transferEncoding) ||
                        XmlConstants.BatchRequestContentTransferEncoding != transferEncoding)
                    {
                        throw Error.BatchStreamMissingOrInvalidContentEncodingHeader(
                            XmlConstants.HttpContentTransferEncoding,
                            XmlConstants.BatchRequestContentTransferEncoding);
                    }

                    readHttpHeaders = true;
                }
                else if (BatchStreamState.EndBatch == this.batchState)
                {
                    string boundary;
                    Encoding encoding;
                    if (GetBoundaryAndEncodingFromMultipartMixedContentType(contentType, out boundary, out encoding))
                    {
                        this.changesetBoundary = VerifyBoundary(boundary);
                        this.changesetEncoding = encoding;
                        this.batchState = BatchStreamState.BeginChangeSet;
                    }
                    else
                    {
                        throw Error.BatchStreamInvalidContentTypeSpecified(
                            XmlConstants.HttpContentType,
                            contentType,
                            XmlConstants.MimeApplicationHttp,
                            XmlConstants.MimeMultiPartMixed);
                    }

                    if (this.contentHeaders.Count > 2 ||
                        (this.contentHeaders.Count == 2 && !this.contentHeaders.ContainsKey(XmlConstants.HttpContentLength)))
                    {
                        throw Error.BatchStreamInvalidNumberOfHeadersAtChangeSetStart(XmlConstants.HttpContentType, XmlConstants.HttpContentLength);
                    }
                }
                else
                {
                    throw Error.BatchStreamInvalidContentTypeSpecified(
                        XmlConstants.HttpContentType,
                        contentType,
                        XmlConstants.MimeApplicationHttp,
                        XmlConstants.MimeMultiPartMixed);
                }
            }
            else
            {
                throw Error.BatchStreamMissingContentTypeHeader(XmlConstants.HttpContentType);
            }

            // what is the operation and uri?
            if (readHttpHeaders)
            {
                this.ReadHttpHeaders();

                this.contentHeaders.TryGetValue(XmlConstants.HttpContentType, out contentType);
            }

            // does content have a fixed length?
            string text = null;
            int length = -1;
            if (this.contentHeaders.TryGetValue(XmlConstants.HttpContentLength, out text))
            {
                length = int.Parse(text, CultureInfo.InvariantCulture);
                if (length < 0)
                {
                    throw Error.BatchStreamInvalidContentLengthSpecified(text);
                }

                if (this.batchState == BatchStreamState.BeginChangeSet)
                {
                    this.batchLength = length;
                }
                else if (length != 0)
                {
                    Debug.Assert(
                        this.batchState == BatchStreamState.Delete ||
                        this.batchState == BatchStreamState.Get ||
                        this.batchState == BatchStreamState.Post ||
                        this.batchState == BatchStreamState.Put ||
                        this.batchState == BatchStreamState.Merge,
                        "unexpected contentlength location");
                    this.contentStream = new StreamWithLength(this, length);
                }
            }
            else
            {
                if (this.batchState == BatchStreamState.EndBatch)
                {
                    this.batchLength = int.MaxValue;
                }

                if (this.batchState != BatchStreamState.BeginChangeSet)
                {
                    this.contentStream = new StreamWithDelimiter(this);
                }
            }

            Debug.Assert(
                this.batchState == BatchStreamState.BeginChangeSet ||
                (this.batchRequest && (this.batchState == BatchStreamState.Delete ||
                                       this.batchState == BatchStreamState.Get ||
                                       this.batchState == BatchStreamState.Post ||
                                       this.batchState == BatchStreamState.Put ||
                                       this.batchState == BatchStreamState.Merge)) ||
                (!this.batchRequest && (this.batchState == BatchStreamState.GetResponse ||
                                        this.batchState == BatchStreamState.ChangeResponse)),
                "unexpected state at return");

            // enforce if contentStream is expected, caller needs to enforce if contentStream is not expected
            if (null == this.contentStream)
            {
                switch (this.batchState)
                {
                    case BatchStreamState.BeginChangeSet:
                    case BatchStreamState.Delete:
                    case BatchStreamState.Get:
                    case BatchStreamState.ChangeResponse:   
                    case BatchStreamState.GetResponse:      
                        break;

                    case BatchStreamState.Post:
                    case BatchStreamState.Put:
                    case BatchStreamState.Merge:
                    default:
                        throw Error.BatchStreamContentExpected(this.batchState);
                }
            }

            // enforce if contentType not is expected, caller needs to enforce if contentType is expected
            if (!string.IsNullOrEmpty(contentType))
            {
                switch (this.batchState)
                {
                    case BatchStreamState.BeginChangeSet:
                    case BatchStreamState.Post:
                    case BatchStreamState.Put:
                    case BatchStreamState.Merge:
                    case BatchStreamState.GetResponse:
                    case BatchStreamState.ChangeResponse:
                        break;

                    case BatchStreamState.Get:
                    case BatchStreamState.Delete:
                    default:
                        throw Error.BatchStreamContentUnexpected(this.batchState);
                }
            }

            return true;
        }
コード例 #9
0
        private void ReadHttpHeaders()
        {
            string line = this.ReadLine();

            int index1 = line.IndexOf(' ');
            if ((index1 <= 0) || ((line.Length - 3) <= index1))
            {
                throw Error.BatchStreamInvalidMethodHeaderSpecified(line);
            }

            int index2 = this.batchRequest ? line.LastIndexOf(' ') : line.IndexOf(' ', index1 + 1);
            if ((index2 < 0) || (index2 - index1 - 1 <= 0) || ((line.Length - 1) <= index2))
            {
                throw Error.BatchStreamInvalidMethodHeaderSpecified(line);
            }

            string segment1 = line.Substring(0, index1);                        
            string segment2 = line.Substring(index1 + 1, index2 - index1 - 1);  
            string segment3 = line.Substring(index2 + 1);                       

            string httpVersion = this.batchRequest ? segment3 : segment1;
            if (httpVersion != XmlConstants.HttpVersionInBatching)
            {
                throw Error.BatchStreamInvalidHttpVersionSpecified(httpVersion, XmlConstants.HttpVersionInBatching);
            }

            this.ReadContentHeaders();

            BatchStreamState state;
            if (this.batchRequest)
            {
                state = GetStateBasedOnHttpMethodName(segment1);
            }
            else
            {
                state = (BatchStreamState.EndBatch == this.batchState) ? BatchStreamState.GetResponse : BatchStreamState.ChangeResponse;
                this.statusCode = segment2;
            }

            Debug.Assert(
                BatchStreamState.EndBatch == this.batchState ||
                BatchStreamState.EndChangeSet == this.batchState,
                "unexpected BatchStreamState");

            if (this.batchState == BatchStreamState.EndBatch)
            {
                if ((this.batchRequest && (state == BatchStreamState.Get)) ||
                    (!this.batchRequest && (state == BatchStreamState.GetResponse)))
                {
                    this.batchState = state;
                }
                else
                {
                    throw Error.BatchStreamOnlyGETOperationsCanBeSpecifiedInBatch();
                }
            }
            else if (this.batchState == BatchStreamState.EndChangeSet)
            {
                if ((this.batchRequest && ((BatchStreamState.Post == state) || (BatchStreamState.Put == state) || (BatchStreamState.Delete == state) || (BatchStreamState.Merge == state))) ||
                    (!this.batchRequest && (state == BatchStreamState.ChangeResponse)))
                {
                    this.batchState = state;
                }
                else
                {
                    this.batchState = BatchStreamState.Post;

                    throw Error.BatchStreamGetMethodNotSupportInChangeset();
                }
            }
            else
            {   
                throw Error.BatchStreamInvalidOperationHeaderSpecified();
            }
        }
コード例 #10
0
ファイル: Error.cs プロジェクト: dox0/DotNet471RS3
 /// <summary>create exception when unexpected content is discovered</summary>
 /// <param name="state">http method operation</param>
 /// <returns>exception to throw</returns>
 internal static DataServiceException BatchStreamContentUnexpected(BatchStreamState state)
 {
     return(Trace(DataServiceException.CreateBadRequestError(Strings.BatchStream_ContentUnexpected(state.ToString()))));
 }