/// <summary> /// On the stream being compressed. /// </summary> protected void StartSendStream(MemoryStream stream, WebResource resource) { // replace the resource stream with the compressed bytes resource.ReplaceStreamLocked(stream, _compression); SendHeaders((int)stream.Length); Log.Info("Sending stream of length '" + stream.Length + "' to client " + this + "."); // send the stream Socket.Send(stream, (int)stream.Length); stream.Dispose(); // is the callback set? if (_onSent != null) { // yes, run it var onSent = _onSent; _onSent = null; _lock.Release(); onSent.Run(); } else { // no, release the lock _lock.Release(); } }
/// <summary> /// On a web resource stream being compressed. /// </summary> protected void StartSendStream(MemoryStream stream, WebResource resource) { try { // replace the resource stream with the compressed bytes resource.ReplaceStreamLocked(stream, _header.Compression); // is the stream to be encrypted? yes, encrypt it if (_header.EncryptionPassword != null) { stream = Crypto.EncryptWithPassword(stream, _header.EncryptionPassword); } EnqueueHeader((int)stream.Length); // send the stream AsyncSocket.Enqueue(stream, (int)stream.Length); stream.Dispose(); AsyncSocket.Send(_onSent); _onSent = null; } finally { // release the lock _lock.Release(); } }
/// <summary> /// Begin sending the stream of a web resource and prepare to release the resource lock on completion. /// </summary> protected void SendResource(Stream stream, Lock resourceLock, WebResource resource, TransportOptions options, IAction onSent) { // was the stream retrieved? if (stream == null) { // no, unlock the resource resourceLock.Release(); // callback ProcessError(new Exception("A resource stream '" + resource.FullPath + "' was unable to be resolved.")); return; } _lock.Take(); if (onSent == null) { _onSent = new ActionSet(resourceLock.Release); } else { _onSent = new ActionPair(resourceLock.Release, onSent); } // set the content type ProcessOptions(options); int length = resource.Size == -1 ? (int)stream.Length : (int)resource.Size; // start sending the stream StartSendStream(stream, length, resource); }
/// <summary> /// On a resource wrapper being parsed. /// </summary> protected void OnWrapperParsed(ElementParser parser, HttpConnection client, WebResource resource) { // get the element that is to be replaced var content = parser.Root.Build(); // replace text where required string replaceString = "{ReplaceText(" + resource.MimeType + ")}"; int replaceIndex = content.IndexOf(replaceString, StringComparison.Ordinal); while (replaceIndex >= 0) { var sections = content.Split(replaceIndex, 0, replaceString.Length); content = sections.ArgA + resource.GetString() + sections.ArgB; replaceIndex = content.IndexOf(replaceString, StringComparison.Ordinal); } // replace source strings where required replaceString = "{ReplaceSource(" + resource.MimeType + ")}"; replaceIndex = content.IndexOf(replaceString, StringComparison.Ordinal); while (replaceIndex >= 0) { var sections = content.Split(replaceIndex, 0, replaceString.Length); content = sections.ArgA + resource.Path + sections.ArgB; replaceIndex = content.IndexOf(replaceString, StringComparison.Ordinal); } // just start sending the resource client.Send(parser.Root, true, _defaultSendOptions); }
/// <summary> /// Send the specified web resource. /// </summary> public void Send(WebResource resource, HttpSendOptions options = null, IAction onSent = null) { Log.Info("Sending web resource " + resource + " bytes to client " + this + "."); // get the resource stream then prepare to send the resource stream data resource.GetStream(ActionSet.New(SendResource, (Stream)null, (Lock)null, resource, options, onSent)); }
/// <summary> /// Send the specified web resource. /// </summary> public void Send(WebResource resource, TransportOptions options = null, IAction onSent = null) { // is disposed? if (_disposed) { Log.Warning("Cannot send from disposed connection."); return; } // get the resource stream then prepare to send the resource stream data resource.GetStream(ActionSet.New(SendResource, (Stream)null, (Lock)null, resource, options, onSent)); }
/// <summary> /// Start sending the stream. The client is locked until the stream is complete. /// </summary> protected void StartSendStream(Stream stream, int length, WebResource resource) { // yes, does the buffer need to be compressed? if (_defaultCompression == resource.Compression) { // send the headers with the stream length SendHeaders((int)stream.Length); Log.Info("Sending stream of length '" + length + "' to client " + this + "."); // no, the resource compression matches the required compression // send the stream Socket.Send(stream, length); // is the callback set? if (_onSent != null) { // yes, run it var onSent = _onSent; _onSent = null; _lock.Release(); onSent.Run(); } else { // no, release the lock _lock.Release(); } } else { // is the web resource compressed? if (resource.Compression != DecompressionMethods.None) { // yes, decompress the resource and replace the web resource stream resource.ReplaceStreamLocked(StreamHelper.Decompress(resource.Compression, stream, ref length), DecompressionMethods.None); } // yes, compress the bytes StreamHelper.Compress(Act.New(StartSendStream, (MemoryStream)null, resource), _defaultCompression, System.IO.Compression.CompressionLevel.Fastest, stream, length, false); } }
/// <summary> /// Start sending the stream. The client is locked until the stream is complete. /// </summary> protected void StartSendStream(Stream stream, int length, WebResource resource) { // yes, does the buffer need to be compressed? if (_defaultCompression == resource.Compression) { // no, the resource compression matches the required compression // is the stream to be encrypted? yes, encrypt it if (_header.EncryptionPassword != null) { stream = Crypto.EncryptWithPassword(stream, _header.EncryptionPassword); length = (int)stream.Length; } try { // send the headers with the stream length EnqueueHeader(length); // send the stream AsyncSocket.Enqueue(stream, length); AsyncSocket.Send(_onSent); } finally { _onSent = null; _lock.Release(); } } else { // is the web resource compressed? if (resource.Compression != DecompressionMethods.None) { // yes, decompress the resource and replace the web resource stream resource.ReplaceStreamLocked(StreamHelper.Decompress(resource.Compression, stream, ref length), DecompressionMethods.None); } // yes, compress the bytes StreamHelper.Compress(Act.New(StartSendStream, (MemoryStream)null, resource), _defaultCompression, System.IO.Compression.CompressionLevel.Fastest, stream, length, false); } }
/// <summary> /// Resolve the resource at the specified path. /// </summary> public virtual WebResource GetResource(string path) { // does the path indicate a directory? if (path.Length == 0 || path[path.Length - 1] == Chars.ForwardSlash) { // yes, get the default html page of that directory path = Fs.Combine(path, "default.html"); } // attempt to get the web resource from the cache WebResource resource = _cache.Get(path); // was the resource found in the cache? if (resource == null) { // no, create a new resource resource = new WebResource(this, path); // add the resource to the cache _cache.Add(path, resource); } return(resource); }
/// <summary> /// Begin sending the stream of a web resource and prepare to release the resource lock on completion. /// </summary> protected void SendResource(Stream stream, Lock resourceLock, WebResource resource, HttpSendOptions options, IAction onSent) { // was the stream retrieved? if (stream == null) { // no, unlock the resource resourceLock.Release(); // callback _client.OnErrorRoll.Run(new Exception("A resource stream '" + resource.FullPath + "' was unable to be resolved.")); return; } _lock.Take(); if (onSent == null) { _onSent = new ActionSet(resourceLock.Release); } else { _onSent = new ActionPair(resourceLock.Release, onSent); } // set the content type ProcessOptions(options); if (options == null) { Headers[HttpResponseHeader.ContentType] = resource.MimeType; } int length = resource.Size == -1 ? (int)stream.Length : (int)resource.Size; // start sending the stream StartSendStream(stream, length, resource); }
//----------------------------------// /// <summary> /// On a web request from a client. /// </summary> protected virtual void OnRequest(HttpRequest request) { // is the client allowed the specified resource? if (!ResolvePath(request)) { // no, is the not authenticated callback set? if (_onAccessDenied != null) { // yes, run it _onAccessDenied.Run(request); return; } // log the access denial Log.Warning("Access to unauthorized resource '" + request.RequestPath + "' from '" + request.Connection + "'."); // send the default error page to the client SendErrorPage(request.Connection, "Invalid page request '" + request.RequestPath + "'."); // skip the remaining process return; } // get the page web resource WebResource resource = GetResource(request.RequestPath); // dispose of the web request request.Dispose(); // is the resource valid? if (resource.Valid) { // yes, is there a default wrapper for the resource? if (_configuration["Wrappers"].DictionarySet) { // get the wrapper node for the resource mime type Node wrapperNode = _configuration["Wrappers"][resource.MimeType]; if (wrapperNode.Set) { // yes, get the default wrapper new ElementParser(ResolvePath(wrapperNode.String), new ActionSet <ElementParser, HttpConnection, WebResource>(OnWrapperParsed)).Run(); return; } } // just start sending the resource request.Connection.Send(resource); } else { // no, has the invalid resource callback been assigned? if (_onInvalidResource.Action != null) { // yes, run the callback _onInvalidResource.ArgA = request; _onInvalidResource.Run(); // skip error page return; } // send an error page in response SendErrorPage(request.Connection, "Invalid page request '" + resource.Path + "'"); } }