예제 #1
0
        /// <summary>
        /// Validates the headers that have been read for a part.
        /// </summary>
        /// <param name="headers">The set of headers to validate.</param>
        /// <param name="isChangeSetPart">true if the headers indicate a changset part; otherwise false.</param>
        /// <returns>The set of validated headers.</returns>
        /// <remarks>
        /// An operation part is required to have content type 'application/http' and content transfer
        /// encoding 'binary'. A changeset is required to have content type 'multipart/mixed'.
        /// Note that we allow additional headers for batch parts; clients of the library can choose
        /// to be more strict.
        /// </remarks>
        private ODataBatchOperationHeaders ValidatePartHeaders(ODataBatchOperationHeaders headers, out bool isChangeSetPart)
        {
            string contentType;

            if (!headers.TryGetValue(ODataConstants.ContentTypeHeader, out contentType))
            {
                throw new ODataException(Strings.ODataBatchReaderStream_MissingContentTypeHeader);
            }

            if (MediaTypeUtils.MediaTypeAndSubtypeAreEqual(contentType, MimeConstants.MimeApplicationHttp))
            {
                isChangeSetPart = false;

                // An operation part is required to have application/http content type and
                // binary content transfer encoding.
                string transferEncoding;
                if (!headers.TryGetValue(ODataConstants.ContentTransferEncoding, out transferEncoding) ||
                    string.Compare(transferEncoding, ODataConstants.BatchContentTransferEncoding, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    throw new ODataException(Strings.ODataBatchReaderStream_MissingOrInvalidContentEncodingHeader(
                                                 ODataConstants.ContentTransferEncoding,
                                                 ODataConstants.BatchContentTransferEncoding));
                }
            }
            else if (MediaTypeUtils.MediaTypeStartsWithTypeAndSubtype(contentType, MimeConstants.MimeMultipartMixed))
            {
                isChangeSetPart = true;

                if (this.changesetBoundary != null)
                {
                    // Nested changesets are not supported
                    throw new ODataException(Strings.ODataBatchReaderStream_NestedChangesetsAreNotSupported);
                }
            }
            else
            {
                throw new ODataException(Strings.ODataBatchReaderStream_InvalidContentTypeSpecified(
                                             ODataConstants.ContentTypeHeader,
                                             contentType,
                                             MimeConstants.MimeMultipartMixed,
                                             MimeConstants.MimeApplicationHttp));
            }

            return(headers);
        }
예제 #2
0
        /// <summary>
        /// Parse the content type header value to retrieve the boundary and encoding of a changeset.
        /// </summary>
        /// <param name="contentType">The content type to parse.</param>
        private void DetermineChangesetBoundaryAndEncoding(string contentType)
        {
            Debug.Assert(!string.IsNullOrEmpty(contentType), "Should have validated that non-null, non-empty content type header exists.");

            ODataMediaType   mediaType;
            ODataPayloadKind readerPayloadKind;

            MediaTypeUtils.GetFormatFromContentType(
                contentType,
                new ODataPayloadKind[] { ODataPayloadKind.Batch },
                this.mediaTypeResolver,
                out mediaType,
                out this.changesetEncoding,
                out readerPayloadKind,
                out this.changesetBoundary);
            Debug.Assert(readerPayloadKind == ODataPayloadKind.Batch, "Must find batch payload kind.");
            Debug.Assert(this.changesetBoundary != null && this.changesetBoundary.Length > 0, "Boundary string should have been validated by now.");
            Debug.Assert(HttpUtils.CompareMediaTypeNames(MimeConstants.MimeMultipartMixed, mediaType.FullTypeName), "Must be multipart/mixed media type.");
        }
예제 #3
0
        /// <summary>Reads a Content-Type header and extracts the media type's name (type/subtype) and parameters.</summary>
        /// <param name="contentType">The Content-Type header.</param>
        /// <param name="mediaTypeName">The media type in standard type/subtype form, without parameters.</param>
        /// <param name="mediaTypeCharset">The (optional) charset parameter of the media type.</param>
        /// <returns>The parameters of the media type not including the 'charset' parameter.</returns>
        internal static IList <KeyValuePair <string, string> > ReadMimeType(string contentType, out string mediaTypeName, out string mediaTypeCharset)
        {
            if (String.IsNullOrEmpty(contentType))
            {
                throw new ODataContentTypeException(Strings.HttpUtils_ContentTypeMissing);
            }

            IList <KeyValuePair <ODataMediaType, string> > mediaTypes = ReadMediaTypes(contentType);

            if (mediaTypes.Count != 1)
            {
                throw new ODataContentTypeException(Strings.HttpUtils_NoOrMoreThanOneContentTypeSpecified(contentType));
            }

            ODataMediaType mediaType = mediaTypes[0].Key;

            MediaTypeUtils.CheckMediaTypeForWildCards(mediaType);

            mediaTypeName    = mediaType.FullTypeName;
            mediaTypeCharset = mediaTypes[0].Value;

            return(mediaType.Parameters != null?mediaType.Parameters.ToList() : null);
        }