// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Net.Http.Headers;
namespace System.Net.Http
{
///
/// Extension methods to provide convenience methods for finding items
/// within a collection.
///
[EditorBrowsable(EditorBrowsableState.Never)]
public static class HttpContentCollectionExtensions
{
private const string ContentID = @"Content-ID";
///
/// Returns the first in a sequence that has a header field
/// with a property equal to .
///
/// The contents to evaluate
/// The disposition type to look for.
/// The first in the sequence with a matching disposition type.
public static HttpContent FirstDispositionType(this IEnumerable contents, string dispositionType)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(dispositionType))
{
throw new ArgumentNullException("dispositionType");
}
return contents.First((item) =>
{
return HttpContentCollectionExtensions.FirstDispositionType(item, dispositionType);
});
}
///
/// Returns the first in a sequence that has a header field
/// with a property equal to .
///
/// The contents to evaluate
/// The disposition type to look for.
/// null if source is empty or if no element matches; otherwise the first in
/// the sequence with a matching disposition type.
public static HttpContent FirstDispositionTypeOrDefault(this IEnumerable contents, string dispositionType)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(dispositionType))
{
throw new ArgumentNullException("dispositionType");
}
return contents.FirstOrDefault((item) =>
{
return HttpContentCollectionExtensions.FirstDispositionType(item, dispositionType);
});
}
///
/// Returns the first in a sequence that has a header field
/// with a property equal to .
///
/// The contents to evaluate
/// The disposition name to look for.
/// The first in the sequence with a matching disposition name.
public static HttpContent FirstDispositionName(this IEnumerable contents, string dispositionName)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(dispositionName))
{
throw new ArgumentNullException("dispositionName");
}
return contents.First((item) =>
{
return HttpContentCollectionExtensions.FirstDispositionName(item, dispositionName);
});
}
///
/// Returns the first in a sequence that has a header field
/// with a property equal to .
///
/// The contents to evaluate
/// The disposition name to look for.
/// null if source is empty or if no element matches; otherwise the first in
/// the sequence with a matching disposition name.
public static HttpContent FirstDispositionNameOrDefault(this IEnumerable contents, string dispositionName)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(dispositionName))
{
throw new ArgumentNullException("dispositionName");
}
return contents.FirstOrDefault((item) =>
{
return HttpContentCollectionExtensions.FirstDispositionName(item, dispositionName);
});
}
///
/// Returns the start multipart body part. The start is used to identify the main body
/// in multipart/related content (see RFC 2387).
///
/// The contents to evaluate.
/// The start value to look for.
/// A match is found if a has a Content-ID
/// header field with the given value.
/// The first in the sequence with a matching value.
public static HttpContent FirstStart(this IEnumerable contents, string start)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(start))
{
throw new ArgumentNullException("start");
}
return contents.First((item) =>
{
return HttpContentCollectionExtensions.FirstStart(item, start);
});
}
///
/// Returns the first in a sequence that has a header field
/// parameter equal to . This parameter is typically used in connection with multipart/related
/// content (see RFC 2387).
///
/// The contents to evaluate.
/// The start value to look for. A match is found if a has a Content-ID
/// header field with the given value.
/// null if source is empty or if no element matches; otherwise the first in
/// the sequence with a matching value.
public static HttpContent FirstStartOrDefault(this IEnumerable contents, string start)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (String.IsNullOrWhiteSpace(start))
{
throw new ArgumentNullException("start");
}
return contents.FirstOrDefault((item) =>
{
return HttpContentCollectionExtensions.FirstStart(item, start);
});
}
///
/// Returns all instances of in a sequence that has a header field
/// with a property equal to the provided .
///
/// The content to evaluate
/// The media type to look for.
/// null if source is empty or if no element matches; otherwise the first in
/// the sequence with a matching media type.
public static IEnumerable FindAllContentType(this IEnumerable contents, string contentType)
{
if (String.IsNullOrWhiteSpace(contentType))
{
throw new ArgumentNullException("contentType");
}
return HttpContentCollectionExtensions.FindAllContentType(contents, new MediaTypeHeaderValue(contentType));
}
///
/// Returns all instances of in a sequence that has a header field
/// with a property equal to the provided .
///
/// The content to evaluate
/// The media type to look for.
/// null if source is empty or if no element matches; otherwise the first in
/// the sequence with a matching media type.
public static IEnumerable FindAllContentType(this IEnumerable contents, MediaTypeHeaderValue contentType)
{
if (contents == null)
{
throw new ArgumentNullException("contents");
}
if (contentType == null)
{
throw new ArgumentNullException("contentType");
}
return contents.Where((item) =>
{
return HttpContentCollectionExtensions.FindAllContentType(item, contentType);
});
}
private static bool FirstStart(HttpContent content, string start)
{
Contract.Assert(content != null, "content cannot be null");
Contract.Assert(start != null, "start cannot be null");
if (content.Headers != null)
{
IEnumerable values;
if (content.Headers.TryGetValues(ContentID, out values))
{
return String.Equals(
FormattingUtilities.UnquoteToken(values.ElementAt(0)),
FormattingUtilities.UnquoteToken(start),
StringComparison.OrdinalIgnoreCase);
}
}
return false;
}
private static bool FirstDispositionType(HttpContent content, string dispositionType)
{
Contract.Assert(content != null, "content cannot be null");
Contract.Assert(dispositionType != null, "dispositionType cannot be null");
return content.Headers != null && content.Headers.ContentDisposition != null &&
String.Equals(
FormattingUtilities.UnquoteToken(content.Headers.ContentDisposition.DispositionType),
FormattingUtilities.UnquoteToken(dispositionType),
StringComparison.OrdinalIgnoreCase);
}
private static bool FirstDispositionName(HttpContent content, string dispositionName)
{
Contract.Assert(content != null, "content cannot be null");
Contract.Assert(dispositionName != null, "dispositionName cannot be null");
return content.Headers != null && content.Headers.ContentDisposition != null &&
String.Equals(
FormattingUtilities.UnquoteToken(content.Headers.ContentDisposition.Name),
FormattingUtilities.UnquoteToken(dispositionName),
StringComparison.OrdinalIgnoreCase);
}
private static bool FindAllContentType(HttpContent content, MediaTypeHeaderValue contentType)
{
Contract.Assert(content != null, "content cannot be null");
Contract.Assert(contentType != null, "contentType cannot be null");
return content.Headers != null && content.Headers.ContentType != null &&
String.Equals(
content.Headers.ContentType.MediaType,
contentType.MediaType,
StringComparison.OrdinalIgnoreCase);
}
}
}