Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow HttpContent body/return types for extra customizability. #104

Merged
merged 4 commits into from
Jun 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Refit-Tests/InterfaceStubGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public void GenerateTemplateInfoForInterfaceListSmokeTest()
.ToList();

var result = fixture.GenerateTemplateInfoForInterfaceList(input);
Assert.AreEqual(6, result.ClassList.Count);
Assert.AreEqual(7, result.ClassList.Count);
}

[Test]
Expand Down
25 changes: 25 additions & 0 deletions Refit-Tests/RefitStubs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,31 @@ public virtual Task<bool> PostAValue(string derp)
}
}

namespace Refit.Tests
{
using RefitInternalGenerated;

[Preserve]
public partial class AutoGeneratedIHttpContentApi : IHttpContentApi
{
public HttpClient Client { get; protected set; }
readonly Dictionary<string, Func<HttpClient, object[], object>> methodImpls;

public AutoGeneratedIHttpContentApi(HttpClient client, IRequestBuilder requestBuilder)
{
methodImpls = requestBuilder.InterfaceHttpMethods.ToDictionary(k => k, v => requestBuilder.BuildRestResultFuncForMethod(v));
Client = client;
}

public virtual Task<HttpContent> PostFileUpload(HttpContent content)
{
var arguments = new object[] { content };
return (Task<HttpContent>) methodImpls["PostFileUpload"](Client, arguments);
}

}
}

namespace Refit.Tests
{
using RefitInternalGenerated;
Expand Down
29 changes: 26 additions & 3 deletions Refit-Tests/RequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Net;
Expand Down Expand Up @@ -326,18 +327,21 @@ public class TestHttpMessageHandler : HttpMessageHandler
{
public HttpRequestMessage RequestMessage { get; private set; }
public int MessagesSent { get; set; }
public string Content { get; set; }
public HttpContent Content { get; set; }

public Func<HttpContent> ContentFactory { get; set; }

public TestHttpMessageHandler(string content = "test")
{
Content = content;
Content = new StringContent(content);
ContentFactory = () => Content;
}

protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
RequestMessage = request;
MessagesSent++;
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = new StringContent(Content) });
return Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK) { Content = ContentFactory() });
}
}

Expand All @@ -359,6 +363,25 @@ public string Format(object value, ParameterInfo parameterInfo)
[TestFixture]
public class RequestBuilderTests
{
[Test]
public void HttpContentTest()
{
var fixture = new RequestBuilderImplementation(typeof(IHttpContentApi));
var factory = fixture.BuildRestResultFuncForMethod("PostFileUpload");
var testHttpMessageHandler = new TestHttpMessageHandler();
var retContent = new StreamContent(new MemoryStream());
testHttpMessageHandler.Content = retContent;

var mpc = new MultipartContent("foosubtype");


var task = (Task<HttpContent>)factory(new HttpClient(testHttpMessageHandler) { BaseAddress = new Uri("http://api/") }, new object[] { mpc });
task.Wait();

Assert.AreEqual(testHttpMessageHandler.RequestMessage.Content, mpc);
Assert.AreEqual(retContent, task.Result);
}

[Test]
public void MethodsThatDontHaveAnHttpMethodShouldFail()
{
Expand Down
17 changes: 14 additions & 3 deletions Refit-Tests/RestService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,12 @@ public interface IBrokenWebApi
Task<bool> PostAValue([Body] string derp);
}

public interface IHttpContentApi
{
[Post("/blah")]
Task<HttpContent> PostFileUpload([Body] HttpContent content);
}

public class HttpBinGet
{
public Dictionary<string, string> Args { get; set; }
Expand Down Expand Up @@ -271,6 +277,10 @@ public async Task HitTheGitHubUserApiAsObservableAndSubscribeAfterTheFactWithSet
public async Task TwoSubscriptionsResultInTwoRequests()
{
var input = new TestHttpMessageHandler();

// we need to use a factory here to ensure each request gets its own httpcontent instance
input.ContentFactory = () => new StringContent("test");

var client = new HttpClient(input) { BaseAddress = new Uri("http://foo") };
var fixture = RestService.For<IGitHubApi>(client);

Expand All @@ -279,14 +289,15 @@ public async Task TwoSubscriptionsResultInTwoRequests()
var obs = fixture.GetIndexObservable()
.Timeout(TimeSpan.FromSeconds(10));

await obs;
var result1 = await obs;
Assert.AreEqual(1, input.MessagesSent);

var result = await obs;
var result2 = await obs;
Assert.AreEqual(2, input.MessagesSent);

// NB: TestHttpMessageHandler returns what we tell it to ('test' by default)
Assert.IsTrue(result.Contains("test"));
Assert.IsTrue(result1.Contains("test"));
Assert.IsTrue(result2.Contains("test"));
}

[Test]
Expand Down
11 changes: 10 additions & 1 deletion Refit/RequestBuilderImplementation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,12 @@ public Func<object[], HttpRequestMessage> BuildRequestFactoryForMethod(string me
if (restMethod.BodyParameterInfo != null && restMethod.BodyParameterInfo.Item2 == i) {
var streamParam = paramList[i] as Stream;
var stringParam = paramList[i] as string;
var httpContentParam = paramList[i] as HttpContent;

if (streamParam != null) {
if (httpContentParam != null)
{
ret.Content = httpContentParam;
} else if (streamParam != null) {
ret.Content = new StreamContent(streamParam);
} else if (stringParam != null) {
ret.Content = new StringContent(stringParam);
Expand Down Expand Up @@ -239,6 +243,11 @@ Func<HttpClient, CancellationToken, object[], Task<T>> buildCancellableTaskFuncF
throw await ApiException.Create(resp, restMethod.RefitSettings);
}

if (restMethod.SerializedReturnType == typeof(HttpContent))
{
return (T)(object)resp.Content;
}

var ms = new MemoryStream();
var fromStream = await resp.Content.ReadAsStreamAsync();
await fromStream.CopyToAsync(ms, 4096, ct);
Expand Down