Skip to content

Commit

Permalink
Fixed NullReferenceException in TopicController and MessageJournalCon…
Browse files Browse the repository at this point in the history
…troller caused by null content encoding in responses when using HttpServer or self-hosted OWIN middleware.
  • Loading branch information
sweetlandj committed Jun 16, 2017
1 parent af8b1a1 commit 4046ab8
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
using System;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Platibus.Http;
using Platibus.Http.Clients;
using Platibus.Serialization;
using Xunit;
Expand All @@ -33,11 +35,27 @@ namespace Platibus.IntegrationTests.HttpServer
[Collection(HttpServerCollection.Name)]
public class HttpServerPubSubTests : PubSubTests
{
private readonly HttpClientPool _httpClientPool = new HttpClientPool();

public HttpServerPubSubTests(HttpServerFixture fixture)
: base(fixture.Sender, fixture.Receiver)
{
}

protected override void Dispose(bool disposing)
{
if (disposing)
{
_httpClientPool.TryDispose();
}
base.Dispose(disposing);
}

[Fact]
public async Task TopicsCanBeQueriedOverHttp()
{
await AssertTopicsCanBeRetrievedByHttpClient();
}

[Fact]
public async Task MessageJournalCanBeQueriedOverHttp()
Expand All @@ -60,6 +78,18 @@ protected async Task AssertMessageRetrievedByMessageJournalClient()
Assert.Contains(Publication, messageContent);
}

protected async Task AssertTopicsCanBeRetrievedByHttpClient()
{
// From the platibus.http0 configuration section of app.config
var publisherBaseUri = new Uri("http://localhost:52180/platibus0/");
var httpClient = await _httpClientPool.GetClient(publisherBaseUri, null);
var responseMessage = await httpClient.GetAsync("topic");
Assert.True(responseMessage.IsSuccessStatusCode, "HTTP Status " + responseMessage.StatusCode + " " + responseMessage.ReasonPhrase);
var responseContent = await responseMessage.Content.ReadAsStringAsync();
var topicArray = JsonConvert.DeserializeObject<string[]>(responseContent);
Assert.Contains((string)Topic, topicArray);
}

private static object DeserializeMessageContent(Message message)
{
var messageNamingService = new DefaultMessageNamingService();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

using System;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Platibus.Http;
using Platibus.Http.Clients;
using Platibus.Serialization;
using Xunit;

namespace Platibus.IntegrationTests.OwinMiddleware
Expand All @@ -28,9 +35,60 @@ namespace Platibus.IntegrationTests.OwinMiddleware
[Collection(OwinMiddlewareCollection.Name)]
public class OwinMiddlewarePubSubTests : PubSubTests
{
private readonly HttpClientPool _httpClientPool = new HttpClientPool();

public OwinMiddlewarePubSubTests(OwinMiddlewareFixture fixture)
: base(fixture.Sender, fixture.Receiver)
{
}

[Fact]
public async Task TopicsCanBeQueriedOverHttp()
{
await AssertTopicsCanBeRetrievedByHttpClient();
}

[Fact]
public async Task MessageJournalCanBeQueriedOverHttp()
{
GivenTestPublication();
await WhenPublished();
await AssertMessageRetrievedByMessageJournalClient();
}

protected async Task AssertMessageRetrievedByMessageJournalClient()
{
// From the platibus.owin0 configuration section of app.config
var publisherBaseUri = new Uri("http://localhost:52182/platibus0/");
var messageJournalClient = new HttpMessageJournalClient(publisherBaseUri);
var result = await messageJournalClient.Read(null, 100);
Assert.NotNull(result);

var messages = result.Entries.Select(e => e.Data);
var messageContent = messages.Select(DeserializeMessageContent);
Assert.Contains(Publication, messageContent);
}

protected async Task AssertTopicsCanBeRetrievedByHttpClient()
{
// From the platibus.owin0 configuration section of app.config
var publisherBaseUri = new Uri("http://localhost:52182/platibus0/");
var httpClient = await _httpClientPool.GetClient(publisherBaseUri, null);
var responseMessage = await httpClient.GetAsync("topic");
Assert.True(responseMessage.IsSuccessStatusCode, "HTTP Status " + responseMessage.StatusCode + " " + responseMessage.ReasonPhrase);
var responseContent = await responseMessage.Content.ReadAsStringAsync();
var topicArray = JsonConvert.DeserializeObject<string[]>(responseContent);
Assert.Contains((string)Topic, topicArray);
}

private static object DeserializeMessageContent(Message message)
{
var messageNamingService = new DefaultMessageNamingService();
var serializationService = new DefaultSerializationService();

var messageType = messageNamingService.GetTypeForName(message.Headers.MessageName);
var serializer = serializationService.GetSerializer(message.Headers.ContentType);
return serializer.Deserialize(message.Content, messageType);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@
<HintPath>..\packages\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.InteropServices.RuntimeInformation.4.0.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
<Private>True</Private>
Expand Down
1 change: 1 addition & 0 deletions Source/Platibus.IntegrationTests/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ THE SOFTWARE.
<platibus.owin0 baseUri="http://localhost:52182/platibus0" replyTimeout="00:00:30">
<queueing provider="SQLite" path="platibus2\queues" />
<subscriptionTracking provider="Filesystem" path="platibus.owin0\subscriptions" />
<journaling provider="SQLite" path="platibus.owin0\journal" />
<endpoints>
<add name="platibus1" address="http://localhost:52182/platibus1" />
</endpoints>
Expand Down
33 changes: 27 additions & 6 deletions Source/Platibus.Owin/OwinResponseAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ namespace Platibus.Owin
internal class OwinResponseAdapter : IHttpResourceResponse
{
private readonly IOwinResponse _response;
private readonly ContentType _contentType;
private ContentType _contentType;
private Encoding _contentEncoding;

public int StatusCode
{
Expand All @@ -45,17 +46,36 @@ public string StatusDescription

public string ContentType
{
get { return _response.ContentType; }
set { _response.ContentType = value; }
get { return _contentType == null ? null : _contentType.Type; }
set
{
if (value == null)
{
_contentType = null;
_contentEncoding = null;
return;
}

_contentType = value;
if (_contentEncoding != null)
{
_contentType.CharsetEncoding = _contentEncoding;
}
_response.ContentType = _contentType.ToString();
}
}

public Encoding ContentEncoding
{
get { return _contentType.CharsetEncoding; }
get { return _contentEncoding; }
set
{
_contentType.CharsetEncoding = value;
_response.ContentType = _contentType;
_contentEncoding = value;
if (_contentType != null)
{
_contentType.CharsetEncoding = value;
_response.ContentType = _contentType;
}
}
}

Expand All @@ -69,6 +89,7 @@ public OwinResponseAdapter(IOwinResponse response)
if (response == null) throw new ArgumentNullException("response");
_response = response;
_contentType = response.ContentType;
_contentEncoding = _contentType == null ? null : _contentType.CharsetEncoding;
}

public void AddHeader(string header, string value)
Expand Down
3 changes: 2 additions & 1 deletion Source/Platibus/Http/Controllers/JournalController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,14 @@ private async Task Get(IHttpResourceRequest request, IHttpResourceResponse respo
}

response.ContentType = "application/json";
var serializedContent = _serializer.Serialize(responseModel);
var encoding = response.ContentEncoding;
if (encoding == null)
{
encoding = Encoding.UTF8;
response.ContentEncoding = encoding;
}

var serializedContent = _serializer.Serialize(responseModel);
var encodedContent = encoding.GetBytes(serializedContent);
await response.OutputStream.WriteAsync(encodedContent, 0, encodedContent.Length);
}
Expand Down
10 changes: 9 additions & 1 deletion Source/Platibus/Http/Controllers/TopicController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Platibus.Security;
using Platibus.Serialization;
Expand Down Expand Up @@ -97,9 +98,16 @@ public async Task Process(IHttpResourceRequest request, IHttpResourceResponse re

private async Task GetTopics(IHttpResourceResponse response)
{
response.ContentType = "application/json";
var encoding = response.ContentEncoding;
if (encoding == null)
{
encoding = Encoding.UTF8;
response.ContentEncoding = encoding;
}

var topicList = _topics.Select(t => t.ToString()).ToArray();
var responseContent = _serializer.Serialize(topicList);
var encoding = response.ContentEncoding;
var encodedContent = encoding.GetBytes(responseContent);
await response.OutputStream.WriteAsync(encodedContent, 0, encodedContent.Length);
response.StatusCode = 200;
Expand Down

0 comments on commit 4046ab8

Please sign in to comment.