fixed a bug where getting invalid parameter error if sending a steam content with no stream, now we try convert to byte array which the c# http client is happy to take if empty...or this error is caused because we are trying to use a stream when we shouldnt.

This commit is contained in:
TomPallister 2016-10-28 22:50:00 +01:00
parent 6be3c1cf73
commit 3a1dd1f9bc
7 changed files with 49 additions and 18 deletions

View File

@ -12,17 +12,18 @@ namespace Ocelot.RequestBuilder.Builder
public class HttpRequestBuilder : IRequestBuilder
{
public async Task<Response<Request>> Build(string httpMethod, string downstreamUrl, Stream content, IHeaderDictionary headers,
IRequestCookieCollection cookies, string queryString, string contentType)
IRequestCookieCollection cookies, QueryString queryString, string contentType)
{
var method = new HttpMethod(httpMethod);
var uri = new Uri(string.Format("{0}{1}", downstreamUrl, queryString));
var uri = new Uri(string.Format("{0}{1}", downstreamUrl, queryString.ToUriComponent()));
var httpRequestMessage = new HttpRequestMessage(method, uri);
if (content != null)
{
httpRequestMessage.Content = new StreamContent(content);
httpRequestMessage.Content = new ByteArrayContent(ToByteArray(content));
}
if (!string.IsNullOrEmpty(contentType))
@ -35,11 +36,7 @@ namespace Ocelot.RequestBuilder.Builder
if (headers != null)
{
headers.Remove("Content-Type");
}
//todo get rid of if
if (headers != null)
{
foreach (var header in headers)
{
//todo get rid of if..
@ -63,5 +60,17 @@ namespace Ocelot.RequestBuilder.Builder
return new OkResponse<Request>(new Request(httpRequestMessage, cookieContainer));
}
private byte[] ToByteArray(Stream stream)
{
using (stream)
{
using (MemoryStream memStream = new MemoryStream())
{
stream.CopyTo(memStream);
return memStream.ToArray();
}
}
}
}
}

View File

@ -12,7 +12,7 @@ namespace Ocelot.RequestBuilder.Builder
Stream content,
IHeaderDictionary headers,
IRequestCookieCollection cookies,
string queryString,
QueryString queryString,
string contentType);
}
}

View File

@ -34,7 +34,7 @@ namespace Ocelot.RequestBuilder.Middleware
var request = await _requestBuilder
.Build(context.Request.Method, downstreamUrl.Data, context.Request.Body,
context.Request.Headers, context.Request.Cookies, context.Request.QueryString.Value, context.Request.ContentType);
context.Request.Headers, context.Request.Cookies, context.Request.QueryString, context.Request.ContentType);
if (request.IsError)
{

View File

@ -106,6 +106,31 @@ namespace Ocelot.AcceptanceTests
.BDDfy();
}
[Fact]
public void should_return_response_201_with_complex_query_string()
{
var yamlConfiguration = new YamlConfiguration
{
ReRoutes = new List<YamlReRoute>
{
new YamlReRoute
{
DownstreamTemplate = "http://localhost:51879/newThing",
UpstreamTemplate = "/newThing",
UpstreamHttpMethod = "Get",
}
}
};
this.Given(x => x.GivenThereIsAServiceRunningOn("http://localhost:51879", 200, "Hello from Laura"))
.And(x => _steps.GivenThereIsAConfiguration(yamlConfiguration))
.And(x => _steps.GivenOcelotIsRunning())
.When(x => _steps.WhenIGetUrlOnTheApiGateway("/newThing?DeviceType=IphoneApp&Browser=moonpigIphone&BrowserString=-&CountryCode=123&DeviceName=iPhone 5 (GSM+CDMA)&OperatingSystem=iPhone OS 7.1.2&BrowserVersion=3708AdHoc&ipAddress=-"))
.Then(x => _steps.ThenTheStatusCodeShouldBe(HttpStatusCode.OK))
.And(x => _steps.ThenTheResponseBodyShouldBe("Hello from Laura"))
.BDDfy();
}
private void GivenThereIsAServiceRunningOn(string url, int statusCode, string responseBody)
{
_builder = new WebHostBuilder()

View File

@ -21,9 +21,6 @@ ReRoutes:
LocationId: Claims[LocationId] > value
UserType: Claims[sub] > value[0] > |
UserId: Claims[sub] > value[1] > |
- DownstreamTemplate: http://www.bbc.co.uk
UpstreamTemplate: /
UpstreamHttpMethod: Get
- DownstreamTemplate: http://localhost:51879/api/products/{productId}
UpstreamTemplate: /products/{productId}
- DownstreamTemplate: http://jsonplaceholder.typicode.com/posts
UpstreamTemplate: /posts
UpstreamHttpMethod: Get

View File

@ -69,7 +69,7 @@ namespace Ocelot.UnitTests.RequestBuilder
_request = new OkResponse<Request>(request);
_requestBuilder
.Setup(x => x.Build(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<Stream>(), It.IsAny<IHeaderDictionary>(),
It.IsAny<IRequestCookieCollection>(), It.IsAny<string>(), It.IsAny<string>()))
It.IsAny<IRequestCookieCollection>(), It.IsAny<QueryString>(), It.IsAny<string>()))
.ReturnsAsync(_request);
}

View File

@ -21,7 +21,7 @@ namespace Ocelot.UnitTests.RequestBuilder
private HttpContent _content;
private IHeaderDictionary _headers;
private IRequestCookieCollection _cookies;
private string _query;
private QueryString _query;
private string _contentType;
private readonly IRequestBuilder _requestBuilder;
private Response<Request> _result;
@ -137,7 +137,7 @@ namespace Ocelot.UnitTests.RequestBuilder
{
this.Given(x => x.GivenIHaveHttpMethod("POST"))
.And(x => x.GivenIHaveDownstreamUrl("http://www.bbc.co.uk"))
.And(x => x.GivenTheQueryStringIs("?jeff=1&geoff=2"))
.And(x => x.GivenTheQueryStringIs(new QueryString("?jeff=1&geoff=2")))
.When(x => x.WhenICreateARequest())
.And(x => x.ThenTheCorrectQueryStringIsUsed("?jeff=1&geoff=2"))
.BDDfy();
@ -153,7 +153,7 @@ namespace Ocelot.UnitTests.RequestBuilder
_result.Data.HttpRequestMessage.RequestUri.Query.ShouldBe(expected);
}
private void GivenTheQueryStringIs(string query)
private void GivenTheQueryStringIs(QueryString query)
{
_query = query;
}