Merge remote-tracking branch 'upstream/master' into pr-495ext

Conflicts:
	Octokit/Octokit-MonoAndroid.csproj
	Octokit/Octokit-Monotouch.csproj
This commit is contained in:
Kristian Hald
2015-05-09 12:51:28 +02:00
54 changed files with 1489 additions and 199 deletions
+62
View File
@@ -199,6 +199,33 @@ namespace Octokit
return response.Body;
}
/// <summary>
/// Creates a new API resource in the list at the specified URI.
/// </summary>
/// <typeparam name="T">The API resource's type.</typeparam>
/// <param name="uri">URI of the API resource to get</param>
/// <param name="data">Object that describes the new API resource; this will be serialized and used as the request's body</param>
/// <param name="accepts">Accept header to use for the API request</param>
/// <param name="contentType">Content type of the API request</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Authentication Code</param>
/// <returns>The created API resource.</returns>
/// <exception cref="ApiException">Thrown when an API error occurs.</exception>
public async Task<T> Post<T>(Uri uri, object data, string accepts, string contentType, string twoFactorAuthenticationCode)
{
Ensure.ArgumentNotNull(uri, "uri");
Ensure.ArgumentNotNull(data, "data");
Ensure.ArgumentNotNull(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");
var response = await Connection.Post<T>(
uri,
data,
accepts,
contentType,
twoFactorAuthenticationCode).ConfigureAwait(false);
return response.Body;
}
public async Task<T> Post<T>(Uri uri, object data, string accepts, string contentType, TimeSpan timeout)
{
Ensure.ArgumentNotNull(uri, "uri");
@@ -345,6 +372,19 @@ namespace Octokit
return Connection.Delete(uri);
}
/// <summary>
/// Deletes the API object at the specified URI.
/// </summary>
/// <param name="uri">URI of the API resource to delete</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Code</param>
/// <returns>A <see cref="Task"/> for the request's execution.</returns>
public Task Delete(Uri uri, string twoFactorAuthenticationCode)
{
Ensure.ArgumentNotNull(uri, "uri");
return Connection.Delete(uri, twoFactorAuthenticationCode);
}
/// <summary>
/// Deletes the API object at the specified URI.
/// </summary>
@@ -359,6 +399,28 @@ namespace Octokit
return Connection.Delete(uri, data);
}
/// <summary>
/// Executes a GET to the API object at the specified URI. This operation is appropriate for
/// API calls which wants to return the redirect URL.
/// It expects the API to respond with a 302 Found.
/// </summary>
/// <param name="uri">URI of the API resource to get</param>
/// <returns>The URL returned by the API in the Location header</returns>
/// <exception cref="ApiException">Thrown when an API error occurs, or the API does not respond with a 302 Found</exception>
public async Task<string> GetRedirect(Uri uri)
{
Ensure.ArgumentNotNull(uri, "uri");
var response = await Connection.GetRedirect<string>(uri);
if (response.HttpResponse.StatusCode == HttpStatusCode.Redirect)
{
return response.HttpResponse.Headers["Location"];
}
throw new ApiException("Redirect Operation expect status code of Redirect.",
response.HttpResponse.StatusCode);
}
/// <summary>
/// Executes a GET to the API object at the specified URI. This operation is appropriate for
/// API calls which queue long running calculations.
+65 -3
View File
@@ -142,6 +142,24 @@ namespace Octokit
return SendData<T>(uri.ApplyParameters(parameters), HttpMethod.Get, null, accepts, null, CancellationToken.None);
}
/// <summary>
/// Performs an asynchronous HTTP GET request.
/// Attempts to map the response to an object of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type to map the response to</typeparam>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="parameters">Querystring parameters for the request</param>
/// <param name="accepts">Specifies accepted response media types.</param>
/// <param name="allowAutoRedirect">To follow redirect links automatically or not</param>
/// <returns><seealso cref="IResponse"/> representing the received HTTP response</returns>
public Task<IApiResponse<T>> Get<T>(Uri uri, IDictionary<string, string> parameters, string accepts, bool allowAutoRedirect)
{
Ensure.ArgumentNotNull(uri, "uri");
return SendData<T>(uri.ApplyParameters(parameters), HttpMethod.Get, null, accepts, null, CancellationToken.None, allowAutoRedirect: allowAutoRedirect);
}
public Task<IApiResponse<T>> Get<T>(Uri uri, IDictionary<string, string> parameters, string accepts, CancellationToken cancellationToken)
{
Ensure.ArgumentNotNull(uri, "uri");
@@ -205,6 +223,27 @@ namespace Octokit
return SendData<T>(uri, HttpMethod.Post, body, accepts, contentType, CancellationToken.None);
}
/// <summary>
/// Performs an asynchronous HTTP POST request.
/// Attempts to map the response body to an object of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type to map the response to</typeparam>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="body">The object to serialize as the body of the request</param>
/// <param name="accepts">Specifies accepted response media types.</param>
/// <param name="contentType">Specifies the media type of the request body</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Authentication Code</param>
/// <returns><seealso cref="IResponse"/> representing the received HTTP response</returns>
public Task<IApiResponse<T>> Post<T>(Uri uri, object body, string accepts, string contentType, string twoFactorAuthenticationCode)
{
Ensure.ArgumentNotNull(uri, "uri");
Ensure.ArgumentNotNull(body, "body");
Ensure.ArgumentNotNullOrEmptyString(twoFactorAuthenticationCode, "twoFactorAuthenticationCode");
return SendData<T>(uri, HttpMethod.Post, body, accepts, contentType, CancellationToken.None, twoFactorAuthenticationCode);
}
public Task<IApiResponse<T>> Post<T>(Uri uri, object body, string accepts, string contentType, TimeSpan timeout)
{
Ensure.ArgumentNotNull(uri, "uri");
@@ -281,7 +320,8 @@ namespace Octokit
string contentType,
CancellationToken cancellationToken,
string twoFactorAuthenticationCode = null,
Uri baseAddress = null)
Uri baseAddress = null,
bool allowAutoRedirect = true)
{
Ensure.ArgumentNotNull(uri, "uri");
@@ -290,6 +330,7 @@ namespace Octokit
Method = method,
BaseAddress = baseAddress ?? BaseAddress,
Endpoint = uri,
AllowAutoRedirect = allowAutoRedirect,
};
return SendDataInternal<T>(body, accepts, contentType, cancellationToken, twoFactorAuthenticationCode, request);
@@ -374,6 +415,27 @@ namespace Octokit
return response.HttpResponse.StatusCode;
}
/// <summary>
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
/// </summary>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Code</param>
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
public async Task<HttpStatusCode> Delete(Uri uri, string twoFactorAuthenticationCode)
{
Ensure.ArgumentNotNull(uri, "uri");
var response = await SendData<object>(
uri,
HttpMethod.Delete,
null,
null,
null,
CancellationToken.None,
twoFactorAuthenticationCode);
return response.HttpResponse.StatusCode;
}
/// <summary>
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
/// </summary>
@@ -502,9 +564,9 @@ namespace Octokit
: new ForbiddenException(response);
}
static TwoFactorType ParseTwoFactorType(IResponse restResponse)
internal static TwoFactorType ParseTwoFactorType(IResponse restResponse)
{
if (restResponse.Headers == null || !restResponse.Headers.Any()) return TwoFactorType.None;
if (restResponse == null || restResponse.Headers == null || !restResponse.Headers.Any()) return TwoFactorType.None;
var otpHeader = restResponse.Headers.FirstOrDefault(header =>
header.Key.Equals("X-GitHub-OTP", StringComparison.OrdinalIgnoreCase));
if (String.IsNullOrEmpty(otpHeader.Value)) return TwoFactorType.None;
+17 -10
View File
@@ -50,15 +50,21 @@ namespace Octokit.Internal
httpOptions.Proxy = _webProxy;
}
var http = new HttpClient(httpOptions)
var http = new HttpClient(httpOptions);
var cancellationTokenForRequest = cancellationToken;
if (request.Timeout != TimeSpan.Zero)
{
BaseAddress = request.BaseAddress,
Timeout = request.Timeout
};
var timeoutCancellation = new CancellationTokenSource(request.Timeout);
var unifiedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, timeoutCancellation.Token);
cancellationTokenForRequest = unifiedCancellationToken.Token;
}
using (var requestMessage = BuildRequestMessage(request))
{
// Make the request
var responseMessage = await http.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, cancellationToken)
var responseMessage = await http.SendAsync(requestMessage, HttpCompletionOption.ResponseContentRead, cancellationTokenForRequest)
.ConfigureAwait(false);
return await BuildResponse(responseMessage).ConfigureAwait(false);
}
@@ -76,14 +82,14 @@ namespace Octokit.Internal
{
contentType = GetContentMediaType(responseMessage.Content);
// We added support for downloading images. Let's constrain this appropriately.
if (contentType == null || !contentType.StartsWith("image/"))
// We added support for downloading images and zip-files. Let's constrain this appropriately.
if (contentType != null && (contentType.StartsWith("image/") || contentType.Equals("application/zip", StringComparison.OrdinalIgnoreCase)))
{
responseBody = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
responseBody = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
}
else
{
responseBody = await responseMessage.Content.ReadAsByteArrayAsync().ConfigureAwait(false);
responseBody = await responseMessage.Content.ReadAsStringAsync().ConfigureAwait(false);
}
}
}
@@ -101,7 +107,8 @@ namespace Octokit.Internal
HttpRequestMessage requestMessage = null;
try
{
requestMessage = new HttpRequestMessage(request.Method, request.Endpoint);
var fullUri = new Uri(request.BaseAddress, request.Endpoint);
requestMessage = new HttpRequestMessage(request.Method, fullUri);
foreach (var header in request.Headers)
{
requestMessage.Headers.Add(header.Key, header.Value);
+31
View File
@@ -123,6 +123,19 @@ namespace Octokit
/// <exception cref="ApiException">Thrown when an API error occurs.</exception>
Task<T> Post<T>(Uri uri, object data, string accepts, string contentType);
/// <summary>
/// Creates a new API resource in the list at the specified URI.
/// </summary>
/// <typeparam name="T">The API resource's type.</typeparam>
/// <param name="uri">URI of the API resource to get</param>
/// <param name="data">Object that describes the new API resource; this will be serialized and used as the request's body</param>
/// <param name="accepts">Accept header to use for the API request</param>
/// <param name="contentType">Content type of the API request</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Authentication Code</param>
/// <returns>The created API resource.</returns>
/// <exception cref="ApiException">Thrown when an API error occurs.</exception>
Task<T> Post<T>(Uri uri, object data, string accepts, string contentType, string twoFactorAuthenticationCode);
/// <summary>
/// Creates a new API resource in the list at the specified URI.
/// </summary>
@@ -212,6 +225,14 @@ namespace Octokit
/// <returns>A <see cref="Task"/> for the request's execution.</returns>
Task Delete(Uri uri);
/// <summary>
/// Deletes the API object at the specified URI.
/// </summary>
/// <param name="uri">URI of the API resource to delete</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Code</param>
/// <returns>A <see cref="Task"/> for the request's execution.</returns>
Task Delete(Uri uri, string twoFactorAuthenticationCode);
/// <summary>
/// Deletes the API object at the specified URI.
/// </summary>
@@ -220,6 +241,16 @@ namespace Octokit
/// <returns>A <see cref="Task"/> for the request's execution.</returns>
Task Delete(Uri uri, object data);
/// <summary>
/// Executes a GET to the API object at the specified URI. This operation is appropriate for
/// API calls which wants to return the redirect URL.
/// It expects the API to respond with a 302 Found.
/// </summary>
/// <param name="uri">URI of the API resource to get</param>
/// <returns>The URL returned by the API in the Location header</returns>
/// <exception cref="ApiException">Thrown when an API error occurs, or the API does not respond with a 302 Found</exception>
Task<string> GetRedirect(Uri uri);
/// <summary>
/// Executes a GET to the API object at the specified URI. This operation is appropriate for
/// API calls which queue long running calculations.
+34
View File
@@ -32,6 +32,19 @@ namespace Octokit
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")]
Task<IApiResponse<T>> Get<T>(Uri uri, IDictionary<string, string> parameters, string accepts);
/// <summary>
/// Performs an asynchronous HTTP GET request.
/// Attempts to map the response to an object of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type to map the response to</typeparam>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="parameters">Querystring parameters for the request</param>
/// <param name="accepts">Specifies accepted response media types.</param>
/// <param name="allowAutoRedirect">To follow redirect links automatically or not</param>
/// <returns><seealso cref="IResponse"/> representing the received HTTP response</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get")]
Task<IApiResponse<T>> Get<T>(Uri uri, IDictionary<string, string> parameters, string accepts, bool allowAutoRedirect);
/// <summary>
/// Performs an asynchronous HTTP GET request.
/// Attempts to map the response to an object of type <typeparamref name="T"/>
@@ -92,6 +105,19 @@ namespace Octokit
/// <returns><seealso cref="IResponse"/> representing the received HTTP response</returns>
Task<IApiResponse<T>> Post<T>(Uri uri, object body, string accepts, string contentType);
/// <summary>
/// Performs an asynchronous HTTP POST request.
/// Attempts to map the response body to an object of type <typeparamref name="T"/>
/// </summary>
/// <typeparam name="T">The type to map the response to</typeparam>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="body">The object to serialize as the body of the request</param>
/// <param name="accepts">Specifies accepted response media types.</param>
/// <param name="contentType">Specifies the media type of the request body</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Authentication Code</param>
/// <returns><seealso cref="IResponse"/> representing the received HTTP response</returns>
Task<IApiResponse<T>> Post<T>(Uri uri, object body, string accepts, string contentType, string twoFactorAuthenticationCode);
/// <summary>
/// Performs an asynchronous HTTP POST request.
/// Attempts to map the response body to an object of type <typeparamref name="T"/>
@@ -171,6 +197,14 @@ namespace Octokit
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
Task<HttpStatusCode> Delete(Uri uri);
/// <summary>
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
/// </summary>
/// <param name="uri">URI endpoint to send request to</param>
/// <param name="twoFactorAuthenticationCode">Two Factor Code</param>
/// <returns>The returned <seealso cref="HttpStatusCode"/></returns>
Task<HttpStatusCode> Delete(Uri uri, string twoFactorAuthenticationCode);
/// <summary>
/// Performs an asynchronous HTTP DELETE request that expects an empty response.
/// </summary>