1 // Copyright 2004-2007 Castle Project - http://www.castleproject.org/
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
15 namespace Castle
.MonoRail
.TestSupport
20 using System
.Web
.Hosting
;
21 using System
.Collections
;
22 using System
.Globalization
;
25 /// Used to integrate with the ASP.Net Runtime
27 public class MonoRailTestWorkerRequest
: SimpleWorkerRequest
29 private TextWriter output
;
30 private TestRequest requestData
;
31 private TestResponse response
= new TestResponse();
32 private String virtualAppPath
;
33 private String appPhysicalPath
;
34 private String filePath
;
35 private String
[] knownRequestHeaders
;
36 private String
[][] unknownRequestHeaders
;
37 private String queryString
;
38 private byte[] preloadedContent
;
39 private byte[] queryStringBytes
;
40 private StringBuilder buffer
= new StringBuilder();
42 public MonoRailTestWorkerRequest(TestRequest requestData
,
43 String virtualAppPath
,
44 String physicalAppPath
,
45 TextWriter output
) : base(virtualAppPath
, String
.Empty
, output
)
47 this.virtualAppPath
= virtualAppPath
;
48 this.requestData
= requestData
;
49 this.appPhysicalPath
= physicalAppPath
;
51 this.filePath
= requestData
.Url
;
53 if (!appPhysicalPath
.EndsWith(Path
.DirectorySeparatorChar
.ToString()))
55 appPhysicalPath
= appPhysicalPath
+ Path
.DirectorySeparatorChar
;
59 protected internal void Prepare()
68 private void ProcessHeaders()
70 knownRequestHeaders
= new string[RequestHeaderMaximum
];
72 IList unknownHeaders
= new ArrayList();
74 foreach(String name
in requestData
.Headers
)
76 String
value = requestData
.Headers
[name
];
78 int index
= GetKnownRequestHeaderIndex(name
);
82 knownRequestHeaders
[index
] = value;
86 unknownHeaders
.Add(name
);
87 unknownHeaders
.Add(value);
91 int totalunknownHeaders
= unknownHeaders
.Count
/ 2;
92 unknownRequestHeaders
= new String
[totalunknownHeaders
][];
96 for(int i
= 0; i
< totalunknownHeaders
; i
++)
98 unknownRequestHeaders
[i
] = new String
[2];
99 unknownRequestHeaders
[i
][0] = (String
) unknownHeaders
[j
++];
100 unknownRequestHeaders
[i
][1] = (String
) unknownHeaders
[j
++];
104 private void ProcessQueryString()
106 if (requestData
.QueryStringParams
!= null)
110 foreach(String param
in requestData
.QueryStringParams
)
112 buffer
.AppendFormat("{0}&", param
);
115 queryString
= buffer
.ToString();
117 queryStringBytes
= Encoding
.ASCII
.GetBytes(queryString
);
121 private void ProcessPostBody()
123 if (requestData
.PostParams
!= null)
127 foreach(String param
in requestData
.PostParams
)
129 buffer
.AppendFormat("{0}&", param
);
132 preloadedContent
= Encoding
.ASCII
.GetBytes(buffer
.ToString());
136 public TestResponse Response
138 get { return response; }
141 private string GetPathInternal()
143 return virtualAppPath
.Equals("/")
144 ? ("/" + filePath
) : (virtualAppPath
+ "/" + filePath
);
147 public override string GetAppPath()
149 return virtualAppPath
;
152 public override string GetFilePathTranslated()
154 return appPhysicalPath
+ filePath
.Replace('/', Path
.DirectorySeparatorChar
);
157 public override String
MapPath(String path
)
161 if (path
== null || path
.Length
== 0 || path
.Equals("/"))
163 // asking for the site root
164 if ("/".Equals(virtualAppPath
))
166 // app at the site root
167 mappedPath
= appPhysicalPath
;
171 // unknown site root - don't point to app root to avoid double config inclusion
172 mappedPath
= Environment
.SystemDirectory
;
177 if (path
.StartsWith("/") || path
.StartsWith("\\"))
179 path
= path
.Substring(1);
182 mappedPath
= new DirectoryInfo(Path
.Combine(appPhysicalPath
, path
)).FullName
;
185 mappedPath
= mappedPath
.Replace('/', Path
.DirectorySeparatorChar
);
187 if (mappedPath
.EndsWith(Path
.DirectorySeparatorChar
.ToString()) && !mappedPath
.EndsWith(":\\"))
189 mappedPath
= mappedPath
.Substring(0, mappedPath
.Length
- 1);
195 public override String
GetAppPathTranslated()
197 return appPhysicalPath
;
200 public override byte[] GetPreloadedEntityBody()
202 return preloadedContent
;
205 public override bool IsEntireEntityBodyIsPreloaded()
210 public override int ReadEntityBody(byte[] buffer
, int size
)
212 int bytestocopy
= Math
.Min(preloadedContent
.Length
, size
);
214 Buffer
.BlockCopy(preloadedContent
, 0, buffer
, 0, bytestocopy
);
219 public override String
GetKnownRequestHeader(int index
)
221 return knownRequestHeaders
[index
];
224 public override String
GetUnknownRequestHeader(String name
)
226 for(int i
= 0; i
< unknownRequestHeaders
.Length
; i
++)
228 if (String
.Compare(name
, unknownRequestHeaders
[i
][0], true, CultureInfo
.InvariantCulture
) == 0)
230 return unknownRequestHeaders
[i
][1];
237 public override String
[][] GetUnknownRequestHeaders()
239 return unknownRequestHeaders
;
242 public override string GetServerVariable(string name
)
244 String
value = requestData
.ServerVariables
[name
];
250 case "SERVER_PROTOCOL":
251 return requestData
.Protocol
;
257 return value == null ? String
.Empty
: value;
260 public override void EndOfRequest()
264 public override string GetFilePath()
266 return GetPathInternal();
269 public override string GetHttpVerbName()
271 return requestData
.Verb
;
274 public override string GetHttpVersion()
276 return requestData
.Protocol
;
279 public override void FlushResponse(bool finalFlush
)
284 public override string GetLocalAddress()
286 return requestData
.LocalAddress
;
289 public override int GetLocalPort()
291 return requestData
.LocalPort
;
294 public override String
GetQueryString()
299 public override byte[] GetQueryStringRawBytes()
301 return queryStringBytes
;
304 public override string GetRawUrl()
306 return String
.Format("{0}{1}{2}",
307 GetPathInternal(), queryString
!= null ? "?" : "", queryString
);
310 public override string GetRemoteAddress()
312 return requestData
.RemoteAddress
;
315 public override int GetRemotePort()
317 return requestData
.RemotePort
;
320 public override string GetUriPath()
322 return GetPathInternal();
325 public override IntPtr
GetUserToken()
327 return requestData
.UserToken
;
330 public override void SendKnownResponseHeader(int index
, string value)
332 String key
= GetKnownResponseHeaderName(index
);
334 SendUnknownResponseHeader(key
, value);
337 public override void SendResponseFromFile(IntPtr handle
, long offset
, long length
)
339 // TODO: SendResponseFromFile
342 public override void SendResponseFromFile(string filename
, long offset
, long length
)
344 // TODO: SendResponseFromFile
347 public override void SendResponseFromMemory(byte[] data
, int length
)
349 output
.Write(Encoding
.Default
.GetChars(data
, 0, length
));
352 public override void SendStatus(int statusCode
, string statusDescription
)
354 response
.StatusCode
= statusCode
;
355 response
.StatusDescription
= statusDescription
;
358 public override void SendUnknownResponseHeader(string name
, string value)
360 object existingValue
= response
.Headers
[name
];
362 if (existingValue
== null)
364 response
.Headers
[name
] = value;
368 if (existingValue
is IList
)
370 (existingValue
as IList
).Add(value);
374 IList list
= new ArrayList();
376 list
.Add(existingValue
);
379 response
.Headers
[name
] = list
;
384 public override bool IsSecure()
389 public override string GetProtocol()
391 return requestData
.Protocol
;
394 public override void SendCalculatedContentLength(int contentLength
)
396 response
.Headers
["Content-Length"] = contentLength
.ToString();
399 public override bool HeadersSent()
404 public override bool IsClientConnected()
409 public override void CloseConnection()