Index Source Files Annotated Class List Alphabetical Class List Class Hierarchy Graphical Class Hierarchy

# HttpServer.cpp

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 ** Copyright (c) quickfixengine.org  All rights reserved.
    00003 **
    00004 ** This file is part of the QuickFIX FIX Engine
    00005 **
    00006 ** This file may be distributed under the terms of the quickfixengine.org
    00007 ** license as defined by quickfixengine.org and appearing in the file
    00008 ** LICENSE included in the packaging of this file.
    00009 **
    00010 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
    00011 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
    00012 **
    00013 ** See http://www.quickfixengine.org/LICENSE for licensing information.
    00014 **
    00015 ** Contact ask@quickfixengine.org if any conditions of this licensing are
    00016 ** not clear to you.
    00017 **
    00018 ****************************************************************************/
    00019
    00020 #ifdef _MSC_VER
    00021 #include "stdafx.h"
    00022 #else
    00023 #include "config.h"
    00024 #endif
    00025 #include "CallStack.h"
    00026
    00027 #include "HttpServer.h"
    00028 #include "HttpConnection.h"
    00029 #include "Settings.h"
    00030 #include "Utility.h"
    00031
    00032 namespace FIX
    00033 {
    00034 Mutex HttpServer::s_mutex;
    00035 int HttpServer::s_count = 0;
    00036 HttpServer* HttpServer::s_pServer = 0;
    00037
    00038 void HttpServer::startGlobal( const SessionSettings& s )
    00039 throw ( ConfigError, RuntimeError )
    00040 {
    00041   Locker l( s_mutex );
    00042
    00043   if( !s.get().has(HTTP_ACCEPT_PORT) )
    00044     return;
    00045
    00046   s_count += 1;
    00047   if( !s_pServer )
    00048   {
    00049     s_pServer = new HttpServer( s );
    00050     s_pServer->start();
    00051   }
    00052 }
    00053
    00054 void HttpServer::stopGlobal()
    00055 {
    00056   Locker l( s_mutex );
    00057
    00058   s_count -= 1;
    00059   if( !s_count && s_pServer )
    00060   {
    00061     s_pServer->stop();
    00062     delete s_pServer;
    00063     s_pServer = 0;
    00064   }
    00065 }
    00066
    00067 HttpServer::HttpServer( const SessionSettings& settings ) throw( ConfigError )
    00068 : m_pServer( 0 ), m_settings( settings ), m_threadid( 0 ), m_port( 0 ), m_stop( false ) {}
    00069
    00070 void HttpServer::onConfigure( const SessionSettings& s )
    00071 throw ( ConfigError )
    00072 { QF_STACK_PUSH(HttpServer::onConfigure)
    00073   m_port = s.get().getLong( HTTP_ACCEPT_PORT );
    00074   QF_STACK_POP
    00075 }
    00076
    00077 void HttpServer::onInitialize( const SessionSettings& s )
    00078 throw ( RuntimeError )
    00079 { QF_STACK_PUSH(HttpServer::onInitialize)
    00080
    00081   try
    00082   {
    00083     m_pServer = new SocketServer( 1 );
    00084     m_pServer->add( m_port, true, false, 0, 0 );
    00085   }
    00086   catch( std::exception& )
    00087   {
    00088     throw RuntimeError( "Unable to create, bind, or listen to port " + IntConvertor::convert( (unsigned short)m_port ) );
    00089   }
    00090
    00091   QF_STACK_POP
    00092 }
    00093
    00094 void HttpServer::start() throw ( ConfigError, RuntimeError )
    00095 { QF_STACK_PUSH( Acceptor::start )
    00096
    00097   m_stop = false;
    00098   onConfigure( m_settings );
    00099   onInitialize( m_settings );
    00100
    00101   if( !thread_spawn( &startThread, this, m_threadid ) )
    00102     throw RuntimeError("Unable to spawn thread");
    00103
    00104   QF_STACK_POP
    00105 }
    00106
    00107 void HttpServer::stop()
    00108 { QF_STACK_PUSH( HttpServer::stop )
    00109
    00110   if( m_stop ) return;
    00111   m_stop = true;
    00112   onStop();
    00113
    00114   if( m_threadid )
    00115     thread_join( m_threadid );
    00116   m_threadid = 0;
    00117
    00118   QF_STACK_POP
    00119 }
    00120
    00121 void HttpServer::onStart()
    00122 { QF_STACK_PUSH(HttpServer::start)
    00123
    00124   while ( !m_stop && m_pServer && m_pServer->block( *this ) ) {}
    00125
    00126   if( !m_pServer )
    00127     return;
    00128
    00129   m_pServer->close();
    00130   delete m_pServer;
    00131   m_pServer = 0;
    00132
    00133   QF_STACK_POP
    00134 }
    00135
    00136 bool HttpServer::onPoll()
    00137 { QF_STACK_PUSH(HttpServer::onPoll)
    00138
    00139   if( !m_pServer || m_stop )
    00140     return false;
    00141
    00142   m_pServer->block( *this, true );
    00143   return true;
    00144
    00145   QF_STACK_POP
    00146 }
    00147
    00148 void HttpServer::onStop()
    00149 { QF_STACK_PUSH(HttpServer::onStop)
    00150   QF_STACK_POP
    00151 }
    00152
    00153 void HttpServer::onConnect( SocketServer& server, int a, int s )
    00154 { QF_STACK_PUSH(HttpServer::onConnect)
    00155
    00156   if ( !socket_isValid( s ) ) return;
    00157   HttpConnection connection( s );
    00158   while( connection.read() ) {}
    00159   m_pServer->getMonitor().drop( s );
    00160
    00161   QF_STACK_POP
    00162 }
    00163
    00164 void HttpServer::onWrite( SocketServer& server, int s )
    00165 { QF_STACK_PUSH(HttpServer::onWrite)
    00166   QF_STACK_POP
    00167 }
    00168
    00169 bool HttpServer::onData( SocketServer& server, int s )
    00170 { QF_STACK_PUSH(HttpServer::onData)
    00171
    00172   return true;
    00173
    00174   QF_STACK_POP
    00175 }
    00176
    00177 void HttpServer::onDisconnect( SocketServer&, int s )
    00178 { QF_STACK_PUSH(HttpServer::onDisconnect)
    00179   QF_STACK_POP
    00180 }
    00181
    00182 void HttpServer::onError( SocketServer& ) {}
    00183
    00184 void HttpServer::onTimeout( SocketServer& )
    00185 { QF_STACK_PUSH(HttpServer::onInitialize)
    00186   QF_STACK_POP
    00187 }
    00188
    00189 THREAD_PROC HttpServer::startThread( void* p )
    00190 { QF_STACK_TRY
    00191   QF_STACK_PUSH( HttpServer::startThread )
    00192
    00193   HttpServer * pServer = static_cast < HttpServer* > ( p );
    00194   pServer->onStart();
    00195   return 0;
    00196
    00197   QF_STACK_POP
    00198   QF_STACK_CATCH
    00199 }
    00200
    00201 }