Skip to content

Commit

Permalink
Adding a null check for reading Content from a response as a string (A…
Browse files Browse the repository at this point in the history
…zure#1170)

* Adding a null check for HttpContent when there is no default specified in the response section

* Adding test coverage for the scenario where no default is included in responses and the server returns an empty response

* Regenerating C# expected files
  • Loading branch information
tbombach committed Jun 21, 2016
1 parent 64a7b86 commit 4aaef63
Show file tree
Hide file tree
Showing 19 changed files with 700 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,12 @@ public async Task<AzureOperationResponse> GetWithHttpMessagesAsync(Dictionary<st
if ((int)_statusCode != 200)
{
var ex = new CloudException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_httpResponse.Headers.Contains("x-ms-request-id"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ public async Task<AzureOperationResponse> Head200WithHttpMessagesAsync(Dictionar
if ((int)_statusCode != 200)
{
var ex = new CloudException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_httpResponse.Headers.Contains("x-ms-request-id"))
Expand Down Expand Up @@ -264,7 +269,12 @@ public async Task<AzureOperationResponse> Head204WithHttpMessagesAsync(Dictionar
if ((int)_statusCode != 204)
{
var ex = new CloudException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_httpResponse.Headers.Contains("x-ms-request-id"))
Expand Down Expand Up @@ -387,7 +397,12 @@ public async Task<AzureOperationResponse> Head404WithHttpMessagesAsync(Dictionar
if ((int)_statusCode != 204)
{
var ex = new CloudException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_httpResponse.Headers.Contains("x-ms-request-id"))
Expand Down
3 changes: 3 additions & 0 deletions AutoRest/Generators/CSharp/CSharp.Tests/AcceptanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1807,6 +1807,9 @@ private static void TestSuccessStatusCodes(AutoRestHttpInfrastructureTestService
var ex2 = Assert.Throws<HttpOperationException>(() => client.HttpFailure.GetNoModelError());
Assert.Equal("{\"message\":\"NoErrorModel\",\"status\":400}", ex2.Response.Content);

var ex3 = Assert.Throws<HttpOperationException>(() => client.HttpFailure.GetNoModelEmpty());
Assert.Equal(string.Empty, ex3.Response.Content);

client.HttpSuccess.Head200();
Assert.True(client.HttpSuccess.Get200());
client.HttpSuccess.Put200(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,130 @@ public HttpFailure(AutoRestHttpInfrastructureTestService client)
if ((int)_statusCode != 200)
{
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_shouldTrace)
{
ServiceClientTracing.Error(_invocationId, ex);
}
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw ex;
}
// Create Result
var _result = new HttpOperationResponse<bool?>();
_result.Request = _httpRequest;
_result.Response = _httpResponse;
// Deserialize Response
if ((int)_statusCode == 200)
{
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
try
{
_result.Body = SafeJsonConvert.DeserializeObject<bool?>(_responseContent, this.Client.DeserializationSettings);
}
catch (JsonException ex)
{
_httpRequest.Dispose();
if (_httpResponse != null)
{
_httpResponse.Dispose();
}
throw new SerializationException("Unable to deserialize the response.", _responseContent, ex);
}
}
if (_shouldTrace)
{
ServiceClientTracing.Exit(_invocationId, _result);
}
return _result;
}

/// <summary>
/// Get empty response from server
/// </summary>
/// <param name='customHeaders'>
/// Headers that will be added to request.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
/// <exception cref="HttpOperationException">
/// Thrown when the operation returned an invalid status code
/// </exception>
/// <exception cref="SerializationException">
/// Thrown when unable to deserialize the response
/// </exception>
/// <return>
/// A response object containing the response body and response headers.
/// </return>
public async Task<HttpOperationResponse<bool?>> GetNoModelEmptyWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
{
// Tracing
bool _shouldTrace = ServiceClientTracing.IsEnabled;
string _invocationId = null;
if (_shouldTrace)
{
_invocationId = ServiceClientTracing.NextInvocationId.ToString();
Dictionary<string, object> tracingParameters = new Dictionary<string, object>();
tracingParameters.Add("cancellationToken", cancellationToken);
ServiceClientTracing.Enter(_invocationId, this, "GetNoModelEmpty", tracingParameters);
}
// Construct URL
var _baseUrl = this.Client.BaseUri.AbsoluteUri;
var _url = new Uri(new Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), "http/failure/nomodel/empty").ToString();
// Create HTTP transport objects
HttpRequestMessage _httpRequest = new HttpRequestMessage();
HttpResponseMessage _httpResponse = null;
_httpRequest.Method = new HttpMethod("GET");
_httpRequest.RequestUri = new Uri(_url);
// Set Headers
if (customHeaders != null)
{
foreach(var _header in customHeaders)
{
if (_httpRequest.Headers.Contains(_header.Key))
{
_httpRequest.Headers.Remove(_header.Key);
}
_httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
}
}

// Serialize Request
string _requestContent = null;
// Send Request
if (_shouldTrace)
{
ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
}
cancellationToken.ThrowIfCancellationRequested();
_httpResponse = await this.Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
if (_shouldTrace)
{
ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
}
HttpStatusCode _statusCode = _httpResponse.StatusCode;
cancellationToken.ThrowIfCancellationRequested();
string _responseContent = null;
if ((int)_statusCode != 200)
{
var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
if (_httpResponse.Content != null) {
_responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}
else {
_responseContent = string.Empty;
}
ex.Request = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
if (_shouldTrace)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,33 @@ public static partial class HttpFailureExtensions
}
}

/// <summary>
/// Get empty response from server
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
public static bool? GetNoModelEmpty(this IHttpFailure operations)
{
return Task.Factory.StartNew(s => ((IHttpFailure)s).GetNoModelEmptyAsync(), operations, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap().GetAwaiter().GetResult();
}

/// <summary>
/// Get empty response from server
/// </summary>
/// <param name='operations'>
/// The operations group for this extension method.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
public static async Task<bool?> GetNoModelEmptyAsync(this IHttpFailure operations, CancellationToken cancellationToken = default(CancellationToken))
{
using (var _result = await operations.GetNoModelEmptyWithHttpMessagesAsync(null, cancellationToken).ConfigureAwait(false))
{
return _result.Body;
}
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,21 @@ public partial interface IHttpFailure
/// Thrown when unable to deserialize the response
/// </exception>
Task<HttpOperationResponse<bool?>> GetNoModelErrorWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
/// <summary>
/// Get empty response from server
/// </summary>
/// <param name='customHeaders'>
/// The headers that will be added to request.
/// </param>
/// <param name='cancellationToken'>
/// The cancellation token.
/// </param>
/// <exception cref="HttpOperationException">
/// Thrown when the operation returned an invalid status code
/// </exception>
/// <exception cref="SerializationException">
/// Thrown when unable to deserialize the response
/// </exception>
Task<HttpOperationResponse<bool?>> GetNoModelEmptyWithHttpMessagesAsync(Dictionary<string, List<string>> customHeaders = null, CancellationToken cancellationToken = default(CancellationToken));
}
}
Loading

0 comments on commit 4aaef63

Please sign in to comment.