-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathResponse.cs
More file actions
154 lines (153 loc) · 5.12 KB
/
Response.cs
File metadata and controls
154 lines (153 loc) · 5.12 KB
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
using System.IO;
using System.Text;
using System.Text.Json;
namespace Webtech3;
/// <summary>
/// Struct for Response
/// </summary>
public readonly struct Response(HttpListenerResponse response) {
readonly HttpListenerResponse res = response;
/// <summary>
/// Property fot get/set status code
/// </summary>
/// <value>Int of status</value>
public int Status {
get => res.StatusCode;
set => res.StatusCode = value;
}
/// <summary>
/// Property for get/set status description
/// </summary>
/// <value>String description</value>
public string Description {
get => res.StatusDescription;
set => res.StatusDescription = value;
}
/// <summary>
/// Property for get/set content length
/// </summary>
/// <value>Ulong</value>
public long Length {
get => res.ContentLength64;
set => res.ContentLength64 = value;
}
/// <summary>
/// Property for get/set content mime-type
/// </summary>
/// <value>String if specified, otherwise - null</value>
public string? MimeType {
get => res.ContentType;
set => res.ContentType = value;
}
/// <summary>
/// Property for get/set content encoding
/// </summary>
/// <value>Encoding obj if specified, otherwise - null</value>
public Encoding? Encoding {
get => res.ContentEncoding;
set => res.ContentEncoding = value;
}
/// <summary>
/// Property for getting access to response body
/// </summary>
/// <value>Response body as stream</value>
public Stream Body {
get => Body;
}
/// <summary>
/// Closes the response (same as send)
/// </summary>
public readonly void Send() => res.Close();
/// <summary>
/// Async writes string to response and send him
/// </summary>
/// <param name="content">String for response</param>
/// <returns>Task obj</returns>
public async readonly Task ResponseText(string content) {
var buffer = Encoding.UTF8.GetBytes(content);
Length = buffer.Length;
MimeType = "text/plain";
Status = HTTP.Statuses.Success.OK;
using (Stream answer = Body) {
await answer.WriteAsync(buffer);
await answer.FlushAsync();
}
Send();
}
/// <summary>
/// Async serialize any type obj array to json and write it to response.
/// Than send him
/// </summary>
/// <param name="data">Any type object</param>
/// <typeparam name="T">Generic type for supporting any type</typeparam>
/// <returns>Task obj</returns>
public async readonly Task ResponseJson<T>(params T[] data) {
using(var answer = Body) {
await JsonSerializer.SerializeAsync(answer, data);
await answer.FlushAsync();
}
Send();
}
/// <summary>
/// Async serialize any type single obj to json and write it to response.
/// Than send him
/// </summary>
/// <param name="data">Any type object</param>
/// <typeparam name="T">Generic type for supporting any type</typeparam>
/// <returns>Task obj</returns>
public async readonly Task ResponseJson<T>(T data) {
using(var answer = Body) {
await JsonSerializer.SerializeAsync(answer, data);
await answer.FlushAsync();
}
Send();
}
/// <summary>
/// Writes response with current error code, description & message.
/// Sends response.
/// </summary>
/// <param name="code">Int code for response.</param>
/// <param name="desc">String description for status</param>
/// <param name="mes">String, that writes to response body.
/// By default is null (than is code & description combination)
/// </param>
/// <returns></returns>
public async readonly Task ResponseError(int code, string desc, string? mes = null) {
Status = code;
Description = desc;
mes ??= $"{code} {desc}";
using(Stream answer = Body) {
await answer.WriteAsync(Encoding.UTF8.GetBytes(mes));
await answer.FlushAsync();
}
Send();
}
/// <summary>
/// Async writes file to response and send him
/// </summary>
/// <param name="path">Path to file.
/// If contains ".." - response error 400.
/// If file isn't exists - response error 404.
/// </param>
/// <returns>Task obj</returns>
public async Task ResponseFile(string path) {
if(path.Contains("..")) {
await ResponseError(HTTP.Statuses.Errors.Client.Bad_Request, "Bad request");
return;
}
var info = new FileInfo(path);
if(info.Exists) {
Status = HTTP.Statuses.Success.OK;
var buffer = await File.ReadAllBytesAsync(path);
Length = buffer.Length;
MimeType = info.MimeType;
using (Stream answer = Body) {
await answer.WriteAsync(buffer);
await answer.FlushAsync();
}
Send();
} else {
await ResponseError(HTTP.Statuses.Errors.Client.Not_Found, "Not found", "Requested file wasn't found.");
}
}
}