-
Notifications
You must be signed in to change notification settings - Fork 0
/
HttpResponse.cs
95 lines (74 loc) · 2.3 KB
/
HttpResponse.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
using System.Net;
using System.Net.Http.Headers;
namespace Httpd.Impl;
public class HttpResponse : IDisposable
{
public HttpRequest Request { get; internal set; }
public void Dispose()
{
Request = default;
Content?.Dispose();
Content = default;
}
private string _httpVersion = "HTTP/1.1";
public string Version
=> Request?.Version ?? _httpVersion;
private HttpContent _content;
public HttpStatusCode Code { get; set; } = HttpStatusCode.OK;
public HttpContent Content
{
get => _content;
set
{
if ((_content = value) is not null)
MergeHeaders(Headers, _content.Headers);
}
}
static void MergeHeaders(Dictionary<string, string> source, HttpContentHeaders headers)
{
foreach (var (key, values) in headers)
source[key.ToLowerInvariant()] = string.Join(';', values);
}
public Dictionary<string, string> Headers { get; } = new()
{
["server"] = "Httpd/1.0",
["date"] = DateTime.Now.ToString("F"),
["connection"] = "close"
};
public void SetHeader(string name, object value)
=> Headers[name.ToLowerInvariant()] = value.ToString();
public HttpResponse WithHeader(string name, string value)
{
SetHeader(name, value);
return this;
}
public HttpResponse WithContent(HttpContent content)
{
_content = content;
return this;
}
public HttpResponse WithStringContent(string value)
{
_content = new StringContent(value);
return this;
}
public HttpResponse WithByteArrayContent(byte[] buffer, int offset = 0, int? count = default)
{
_content = new ByteArrayContent(buffer, offset, count ?? buffer.Length);
return this;
}
public HttpResponse WithCode(HttpStatusCode code)
{
Code = code;
return this;
}
public async Task CopyToAsync(Stream s)
{
await s.WriteHttpLineAsync($"{Version} {(int)Code}");
foreach (var header in Headers.DistinctBy(x => x.Key, StringComparer.OrdinalIgnoreCase))
await s.WriteHttpLineAsync($"{header.Key}: {header.Value}");
await s.WriteHttpLineAsync();
if (Content != null)
await Content.CopyToAsync(s);
}
}