using System.IO;
using System.Text;
using System.Threading;
+using System.Web.Util;
namespace System.Web
{
bool _bBuffering;
bool _bHeadersSent;
bool _bFlushing;
+ bool filtered;
long _lContentLength;
int _iStatusCode;
HttpWorkerRequest _WorkerRequest;
+ ArrayList fileDependencies;
+
public HttpResponse (TextWriter output)
{
_bBuffering = true;
Flush (true);
}
- internal void DoFilter ()
+ internal void DoFilter (bool really)
{
- if (null != _Writer)
+ if (really && null != _Writer)
_Writer.FilterData (true);
+
+ filtered = true;
}
[MonoTODO("We need to add cache headers also")]
{
ArrayList oHeaders = new ArrayList (_Headers.ToArray ());
+ oHeaders.Add (new HttpResponseHeader ("X-Powered-By", "Mono"));
// save culture info, we need us info here
CultureInfo oSavedInfo = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = new CultureInfo (0x0409);
- string date = DateTime.Now.ToUniversalTime ().ToString ("ddd, d MMM yyyy HH:mm:ss");
+ string date = DateTime.Now.ToUniversalTime ().ToString ("ddd, d MMM yyyy HH:mm:ss ");
oHeaders.Add (new HttpResponseHeader ("Date", date + "GMT"));
Thread.CurrentThread.CurrentCulture = oSavedInfo;
_sTransferEncoding));
}
- // TODO: Add Cookie headers..
+ if (_Cookies != null) {
+ int length = _Cookies.Count;
+ for (int i = 0; i < length; i++) {
+ oHeaders.Add (_Cookies.Get (i).GetCookieHeader ());
+ }
+ }
return oHeaders;
}
throw new NotImplementedException ();
}
- [MonoTODO()]
public void AddFileDependencies (ArrayList filenames)
{
- //throw new NotImplementedException();
+ if (filenames == null || filenames.Count == 0)
+ return;
+
+ if (fileDependencies == null) {
+ fileDependencies = (ArrayList) filenames.Clone ();
+ return;
+ }
+
+ foreach (string fn in filenames)
+ AddFileDependency (fn);
}
- [MonoTODO()]
public void AddFileDependency (string filename)
{
- //throw new NotImplementedException();
+ if (fileDependencies == null)
+ fileDependencies = new ArrayList ();
+
+ fileDependencies.Add (filename);
}
public void AddHeader (string name, string value)
AppendHeader(name, value);
}
- [MonoTODO()]
public void AppendCookie (HttpCookie cookie)
{
- throw new NotImplementedException ();
+ if (_bHeadersSent)
+ throw new HttpException ("Cannot append cookies after HTTP headers have been sent");
+
+ Cookies.Add (cookie);
}
[MonoTODO()]
throw new NotImplementedException ();
}
- [MonoTODO()]
public string ApplyAppPathModifier (string virtualPath)
{
- throw new NotImplementedException ();
+ if (virtualPath == null)
+ return null;
+
+ if (virtualPath == "")
+ return _Context.Request.RootVirtualDir;
+
+ if (UrlUtils.IsRelativeUrl (virtualPath)) {
+ virtualPath = UrlUtils.Combine (_Context.Request.RootVirtualDir, virtualPath);
+ } else if (UrlUtils.IsRooted (virtualPath)) {
+ virtualPath = UrlUtils.Reduce (virtualPath);
+ }
+
+ return virtualPath;
}
public bool Buffer
{
get {
if (_ContentEncoding == null)
- _ContentEncoding = Encoding.UTF8;
+ _ContentEncoding = WebEncoding.Encoding;
return _ContentEncoding;
}
}
}
- public HttpRequest Request
+ HttpRequest Request
{
get {
+ if (_Context == null)
+ return null;
+
return _Context.Request;
}
}
Flush (true);
}
- [MonoTODO("Check timeout and if we can cancel the thread...")]
public void End ()
{
- if (!_bEnded) {
- Flush ();
- _WorkerRequest.CloseConnection ();
- _bEnded = true;
- }
+ if (_bEnded)
+ return;
+
+ Flush ();
+ _bEnded = true;
+ _Context.ApplicationInstance.CompleteRequest ();
}
public void Flush ()
_bFlushing = true;
- if (_Writer != null) {
- _Writer.FlushBuffers ();
- } else {
+ if (_Writer == null) {
_TextWriter.Flush ();
+ _bFlushing = false;
+ return;
}
try {
- if (!_bHeadersSent && !_bSuppressHeaders && !_bClientDisconnected) {
- if (_Writer != null && BufferOutput) {
- _lContentLength = _Writer.BufferSize;
- } else {
- _lContentLength = 0;
- }
+ if (_bClientDisconnected)
+ return;
- if (_lContentLength == 0 && _iStatusCode == 200 &&
- _sTransferEncoding == null) {
- // Check we are going todo chunked encoding
- string sProto = Request.ServerVariables ["SERVER_PROTOCOL"];
-
- if (sProto != null && sProto == "HTTP/1.1") {
- AppendHeader (
- HttpWorkerRequest.HeaderTransferEncoding,
- "chunked");
- } else {
- // Just in case, the old browsers sends a HTTP/1.0
- // request with Connection: Keep-Alive
- AppendHeader (
- HttpWorkerRequest.HeaderConnection,
- "Close");
+ long length = _Writer.BufferSize;
+ if (!_bHeadersSent && !_bSuppressHeaders) {
+ if (bFinish) {
+ if (length == 0 && _lContentLength == 0)
+ _sContentType = null;
+
+ SendHeaders ();
+ length = _Writer.BufferSize;
+ if (length != 0)
+ _WorkerRequest.SendCalculatedContentLength ((int) length);
+ } else {
+ if (_lContentLength == 0 && _iStatusCode == 200 &&
+ _sTransferEncoding == null) {
+ // Check we are going todo chunked encoding
+ string sProto = Request.ServerVariables ["SERVER_PROTOCOL"];
+ sProto = "HTTP/1.0"; // Remove this line when we support properly
+ // chunked content
+
+ if (sProto != null && sProto == "HTTP/1.1") {
+ AppendHeader (
+ HttpWorkerRequest.HeaderTransferEncoding,
+ "chunked");
+ } else {
+ // Just in case, the old browsers send a HTTP/1.0
+ // request with Connection: Keep-Alive
+ AppendHeader (
+ HttpWorkerRequest.HeaderConnection,
+ "Close");
+ }
}
+ length = _Writer.BufferSize;
SendHeaders ();
- }
+ }
}
- if ((!_bSuppressContent && Request.HttpMethod == "HEAD") || _Writer == null) {
- _bSuppressContent = true;
+
+ if (!filtered) {
+ _Writer.FilterData (false);
+ length = _Writer.BufferSize;
}
+ if (length == 0) {
+ _WorkerRequest.FlushResponse (bFinish);
+ if (!bFinish)
+ _Writer.Clear ();
+ return;
+ }
+
+ if (!_bSuppressContent && Request.HttpMethod == "HEAD")
+ _bSuppressContent = true;
+
if (!_bSuppressContent) {
_bClientDisconnected = false;
if (_bChunked) {
} else {
_Writer.SendContent (_WorkerRequest);
}
+ } else {
+ _Writer.Clear ();
+ }
- _WorkerRequest.FlushResponse (bFinish);
+ _WorkerRequest.FlushResponse (bFinish);
- if (!bFinish)
- _Writer.Clear ();
- }
+ if (!bFinish)
+ _Writer.Clear ();
} finally {
_bFlushing = false;
}
Redirect (url, true);
}
- //FIXME: [1] this is an ugly hack to make it work until we have SimpleWorkerRequest!
- private string redirectLocation;
- public string RedirectLocation
- {
- get {
- return redirectLocation;
- }
- }
-
public void Redirect (string url, bool endResponse)
{
if (_bHeadersSent)
Clear ();
+ url = ApplyAppPathModifier (url);
StatusCode = 302;
- redirectLocation = url;
- //[1]AppendHeader(HttpWorkerRequest.HeaderLocation, url);
+ AppendHeader (HttpWorkerRequest.HeaderLocation, url);
// Text for browsers that can't handle location header
Write ("<html><head><title>Object moved</title></head><body>\r\n");
Write ("<h2>Object moved to <a href='" + url + "'>here</a></h2>\r\n");
Write ("</body><html>\r\n");
- /* [1]
- if (endResponse) {
- End();
- }
- */
+ if (endResponse)
+ End ();
}
public void Write (char ch)
throw new NotImplementedException ();
}
- [MonoTODO()]
public void SetCookie (HttpCookie cookie)
{
- throw new NotImplementedException ();
+ if (_bHeadersSent)
+ throw new HttpException ("Cannot append cookies after HTTP headers have been sent");
+
+ Cookies.Add (cookie);
}
private void WriteFromStream (Stream stream, long offset, long length, long bufsize)