forked from NancyFx/Nancy
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathBrowserContext.cs
More file actions
267 lines (233 loc) · 10.1 KB
/
BrowserContext.cs
File metadata and controls
267 lines (233 loc) · 10.1 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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
namespace Nancy.Testing
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using Configuration;
using Nancy.Helpers;
/// <summary>
/// Defines the context that a <see cref="Browser"/> instance should run under.
/// </summary>
public class BrowserContext : IBrowserContextValues
{
/// <summary>
/// Initializes a new instance of the <see cref="BrowserContext"/> class,
/// with the provided <see cref="INancyEnvironment"/>.
/// </summary>
/// <param name="environment">An <see cref="INancyEnvironment"/> instance.</param>
public BrowserContext(INancyEnvironment environment)
{
this.Environment = environment;
this.Values.Headers = new Dictionary<string, IEnumerable<string>>(StringComparer.OrdinalIgnoreCase);
this.Values.Protocol = string.Empty;
this.Values.QueryString = string.Empty;
this.Values.BodyString = string.Empty;
this.Values.FormValues = string.Empty;
this.Values.HostName = string.Empty;
}
/// <summary>
/// Gets the <see cref="INancyEnvironment"/> instance used by the <see cref="Browser"/>.
/// </summary>
/// <value>An <see cref="INancyEnvironment"/> instance.</value>
public INancyEnvironment Environment { get; private set; }
/// <summary>
/// Gets or sets the that should be sent with the HTTP request.
/// </summary>
/// <value>A <see cref="Stream"/> that contains the body that should be sent with the HTTP request.</value>
Stream IBrowserContextValues.Body { get; set; }
/// <summary>
/// Gets or sets the protocol that should be sent with the HTTP request.
/// </summary>
/// <value>A <see cref="string"/> contains the protocol that should be sent with the HTTP request..</value>
string IBrowserContextValues.Protocol { get; set; }
/// <summary>
/// Gets or sets the querystring
/// </summary>
string IBrowserContextValues.QueryString { get; set; }
/// <summary>
/// Gets or sets the user host name
/// </summary>
string IBrowserContextValues.HostName { get; set; }
/// <summary>
/// Gets or sets the user host address
/// </summary>
string IBrowserContextValues.UserHostAddress { get; set; }
/// <summary>
/// Gets or sets the ClientCertificate
/// </summary>
X509Certificate2 IBrowserContextValues.ClientCertificate { get; set; }
/// <summary>
/// Gets or sets the body string
/// </summary>
string IBrowserContextValues.BodyString { get; set; }
/// <summary>
/// Gets or sets the form values string
/// </summary>
string IBrowserContextValues.FormValues { get; set; }
/// <summary>
/// Gets or sets the headers that should be sent with the HTTP request.
/// </summary>
/// <value>An <see cref="IDictionary{TKey,TValue}"/> instance that contains the headers that should be sent with the HTTP request.</value>
IDictionary<string, IEnumerable<string>> IBrowserContextValues.Headers { get; set; }
/// <summary>
/// Adds a body to the HTTP request.
/// </summary>
/// <param name="body">A string that should be used as the HTTP request body.</param>
public void Body(string body)
{
this.Values.BodyString = body;
}
/// <summary>
/// Adds a body to the HTTP request.
/// </summary>
/// <param name="body">A string that should be used as the HTTP request body.</param>
/// <param name="contentType">Content type of the HTTP request body.</param>
public void Body(string body, string contentType)
{
this.Values.BodyString = body;
this.Header("Content-Type", contentType);
}
/// <summary>
/// Adds a body to the HTTP request.
/// </summary>
/// <param name="body">A stream that should be used as the HTTP request body.</param>
/// <param name="contentType">Content type of the HTTP request body. Defaults to 'application/octet-stream'</param>
public void Body(Stream body, string contentType = null)
{
this.Values.Body = body;
this.Header("Content-Type", contentType ?? "application/octet-stream");
}
/// <summary>
/// Adds an application/x-www-form-urlencoded form value.
/// </summary>
/// <param name="key">The name of the form element.</param>
/// <param name="value">The value of the form element.</param>
public void FormValue(string key, string value)
{
if (!string.IsNullOrEmpty(this.Values.BodyString))
{
throw new InvalidOperationException("Form value cannot be set as well as body string");
}
this.Values.FormValues += string.Format(
"{0}{1}={2}",
this.Values.FormValues.Length == 0 ? string.Empty : "&",
key,
HttpUtility.UrlEncode(value));
}
/// <summary>
/// Adds a header to the HTTP request.
/// </summary>
/// <param name="name">The name of the header.</param>
/// <param name="value">The value of the header.</param>
public void Header(string name, string value)
{
if (!this.Values.Headers.ContainsKey(name))
{
this.Values.Headers.Add(name, new List<string>());
}
var values = (List<string>)this.Values.Headers[name];
values.Add(value);
this.Values.Headers[name] = values;
}
/// <summary>
/// Configures the request to be sent over HTTP.
/// </summary>
public void HttpRequest()
{
this.Values.Protocol = "http";
}
/// <summary>
/// Configures the request to be sent over HTTPS.
/// </summary>
public void HttpsRequest()
{
this.Values.Protocol = "https";
}
/// <summary>
/// Adds a query string entry
/// </summary>
public void Query(string key, string value)
{
this.Values.QueryString += string.Format(
"{0}{1}={2}",
this.Values.QueryString.Length == 0 ? "?" : "&",
key,
HttpUtility.UrlEncode(value));
}
/// <summary>
/// Sets the user host address.
/// </summary>
public void UserHostAddress(string userHostAddress)
{
this.Values.UserHostAddress = userHostAddress;
}
/// <summary>
/// Sets the host name.
/// </summary>
/// <param name="hostName">is the host name of request url string</param>
public void HostName(string hostName)
{
this.Values.HostName = hostName;
}
/// <summary>
/// Sets the ClientCertificate to a default embedded certificate
/// <remarks>The default certificate is embedded using the Nancy.Testing.Nancy Testing Cert.pfx resource name (secured with password "nancy")</remarks>
/// </summary>
public void Certificate()
{
X509Certificate2 certificate2;
using (
var pkcs12 =
Assembly.GetAssembly(typeof (BrowserContext))
.GetManifestResourceStream("Nancy.Testing.Resources.Nancy Testing Cert.pfx"))
{
using (var br = new BinaryReader(pkcs12))
{
certificate2 = new X509Certificate2(br.ReadBytes((int)pkcs12.Length), "nancy",
X509KeyStorageFlags.Exportable);
}
}
this.Values.ClientCertificate = certificate2;
}
/// <summary>
/// Sets the ClientCertificate
/// </summary>
/// <param name="certificate">the certificate in bytes</param>
public void Certificate(byte[] certificate)
{
this.Values.ClientCertificate = new X509Certificate2(certificate);
}
/// <summary>
/// Sets the ClientCertificate
/// </summary>
/// <param name="certificate">the certificate</param>
public void Certificate(X509Certificate2 certificate)
{
this.Values.ClientCertificate = certificate;
}
/// <summary>
/// Find a certificate in a store on the computer.
/// </summary>
/// <param name="storeLocation">The location of the store (LocalMachine, CurrentUser)</param>
/// <param name="storeName">The name of the store (e.q. My)</param>
/// <param name="findType">By which field you want to find the certificate (Commonname, Thumbprint, etc)</param>
/// <param name="findBy">The "Common name" or "thumbprint" you are looking for</param>
public void Certificate(StoreLocation storeLocation, StoreName storeName, X509FindType findType, object findBy)
{
var store = new X509Store(storeName, storeLocation);
store.Open(OpenFlags.ReadOnly);
var certificatesFound = store.Certificates.Find(findType, findBy, false);
if (certificatesFound.Count <= 0)
{
throw new InvalidOperationException(string.Format("No certificates found in {0} {1} with a {2} that looks like \"{3}\"", storeLocation, storeName, findType, findBy));
}
this.Values.ClientCertificate = certificatesFound[0];
}
private IBrowserContextValues Values
{
get { return this; }
}
}
}