1
- // <copyright file="HttpCommandExecutor.cs" company="WebDriver Committers">
1
+ // <copyright file="HttpCommandExecutor.cs" company="WebDriver Committers">
2
2
// Licensed to the Software Freedom Conservancy (SFC) under one
3
3
// or more contributor license agreements. See the NOTICE file
4
4
// distributed with this work for additional information
17
17
// </copyright>
18
18
19
19
using System ;
20
+ using System . Diagnostics ;
20
21
using System . Globalization ;
21
22
using System . IO ;
22
23
using System . Net ;
@@ -30,8 +31,10 @@ namespace OpenQA.Selenium.Remote
30
31
internal class HttpCommandExecutor : ICommandExecutor
31
32
{
32
33
private const string JsonMimeType = "application/json" ;
33
- private const string ContentTypeHeader = JsonMimeType + ";charset=utf-8" ;
34
- private const string RequestAcceptHeader = JsonMimeType + ", image/png" ;
34
+ private const string PngMimeType = "image/png" ;
35
+ private const string CharsetType = "charset=utf-8" ;
36
+ private const string ContentTypeHeader = JsonMimeType + ";" + CharsetType ;
37
+ private const string RequestAcceptHeader = JsonMimeType + ", " + PngMimeType ;
35
38
private Uri remoteServerUri ;
36
39
private TimeSpan serverResponseTimeout ;
37
40
private bool enableKeepAlive ;
@@ -71,6 +74,7 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena
71
74
this . enableKeepAlive = enableKeepAlive ;
72
75
73
76
ServicePointManager . Expect100Continue = false ;
77
+ ServicePointManager . DefaultConnectionLimit = 2000 ;
74
78
75
79
// In the .NET Framework, HttpWebRequest responses with an error code are limited
76
80
// to 64k by default. Since the remote server error responses include a screenshot,
@@ -80,12 +84,12 @@ public HttpCommandExecutor(Uri addressOfRemoteServer, TimeSpan timeout, bool ena
80
84
{
81
85
HttpWebRequest . DefaultMaximumErrorResponseLength = - 1 ;
82
86
}
83
- }
87
+ }
84
88
85
- /// <summary>
86
- /// Gets the repository of objects containin information about commands.
87
- /// </summary>
88
- public CommandInfoRepository CommandInfoRepository
89
+ /// <summary>
90
+ /// Gets the repository of objects containin information about commands.
91
+ /// </summary>
92
+ public CommandInfoRepository CommandInfoRepository
89
93
{
90
94
get { return this . commandInfoRepository ; }
91
95
}
@@ -103,22 +107,11 @@ public virtual Response Execute(Command commandToExecute)
103
107
}
104
108
105
109
CommandInfo info = this . commandInfoRepository . GetCommandInfo ( commandToExecute . Name ) ;
106
- HttpWebRequest request = info . CreateWebRequest ( this . remoteServerUri , commandToExecute ) ;
107
- request . Timeout = ( int ) this . serverResponseTimeout . TotalMilliseconds ;
108
- request . Accept = RequestAcceptHeader ;
109
- request . KeepAlive = this . enableKeepAlive ;
110
- request . ServicePoint . ConnectionLimit = 2000 ;
111
- if ( request . Method == CommandInfo . PostCommand )
112
- {
113
- string payload = commandToExecute . ParametersAsJsonString ;
114
- byte [ ] data = Encoding . UTF8 . GetBytes ( payload ) ;
115
- request . ContentType = ContentTypeHeader ;
116
- Stream requestStream = request . GetRequestStream ( ) ;
117
- requestStream . Write ( data , 0 , data . Length ) ;
118
- requestStream . Close ( ) ;
119
- }
110
+ HttpRequestInfo requestInfo = new HttpRequestInfo ( this . remoteServerUri , commandToExecute , info ) ;
120
111
121
- Response toReturn = this . CreateResponse ( request ) ;
112
+ HttpResponseInfo responseInfo = this . MakeHttpRequest ( requestInfo ) ;
113
+
114
+ Response toReturn = this . CreateResponse ( responseInfo ) ;
122
115
if ( commandToExecute . Name == DriverCommand . NewSession && toReturn . IsSpecificationCompliant )
123
116
{
124
117
// If we are creating a new session, sniff the response to determine
@@ -153,9 +146,25 @@ private static string GetTextOfWebResponse(HttpWebResponse webResponse)
153
146
return responseString ;
154
147
}
155
148
156
- private Response CreateResponse ( WebRequest request )
149
+ private HttpResponseInfo MakeHttpRequest ( HttpRequestInfo requestInfo )
157
150
{
158
- Response commandResponse = new Response ( ) ;
151
+ HttpWebRequest request = HttpWebRequest . Create ( requestInfo . FullUri ) as HttpWebRequest ;
152
+ request . Method = requestInfo . HttpMethod ;
153
+ request . Timeout = ( int ) this . serverResponseTimeout . TotalMilliseconds ;
154
+ request . Accept = RequestAcceptHeader ;
155
+ request . KeepAlive = this . enableKeepAlive ;
156
+ request . ServicePoint . ConnectionLimit = 2000 ;
157
+ if ( request . Method == CommandInfo . PostCommand )
158
+ {
159
+ string payload = requestInfo . RequestBody ;
160
+ byte [ ] data = Encoding . UTF8 . GetBytes ( payload ) ;
161
+ request . ContentType = ContentTypeHeader ;
162
+ Stream requestStream = request . GetRequestStream ( ) ;
163
+ requestStream . Write ( data , 0 , data . Length ) ;
164
+ requestStream . Close ( ) ;
165
+ }
166
+
167
+ HttpResponseInfo responseInfo = new HttpResponseInfo ( ) ;
159
168
HttpWebResponse webResponse = null ;
160
169
try
161
170
{
@@ -182,58 +191,87 @@ private Response CreateResponse(WebRequest request)
182
191
}
183
192
else
184
193
{
185
- string responseString = GetTextOfWebResponse ( webResponse ) ;
186
- if ( webResponse . ContentType != null && webResponse . ContentType . StartsWith ( JsonMimeType , StringComparison . OrdinalIgnoreCase ) )
187
- {
188
- commandResponse = Response . FromJson ( responseString ) ;
189
- }
190
- else
194
+ responseInfo . Body = GetTextOfWebResponse ( webResponse ) ;
195
+ responseInfo . ContentType = webResponse . ContentType ;
196
+ responseInfo . StatusCode = webResponse . StatusCode ;
197
+ }
198
+
199
+ return responseInfo ;
200
+ }
201
+
202
+ private Response CreateResponse ( HttpResponseInfo stuff )
203
+ {
204
+ Response commandResponse = new Response ( ) ;
205
+ string responseString = stuff . Body ;
206
+ if ( stuff . ContentType != null && stuff . ContentType . StartsWith ( JsonMimeType , StringComparison . OrdinalIgnoreCase ) )
207
+ {
208
+ commandResponse = Response . FromJson ( responseString ) ;
209
+ }
210
+ else
211
+ {
212
+ commandResponse . Value = responseString ;
213
+ }
214
+
215
+ if ( this . commandInfoRepository . SpecificationLevel < 1 && ( stuff . StatusCode < HttpStatusCode . OK || stuff . StatusCode >= HttpStatusCode . BadRequest ) )
216
+ {
217
+ // 4xx represents an unknown command or a bad request.
218
+ if ( stuff . StatusCode >= HttpStatusCode . BadRequest && stuff . StatusCode < HttpStatusCode . InternalServerError )
191
219
{
192
- commandResponse . Value = responseString ;
220
+ commandResponse . Status = WebDriverResult . UnhandledError ;
193
221
}
194
-
195
- if ( this . commandInfoRepository . SpecificationLevel < 1 && ( webResponse . StatusCode < HttpStatusCode . OK || webResponse . StatusCode >= HttpStatusCode . BadRequest ) )
222
+ else if ( stuff . StatusCode >= HttpStatusCode . InternalServerError )
196
223
{
197
- // 4xx represents an unknown command or a bad request.
198
- if ( webResponse . StatusCode >= HttpStatusCode . BadRequest && webResponse . StatusCode < HttpStatusCode . InternalServerError )
224
+ // 5xx represents an internal server error. The response status should already be set, but
225
+ // if not, set it to a general error code. The exception is a 501 (NotImplemented) response,
226
+ // which indicates that the command hasn't been implemented on the server.
227
+ if ( stuff . StatusCode == HttpStatusCode . NotImplemented )
199
228
{
200
- commandResponse . Status = WebDriverResult . UnhandledError ;
229
+ commandResponse . Status = WebDriverResult . UnknownCommand ;
201
230
}
202
- else if ( webResponse . StatusCode >= HttpStatusCode . InternalServerError )
231
+ else
203
232
{
204
- // 5xx represents an internal server error. The response status should already be set, but
205
- // if not, set it to a general error code. The exception is a 501 (NotImplemented) response,
206
- // which indicates that the command hasn't been implemented on the server.
207
- if ( webResponse . StatusCode == HttpStatusCode . NotImplemented )
208
- {
209
- commandResponse . Status = WebDriverResult . UnknownCommand ;
210
- }
211
- else
233
+ if ( commandResponse . Status == WebDriverResult . Success )
212
234
{
213
- if ( commandResponse . Status == WebDriverResult . Success )
214
- {
215
- commandResponse . Status = WebDriverResult . UnhandledError ;
216
- }
235
+ commandResponse . Status = WebDriverResult . UnhandledError ;
217
236
}
218
237
}
219
- else
220
- {
221
- commandResponse . Status = WebDriverResult . UnhandledError ;
222
- }
223
238
}
224
-
225
- if ( commandResponse . Value is string )
239
+ else
226
240
{
227
- // First, collapse all \r\n pairs to \n, then replace all \n with
228
- // System.Environment.NewLine. This ensures the consistency of
229
- // the values.
230
- commandResponse . Value = ( ( string ) commandResponse . Value ) . Replace ( "\r \n " , "\n " ) . Replace ( "\n " , System . Environment . NewLine ) ;
241
+ commandResponse . Status = WebDriverResult . UnhandledError ;
231
242
}
243
+ }
232
244
233
- webResponse . Close ( ) ;
245
+ if ( commandResponse . Value is string )
246
+ {
247
+ // First, collapse all \r\n pairs to \n, then replace all \n with
248
+ // System.Environment.NewLine. This ensures the consistency of
249
+ // the values.
250
+ commandResponse . Value = ( ( string ) commandResponse . Value ) . Replace ( "\r \n " , "\n " ) . Replace ( "\n " , System . Environment . NewLine ) ;
234
251
}
235
252
236
253
return commandResponse ;
237
254
}
255
+
256
+ private class HttpRequestInfo
257
+ {
258
+ public HttpRequestInfo ( Uri serverUri , Command commandToExecute , CommandInfo commandInfo )
259
+ {
260
+ this . FullUri = commandInfo . CreateCommandUri ( serverUri , commandToExecute ) ;
261
+ this . HttpMethod = commandInfo . Method ;
262
+ this . RequestBody = commandToExecute . ParametersAsJsonString ;
263
+ }
264
+
265
+ public Uri FullUri { get ; set ; }
266
+ public string HttpMethod { get ; set ; }
267
+ public string RequestBody { get ; set ; }
268
+ }
269
+
270
+ private class HttpResponseInfo
271
+ {
272
+ public HttpStatusCode StatusCode { get ; set ; }
273
+ public string Body { get ; set ; }
274
+ public string ContentType { get ; set ; }
275
+ }
238
276
}
239
277
}
0 commit comments