/// <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); }
/// <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."); }
/// <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); }