// http://en.wikipedia.org/wiki/Internet_media_type internal void SendGenericWebResponse( byte[] Buffer, ulong ModifiedIndex, ulong UniqueEntity, string ContentType ) { if( Client == null ) return; try { // Set the initial UniqueEntity to the current date time index and then just // keep incrementing it. ECTime RightNow = new ECTime(); RightNow.SetToNow(); ECTime ExpireTime = new ECTime(); ExpireTime.SetToNow(); ExpireTime.AddSeconds( 120 ); ECTime ModifiedTime = new ECTime( ModifiedIndex ); // ETag is an Entity Tag. // "An entity tag MUST be unique across all versions of all entities // associated with a particular resource." string Header = "HTTP/1.1 200 OK\r\n" + "Date: " + RightNow.GetHTTPHeaderDateTime() + "\r\n" + "Server: Eric Example\r\n" + "Last-Modified: " + ModifiedTime.GetHTTPHeaderDateTime() + "\r\n" + "ETag: " + UniqueEntity.ToString() + "\r\n" + "Accept-Ranges: bytes\r\n" + "Content-Length: " + Buffer.Length.ToString() + "\r\n" + // "Cache-Control: max-age=5184000 "Expires: " + ExpireTime.GetHTTPHeaderDateTime() + "\r\n" + "Keep-Alive: timeout=5, max=100\r\n" + "Connection: Keep-Alive\r\n" + "Content-Type: " + ContentType + "\r\n" + "\r\n"; // Empty line and then the actual bytes. byte[] HeaderBytes = UTF8Strings.StringToBytes( Header ); if( HeaderBytes == null ) return; byte[] AllSendBytes; if( GetIsHeadOnly() ) AllSendBytes = new byte[HeaderBytes.Length]; else AllSendBytes = new byte[HeaderBytes.Length + Buffer.Length]; int Where = 0; for( int Count = 0; Count < HeaderBytes.Length; Count++ ) { AllSendBytes[Where] = HeaderBytes[Count]; Where++; } if( !GetIsHeadOnly() ) { for( int Count = 0; Count < Buffer.Length; Count++ ) { AllSendBytes[Where] = Buffer[Count]; Where++; } } // This returns immediately. WriteBytesAsync( AllSendBytes ); } catch( Exception Except ) { MForm.ShowStatus( "Exception in SendHTMLOrText():" ); MForm.ShowStatus( Except.Message ); } }
internal void CloseTimedOut() { ECTime OldTime = new ECTime(); OldTime.SetToNow(); //////////////////////// OldTime.AddSeconds( -4 ); ECTime OldWebTime = new ECTime(); OldWebTime.SetToNow(); // Browsers that are cooperative don't open too many connections at once. // Denial of service people will. // This delay makes browsers that are cooperative hold off on sending more // requests until they've closed some sockets. // Apparently this is the operating system that is being cooperative. // And if this server is too busy it's not going to be calling this // function to close it until it can get around to it. // So cooperative web clients will wait. OldWebTime.AddSeconds( -0.1 ); // OldWebTime.AddSeconds( 10 ); // If I put it 10 seconds in the _future_ it works. // OldWebTime.AddSeconds( -10 ); // The socket is setting LastTransactTime when AsyncResult.IsCompleted. // So it's setting it when the socket thinks it's done sending it. ulong OldIndex = OldTime.GetIndex(); ulong OldWebIndex = OldWebTime.GetIndex(); for( int Count = 0; Count < ClientsLast; Count++ ) { if( Clients[Count] == null ) // This should never happen but... continue; if( Clients[Count].IsShutDown()) continue; /* // Close a web request only after it has started processing the request. if( Clients[Count].GetProcessingStarted()) { if( Clients[Count].GetIsAWebRequest()) { if( Clients[Count].GetLastTransactTimeIndex() < OldWebIndex ) { if( Clients[Count].IsProcessingInBackground()) { // ShowStatus( " " ); // ShowStatus( "Web request is still sending." ); // MForm.ServerLog.AddToLog( "Web Still Sending", "Nada", Clients[Count].GetRemoteAddress() ); } Clients[Count].FreeEverything(); } } } */ // If it's more recent than the old index then it's OK. if( Clients[Count].GetLastTransactTimeIndex() > OldIndex ) continue; /* // If this message has not already been processed. if( !Clients[Count].GetProcessingStarted()) { string InputS = Utility.GetCleanUnicodeString( Clients[Count].GetAllInputS(), 2000 ); InputS = InputS.Trim(); if( InputS.Length > 0 ) { // ShowStatus( "Timed out with: " + InputS ); } MForm.NetStats.AddToTimedOutCount( Clients[Count].GetRemoteAddress(), InputS ); } */ if( Clients[Count].IsProcessingInBackground()) { ShowStatus( " " ); ShowStatus( "**************************************" ); ShowStatus( "Still sending after time out period." ); ShowStatus( "**************************************" ); ShowStatus( " " ); } // They normally time out. ShowStatus( "Closing timed out: " + Clients[Count].GetRemoteAddress()); Clients[Count].FreeEverything(); } }