Skip to content

Commit c9b8cfa

Browse files
committed
Fixes #1699
1 parent 402f094 commit c9b8cfa

File tree

7 files changed

+118
-10
lines changed

7 files changed

+118
-10
lines changed

src/RestSharp/Parameters/FileParameter.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public static FileParameter Create(string name, byte[] data, string filename, st
6060
Stream GetFile() {
6161
var stream = new MemoryStream();
6262
stream.Write(data, 0, data.Length);
63+
stream.Flush();
64+
stream.Seek(0, SeekOrigin.Begin);
6365
return stream;
6466
}
6567
}
@@ -69,7 +71,6 @@ Stream GetFile() {
6971
/// </summary>
7072
/// <param name="name">The parameter name to use in the request.</param>
7173
/// <param name="getFile">Delegate that will be called with the request stream so you can write to it..</param>
72-
/// <param name="contentLength">The length of the data that will be written by te writer.</param>
7374
/// <param name="fileName">The filename to use in the request.</param>
7475
/// <param name="contentType">Optional: parameter content type, default is "application/g-zip"</param>
7576
/// <returns>The <see cref="FileParameter" /> using the default content type.</returns>
@@ -88,7 +89,7 @@ public static FileParameter FromFile(string fullPath, string? name = null, strin
8889
var fileName = Path.GetFileName(fullPath);
8990
var parameterName = name ?? fileName;
9091

91-
return new FileParameter(parameterName, fileName, GetFile);
92+
return new FileParameter(parameterName, fileName, GetFile, contentType);
9293

9394
Stream GetFile() => File.OpenRead(fullPath);
9495
}

src/RestSharp/Request/RequestContent.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
using System.Runtime.Serialization;
1717
using RestSharp.Extensions;
1818
using static RestSharp.KnownHeaders;
19+
1920
// ReSharper disable SuggestBaseTypeForParameter
2021

2122
namespace RestSharp;
@@ -176,5 +177,8 @@ string GetContentTypeHeader(string contentType) {
176177
return boundary.IsEmpty() ? contentType : $"{contentType}; boundary=\"{boundary}\"";
177178
}
178179

179-
public void Dispose() => _streams.ForEach(x => x.Dispose());
180+
public void Dispose() {
181+
_streams.ForEach(x => x.Dispose());
182+
Content?.Dispose();
183+
}
180184
}

src/RestSharp/Request/RestRequest.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ static IEnumerable<KeyValuePair<string, string>> ParseQuery(string query)
6161
public RestRequest(Uri resource, Method method = Method.Get)
6262
: this(resource.IsAbsoluteUri ? resource.AbsoluteUri : resource.OriginalString, method) { }
6363

64-
// readonly List<Parameter> _parameters = new();
6564
readonly List<FileParameter> _files = new();
6665

6766
/// <summary>

test/RestSharp.IntegrationTests/FileTests.cs renamed to test/RestSharp.IntegrationTests/DownloadFileTests.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
namespace RestSharp.IntegrationTests;
66

7-
public class FileTests : IDisposable {
8-
public FileTests() {
7+
public sealed class DownloadFileTests : IDisposable {
8+
public DownloadFileTests() {
99
_server = HttpServerFixture.StartServer("Assets/Koala.jpg", FileHandler);
1010
_client = new RestClient(_server.Url);
1111
}
@@ -25,9 +25,9 @@ void FileHandler(HttpListenerRequest request, HttpListenerResponse response) {
2525
reader.BaseStream.CopyTo(response.OutputStream);
2626
}
2727

28-
HttpServerFixture _server;
29-
RestClient _client;
30-
readonly string _path = AppDomain.CurrentDomain.BaseDirectory;
28+
readonly HttpServerFixture _server;
29+
readonly RestClient _client;
30+
readonly string _path = AppDomain.CurrentDomain.BaseDirectory;
3131

3232
[Fact]
3333
public async Task AdvancedResponseWriter_without_ResponseWriter_reads_stream() {

test/RestSharp.IntegrationTests/Fixtures/TestServer.cs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
using Microsoft.AspNetCore.Builder;
33
using Microsoft.AspNetCore.Hosting;
44
using Microsoft.AspNetCore.Http;
5+
using Microsoft.AspNetCore.Mvc;
6+
using Microsoft.AspNetCore.Routing.Constraints;
57
using Microsoft.Extensions.Logging;
8+
using RestSharp.Extensions;
69
using RestSharp.Tests.Shared.Extensions;
710

811
namespace RestSharp.IntegrationTests.Fixtures;
@@ -42,20 +45,46 @@ public HttpServer(ITestOutputHelper output = null) {
4245
// ReSharper disable once ConvertClosureToMethodGroup
4346
_app.MapGet("status", (int code) => Results.StatusCode(code));
4447
_app.MapGet("headers", HandleHeaders);
48+
_app.MapDelete("delete", () => new TestResponse { Message = "Works!" });
4549

4650
// PUT
4751
_app.MapPut(
4852
"content",
4953
async context => {
50-
var content = await context.Request.Body.StreamToStringAsync();
54+
var content = await context.Request.Body.StreamToStringAsync();
5155
await context.Response.WriteAsync(content);
5256
}
5357
);
5458

59+
// Upload file
60+
var assetPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Assets");
61+
62+
_app.MapPost("/upload", HandleUpload);
63+
5564
IResult HandleHeaders(HttpContext ctx) {
5665
var response = ctx.Request.Headers.Select(x => new TestServerResponse(x.Key, x.Value));
5766
return Results.Ok(response);
5867
}
68+
69+
async Task<IResult> HandleUpload(HttpRequest req) {
70+
if (!req.HasFormContentType) {
71+
return Results.BadRequest("It's not a form");
72+
}
73+
74+
var form = await req.ReadFormAsync();
75+
var file = form.Files["file"];
76+
77+
if (file is null) {
78+
return Results.BadRequest("File parameter 'file' is not present");
79+
}
80+
81+
await using var stream = file.OpenReadStream();
82+
83+
var received = await stream.ReadAsBytes(default);
84+
var expected = await File.ReadAllBytesAsync(Path.Combine(assetPath, file.FileName));
85+
86+
return Results.Ok(new UploadResponse(file.FileName, file.Length, received.SequenceEqual(expected)));
87+
}
5988
}
6089

6190
public Uri Url => new(Address);
@@ -70,4 +99,8 @@ public async Task Stop() {
7099

71100
record TestServerResponse(string Name, string Value);
72101

102+
record UploadRequest(string Filename, IFormFile File);
103+
104+
record UploadResponse(string FileName, long Length, bool Equal);
105+
73106
record ContentResponse(string Content);

test/RestSharp.IntegrationTests/RequestTests.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,21 @@ public async Task Can_Timeout_GET_Async() {
6161

6262
Assert.Equal(ResponseStatus.TimedOut, response.ResponseStatus);
6363
}
64+
65+
[Fact]
66+
public async Task Can_Perform_Delete_With_Response_Type() {
67+
var request = new RestRequest("delete");
68+
var response = await _client.ExecuteAsync<Response>(request, Method.Delete);
69+
70+
response.StatusCode.Should().Be(HttpStatusCode.OK);
71+
response.Data!.Message.Should().Be("Works!");
72+
}
73+
74+
[Fact]
75+
public async Task Can_Delete_With_Response_Type_using_extension() {
76+
var request = new RestRequest("delete");
77+
var response = await _client.DeleteAsync<Response>(request);
78+
79+
response!.Message.Should().Be("Works!");
80+
}
6481
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using RestSharp.IntegrationTests.Fixtures;
2+
3+
namespace RestSharp.IntegrationTests;
4+
5+
[Collection(nameof(TestServerCollection))]
6+
public class UploadFileTests {
7+
readonly RestClient _client;
8+
readonly string _path = AppDomain.CurrentDomain.BaseDirectory;
9+
10+
public UploadFileTests(TestServerFixture fixture) => _client = new RestClient(fixture.Server.Url);
11+
12+
[Fact]
13+
public async Task Should_upload_from_file() {
14+
const string filename = "Koala.jpg";
15+
16+
var path = Path.Combine(_path, "Assets", filename);
17+
18+
var request = new RestRequest("upload").AddFile("file", path);
19+
var response = await _client.PostAsync<UploadResponse>(request);
20+
21+
var expected = new UploadResponse(filename, new FileInfo(path).Length, true);
22+
23+
response.Should().BeEquivalentTo(expected);
24+
}
25+
26+
[Fact]
27+
public async Task Should_upload_from_bytes() {
28+
const string filename = "Koala.jpg";
29+
30+
var path = Path.Combine(_path, "Assets", filename);
31+
var bytes = await File.ReadAllBytesAsync(path);
32+
33+
var request = new RestRequest("upload").AddFile("file", bytes, filename);
34+
var response = await _client.PostAsync<UploadResponse>(request);
35+
36+
var expected = new UploadResponse(filename, new FileInfo(path).Length, true);
37+
38+
response.Should().BeEquivalentTo(expected);
39+
}
40+
41+
[Fact]
42+
public async Task Should_upload_from_stream() {
43+
const string filename = "Koala.jpg";
44+
45+
var path = Path.Combine(_path, "Assets", filename);
46+
47+
var request = new RestRequest("upload").AddFile("file", () => File.OpenRead(path), filename);
48+
var response = await _client.PostAsync<UploadResponse>(request);
49+
50+
var expected = new UploadResponse(filename, new FileInfo(path).Length, true);
51+
52+
response.Should().BeEquivalentTo(expected);
53+
}
54+
}

0 commit comments

Comments
 (0)