forked from bonesoul/uhttpsharp
-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathHttpResponse.cs
More file actions
126 lines (109 loc) · 4.55 KB
/
HttpResponse.cs
File metadata and controls
126 lines (109 loc) · 4.55 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
/*
* Copyright (C) 2011 uhttpsharp project - http://github.com/raistlinthewiz/uhttpsharp
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Threading.Tasks;
using uhttpsharp;
using uhttpsharp.Headers;
namespace uhttpsharp
{
public interface IHttpResponse
{
Task WriteBody(StreamWriter writer);
/// <summary>
/// Gets the status line of this http response,
/// The first line that will be sent to the client.
/// </summary>
HttpResponseCode ResponseCode { get; }
IHttpHeaders Headers { get; }
bool CloseConnection { get; }
}
public sealed class HttpResponse : IHttpResponse
{
private Stream ContentStream { get; set; }
private readonly Stream _headerStream = new MemoryStream();
private readonly bool _closeConnection;
private readonly IHttpHeaders _headers;
private readonly HttpResponseCode _responseCode;
public HttpResponse(HttpResponseCode code, string content, bool closeConnection)
: this(code, "text/html; charset=utf-8", StringToStream(content), !closeConnection)
{
}
public HttpResponse(string contentType, Stream contentStream, bool closeConnection)
: this(HttpResponseCode.Ok, contentType, contentStream, closeConnection)
{
}
public HttpResponse(HttpResponseCode code, string contentType, Stream contentStream, bool keepAliveConnection)
{
ContentStream = contentStream;
_closeConnection = !keepAliveConnection;
_responseCode = code;
_headers = new ListHttpHeaders(new[]
{
new KeyValuePair<string, string>("Date", DateTime.UtcNow.ToString("R")),
new KeyValuePair<string, string>("Connection", _closeConnection ? "Close" : "Keep-Alive"),
new KeyValuePair<string, string>("Content-Type", contentType),
new KeyValuePair<string, string>("Content-Length", ContentStream.Length.ToString(CultureInfo.InvariantCulture)),
});
}
public HttpResponse(HttpResponseCode code, byte[] contentStream, bool keepAliveConnection)
: this (code, "text/html; charset=utf-8", new MemoryStream(contentStream), keepAliveConnection)
{
}
public static HttpResponse CreateWithMessage(HttpResponseCode code, string message, bool keepAliveConnection, string body = "")
{
return new HttpResponse(
code,
string.Format(
"<html><head><title>{0}</title></head><body><h1>{0}</h1><hr>{1}</body></html>",
message, body), !keepAliveConnection);
}
private static MemoryStream StringToStream(string content)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(content);
writer.Flush();
return stream;
}
public async Task WriteBody(StreamWriter writer)
{
ContentStream.Position = 0;
await ContentStream.CopyToAsync(writer.BaseStream).ConfigureAwait(false);
await writer.BaseStream.FlushAsync().ConfigureAwait(false);
}
public HttpResponseCode ResponseCode
{
get { return _responseCode; }
}
public IHttpHeaders Headers
{
get { return _headers; }
}
public bool CloseConnection
{
get { return _closeConnection; }
}
public async Task WriteHeaders(StreamWriter writer)
{
_headerStream.Position = 0;
await _headerStream.CopyToAsync(writer.BaseStream).ConfigureAwait(false);
}
}
}