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

# HttpConnection.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 "HttpConnection.h"
    00028 #include "HttpMessage.h"
    00029 #include "HtmlBuilder.h"
    00030 #include "Session.h"
    00031 #include "Utility.h"
    00032
    00033 using namespace HTML;
    00034
    00035 namespace FIX
    00036 {
    00037 HttpConnection::HttpConnection( int s )
    00038 : m_socket( s )
    00039 {
    00040   FD_ZERO( &m_fds );
    00041   FD_SET( m_socket, &m_fds );
    00042 }
    00043
    00044 bool HttpConnection::send( const std::string& msg )
    00045 { QF_STACK_PUSH(HttpConnection::send)
    00046   return socket_send( m_socket, msg.c_str(), msg.length() ) >= 0;
    00047   QF_STACK_POP
    00048 }
    00049
    00050 void HttpConnection::disconnect( int error )
    00051 { QF_STACK_PUSH(HttpConnection::disconnect)
    00052
    00053   if( error > 0 )
    00054     send( HttpMessage::createResponse(error) );
    00055
    00056   socket_close( m_socket );
    00057
    00058   QF_STACK_POP
    00059 }
    00060
    00061 bool HttpConnection::read()
    00062 { QF_STACK_PUSH(HttpConnection::read)
    00063
    00064   struct timeval timeout = { 2, 0 };
    00065   fd_set readset = m_fds;
    00066
    00067   try
    00068   {
    00069     // Wait for input (1 second timeout)
    00070     int result = select( 1 + m_socket, &readset, 0, 0, &timeout );
    00071
    00072     if( result > 0 ) // Something to read
    00073     {
    00074       // We can read without blocking
    00075       int size = recv( m_socket, m_buffer, sizeof(m_buffer), 0 );
    00076       if ( size <= 0 ) { throw SocketRecvFailed( size ); }
    00077       m_parser.addToStream( m_buffer, size );
    00078     }
    00079     else if( result == 0 ) // Timeout
    00080     {
    00081       disconnect( 408 );
    00082       return false;
    00083     }
    00084     else if( result < 0 ) // Error
    00085     {
    00086       throw SocketRecvFailed( result );
    00087     }
    00088
    00089     processStream();
    00090     return true;
    00091   }
    00092   catch ( SocketRecvFailed& )
    00093   {
    00094     disconnect();
    00095     return false;
    00096   }
    00097
    00098   QF_STACK_POP
    00099 }
    00100
    00101 bool HttpConnection::readMessage( std::string& msg )
    00102 throw( SocketRecvFailed )
    00103 { QF_STACK_PUSH(HttpConnection::readMessage)
    00104
    00105   try
    00106   {
    00107     return m_parser.readHttpMessage( msg );
    00108   }
    00109   catch ( MessageParseError& )
    00110   {
    00111     disconnect( 400 );
    00112   }
    00113   return true;
    00114
    00115   QF_STACK_POP
    00116 }
    00117
    00118 void HttpConnection::processStream()
    00119 { QF_STACK_PUSH(HttpConnection::processStream)
    00120
    00121   std::string msg;
    00122   try
    00123   {
    00124     if( !readMessage(msg) )
    00125       return;
    00126     HttpMessage request( msg );
    00127     processRequest( request );
    00128   }
    00129   catch( InvalidMessage& )
    00130   {
    00131     disconnect( 400 );
    00132     return;
    00133   }
    00134
    00135   return;
    00136
    00137   QF_STACK_POP
    00138 }
    00139
    00140 void HttpConnection::processRequest( const HttpMessage& request )
    00141 { QF_STACK_PUSH(HttpConnection::processRequest)
    00142
    00143   int error = 200;
    00144   std::stringstream h;
    00145   std::stringstream b;
    00146   std::string titleString = "QuickFIX Engine Web Interface";
    00147
    00148   { HEAD head(h); head.text();
    00149     { CENTER center(h); center.text();
    00150       { TITLE title(h); title.text(titleString); }
    00151       { H1 h1(h); h1.text(titleString); }
    00152     }
    00153     { CENTER center(h); center.text();
    00154       { A a(h); a.href("/").text("HOME"); }
    00155       h << NBSP;
    00156       { A a(h); a.href(request.toString()).text("RELOAD"); }
    00157     }
    00158     HR hr(h); hr.text();
    00159   }
    00160
    00161   BODY body(b); body.text();
    00162
    00163   try
    00164   {
    00165     if( request.getRootString() == "/" )
    00166       processRoot( request, h, b );
    00167     else if( request.getRootString() == "/resetSessions" )
    00168       processResetSessions( request, h, b );
    00169     else if( request.getRootString() == "/refreshSessions" )
    00170       processRefreshSessions( request, h, b );
    00171     else if( request.getRootString() == "/enableSessions" )
    00172       processEnableSessions( request, h, b );
    00173     else if( request.getRootString() == "/disableSessions" )
    00174       processDisableSessions( request, h, b );
    00175     else if( request.getRootString() == "/session" )
    00176       processSession( request, h, b );
    00177     else if( request.getRootString() == "/resetSession" )
    00178       processResetSession( request, h, b );
    00179     else if( request.getRootString() == "/refreshSession" )
    00180       processRefreshSession( request, h, b );
    00181     else
    00182       error = 404;
    00183   }
    00184   catch( std::exception& e )
    00185   {
    00186     error = 400;
    00187     b << e.what();
    00188   }
    00189
    00190   std::string response = "<HTML>" + h.str() + b.str() + "</HTML>";
    00191   send( HttpMessage::createResponse(error, error == 200 ? response : "") );
    00192
    00193   disconnect();
    00194
    00195   QF_STACK_POP
    00196 }
    00197
    00198 void HttpConnection::processRoot
    00199 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00200 { QF_STACK_PUSH(HttpConnection::processRoot)
    00201
    00202   TABLE table(b); table.border(1).cellspacing(2).width(100).text();
    00203
    00204   { CAPTION caption(b); caption.text();
    00205     EM em(b); em.text();
    00206     b << Session::numSessions() << " Sessions managed by QuickFIX";
    00207     { HR hr(b); hr.text(); }
    00208     { b << NBSP; A a(b); a.href("/resetSessions" + request.getParameterString()).text("RESET"); }
    00209     { b << NBSP; A a(b); a.href("/refreshSessions" + request.getParameterString()).text("REFRESH"); }
    00210     { b << NBSP; A a(b); a.href("/enableSessions" + request.getParameterString()).text("ENABLE"); }
    00211     { b << NBSP; A a(b); a.href("/disableSessions" + request.getParameterString()).text("DISABLE"); }
    00212   }
    00213
    00214   { TR tr(b); tr.text();
    00215     { TD td(b); td.align("center").text("Session"); }
    00216     { TD td(b); td.align("center").text("ConnectionType"); }
    00217     { TD td(b); td.align("center").text("Enabled"); }
    00218     { TD td(b); td.align("center").text("Session Time"); }
    00219     { TD td(b); td.align("center").text("Logged On"); }
    00220     { TD td(b); td.align("center").text("Next Incoming"); }
    00221     { TD td(b); td.align("center").text("Next Outgoing"); }
    00222   }
    00223
    00224   std::set<SessionID> sessions = Session::getSessions();
    00225   std::set<SessionID>::iterator i;
    00226   for( i = sessions.begin(); i != sessions.end(); ++i )
    00227   {
    00228     Session* pSession = Session::lookupSession( *i );
    00229     if( !pSession ) continue;
    00230
    00231     { TR tr(b); tr.text();
    00232       { TD td(b); td.text();
    00233         std::string href = "/session?BeginString=" + i->getBeginString().getValue() +
    00234                             "&SenderCompID=" + i->getSenderCompID().getValue() +
    00235                             "&TargetCompID=" + i->getTargetCompID().getValue();
    00236         if( i->getSessionQualifier().size() )
    00237           href += "&SessionQualifier=" + i->getSessionQualifier();
    00238
    00239         A a(b); a.href(href).text(i->toString());
    00240       }
    00241       { TD td(b); td.text(pSession->isInitiator() ? "initiator" : "acceptor"); }
    00242       { TD td(b); td.text(pSession->isEnabled() ? "yes" : "no"); }
    00243       { TD td(b); td.text(pSession->isSessionTime(UtcTimeStamp()) ? "yes" : "no"); }
    00244       { TD td(b); td.text(pSession->isLoggedOn() ? "yes" : "no"); }
    00245       { TD td(b); td.text(pSession->getExpectedTargetNum()); }
    00246       { TD td(b); td.text(pSession->getExpectedSenderNum()); }
    00247     }
    00248   }
    00249
    00250   QF_STACK_POP
    00251 }
    00252
    00253 void HttpConnection::processResetSessions
    00254 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00255 { QF_STACK_PUSH(HttpConnection::processResetSessions)
    00256
    00257   try
    00258   {
    00259     HttpMessage copy = request;
    00260
    00261     bool confirm = false;
    00262     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00263     {
    00264       confirm = true;
    00265       std::set<SessionID> sessions = Session::getSessions();
    00266       std::set<SessionID>::iterator session;
    00267       for( session = sessions.begin(); session != sessions.end(); ++session )
    00268         Session::lookupSession( *session )->reset();
    00269       copy.removeParameter("confirm");
    00270     }
    00271
    00272     if( confirm )
    00273     {
    00274       h << "<META http-equiv='refresh' content=2;URL='" << "/'>";
    00275       CENTER center(b); center.text();
    00276       H2 h2(b); h2.text();
    00277       { A a(b); a.href("/").text("Sessions"); }
    00278       b << " have been reset";
    00279     }
    00280     else
    00281     {
    00282       { CENTER center(b); center.text();
    00283         H2 h2(b); h2.text();
    00284         b << "Are you sure you want to reset all sessions ?";
    00285       }
    00286       { CENTER center(b); center.text();
    00287         b << "[";
    00288         { A a(b); a.href(request.toString() + "?confirm=1").text("YES, reset sessions"); }
    00289         b << "]" << NBSP << "[";
    00290         { A a(b); a.href("/").text("NO, do not reset sessions"); }
    00291         b << "]";
    00292       }
    00293     }
    00294   }
    00295   catch( std::exception& e )
    00296   {
    00297     b << e.what();
    00298   }
    00299
    00300   QF_STACK_POP
    00301 }
    00302
    00303 void HttpConnection::processRefreshSessions
    00304 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00305 { QF_STACK_PUSH(HttpConnection::processRefreshSessions)
    00306
    00307   try
    00308   {
    00309     HttpMessage copy = request;
    00310
    00311     bool confirm = false;
    00312     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00313     {
    00314       confirm = true;
    00315       std::set<SessionID> sessions = Session::getSessions();
    00316       std::set<SessionID>::iterator session;
    00317       for( session = sessions.begin(); session != sessions.end(); ++session )
    00318         Session::lookupSession( *session )->refresh();
    00319       copy.removeParameter("confirm");
    00320     }
    00321
    00322     if( confirm )
    00323     {
    00324       h << "<META http-equiv='refresh' content=2;URL='" << "/'>";
    00325       CENTER center(b); center.text();
    00326       H2 h2(b); h2.text();
    00327       { A a(b); a.href("/").text("Sessions"); }
    00328       b << " have been refreshed";
    00329     }
    00330     else
    00331     {
    00332       { CENTER center(b); center.text();
    00333         H2 h2(b); h2.text();
    00334         b << "Are you sure you want to refresh all sessions ?";
    00335       }
    00336       { CENTER center(b); center.text();
    00337         b << "[";
    00338         { A a(b); a.href(request.toString() + "?confirm=1").text("YES, refresh sessions"); }
    00339         b << "]" << NBSP << "[";
    00340         { A a(b); a.href("/").text("NO, do not refresh sessions"); }
    00341         b << "]";
    00342       }
    00343     }
    00344   }
    00345   catch( std::exception& e )
    00346   {
    00347     b << e.what();
    00348   }
    00349
    00350   QF_STACK_POP
    00351 }
    00352
    00353 void HttpConnection::processEnableSessions
    00354 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00355 { QF_STACK_PUSH(HttpConnection::processEnableSessions)
    00356
    00357   try
    00358   {
    00359     HttpMessage copy = request;
    00360
    00361     bool confirm = false;
    00362     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00363     {
    00364       confirm = true;
    00365       std::set<SessionID> sessions = Session::getSessions();
    00366       std::set<SessionID>::iterator session;
    00367       for( session = sessions.begin(); session != sessions.end(); ++session )
    00368         Session::lookupSession( *session )->logon();
    00369       copy.removeParameter("confirm");
    00370     }
    00371
    00372     if( confirm )
    00373     {
    00374       h << "<META http-equiv='refresh' content=2;URL='" << "/'>";
    00375       CENTER center(b); center.text();
    00376       H2 h2(b); h2.text();
    00377       { A a(b); a.href("/").text("Sessions"); }
    00378       b << " have been enabled";
    00379     }
    00380     else
    00381     {
    00382       { CENTER center(b); center.text();
    00383         H2 h2(b); h2.text();
    00384         b << "Are you sure you want to enable all sessions ?";
    00385       }
    00386       { CENTER center(b); center.text();
    00387         b << "[";
    00388         { A a(b); a.href(request.toString() + "?confirm=1").text("YES, enable sessions"); }
    00389         b << "]" << NBSP << "[";
    00390         { A a(b); a.href("/").text("NO, do not enable sessions"); }
    00391         b << "]";
    00392       }
    00393     }
    00394   }
    00395   catch( std::exception& e )
    00396   {
    00397     b << e.what();
    00398   }
    00399
    00400   QF_STACK_POP
    00401 }
    00402
    00403 void HttpConnection::processDisableSessions
    00404 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00405 { QF_STACK_PUSH(HttpConnection::processDisableSessions)
    00406
    00407   try
    00408   {
    00409     HttpMessage copy = request;
    00410
    00411     bool confirm = false;
    00412     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00413     {
    00414       confirm = true;
    00415       std::set<SessionID> sessions = Session::getSessions();
    00416       std::set<SessionID>::iterator session;
    00417       for( session = sessions.begin(); session != sessions.end(); ++session )
    00418         Session::lookupSession( *session )->logout();
    00419       copy.removeParameter("confirm");
    00420     }
    00421
    00422     if( confirm )
    00423     {
    00424       h << "<META http-equiv='refresh' content=2;URL='" << "/'>";
    00425       CENTER center(b); center.text();
    00426       H2 h2(b); h2.text();
    00427       { A a(b); a.href("/").text("Sessions"); }
    00428       b << " have been disabled";
    00429     }
    00430     else
    00431     {
    00432       { CENTER center(b); center.text();
    00433         H2 h2(b); h2.text();
    00434         b << "Are you sure you want to disable all sessions ?";
    00435       }
    00436       { CENTER center(b); center.text();
    00437         b << "[";
    00438         { A a(b); a.href(request.toString() + "?confirm=1").text("YES, disable sessions"); }
    00439         b << "]" << NBSP << "[";
    00440         { A a(b); a.href("/").text("NO, do not disable sessions"); }
    00441         b << "]";
    00442       }
    00443     }
    00444   }
    00445   catch( std::exception& e )
    00446   {
    00447     b << e.what();
    00448   }
    00449
    00450   QF_STACK_POP
    00451 }
    00452
    00453 void HttpConnection::processSession
    00454 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00455 { QF_STACK_PUSH(HttpConnection::processSession)
    00456
    00457   try
    00458   {
    00459     HttpMessage copy = request;
    00460     std::string url = request.toString();
    00461     std::string beginString = copy.getParameter( "BeginString" );
    00462     std::string senderCompID = copy.getParameter( "SenderCompID" );
    00463     std::string targetCompID = copy.getParameter( "TargetCompID" );
    00464     std::string sessionQualifier;
    00465     if( copy.hasParameter("SessionQualifier") )
    00466       sessionQualifier = copy.getParameter( "SessionQualifier" );
    00467
    00468     SessionID sessionID( beginString, senderCompID, targetCompID, sessionQualifier );
    00469     Session* pSession = Session::lookupSession( sessionID );
    00470     if( pSession == 0 ) throw SessionNotFound();
    00471
    00472     if( copy.hasParameter("Enabled") )
    00473     {
    00474       copy.getParameter("Enabled") == "0" ? pSession->logout() : pSession->logon();
    00475       copy.removeParameter("Enabled");
    00476     }
    00477     if( copy.hasParameter("Next%20Incoming") )
    00478     {
    00479       int value = IntConvertor::convert( copy.getParameter("Next%20Incoming") );
    00480       pSession->setNextTargetMsgSeqNum( value <= 0 ? 1 : value );
    00481       copy.removeParameter("Next%20Incoming");
    00482     }
    00483     if( copy.hasParameter("Next%20Outgoing") )
    00484     {
    00485       int value = IntConvertor::convert( copy.getParameter("Next%20Outgoing") );
    00486       pSession->setNextSenderMsgSeqNum( value <= 0 ? 1 : value );
    00487       copy.removeParameter("Next%20Outgoing");
    00488     }
    00489     if( copy.hasParameter(SEND_REDUNDANT_RESENDREQUESTS) )
    00490     {
    00491       pSession->setSendRedundantResendRequests( copy.getParameter(SEND_REDUNDANT_RESENDREQUESTS) != "0" );
    00492       copy.removeParameter(SEND_REDUNDANT_RESENDREQUESTS);
    00493     }
    00494     if( copy.hasParameter(CHECK_COMPID) )
    00495     {
    00496       pSession->setCheckCompId( copy.getParameter(CHECK_COMPID) != "0" );
    00497       copy.removeParameter(CHECK_COMPID);
    00498     }
    00499     if( copy.hasParameter(CHECK_LATENCY) )
    00500     {
    00501       pSession->setCheckLatency( copy.getParameter(CHECK_LATENCY) != "0" );
    00502       copy.removeParameter(CHECK_LATENCY);
    00503     }
    00504     if( copy.hasParameter(MAX_LATENCY) )
    00505     {
    00506       int value = IntConvertor::convert( copy.getParameter(MAX_LATENCY) );
    00507       pSession->setMaxLatency( value <= 0 ? 1 : value );
    00508       copy.removeParameter(MAX_LATENCY);
    00509     }
    00510     if( copy.hasParameter(LOGON_TIMEOUT) )
    00511     {
    00512       int value = IntConvertor::convert( copy.getParameter(LOGON_TIMEOUT) );
    00513       pSession->setLogonTimeout( value <= 0 ? 1 : value );
    00514       copy.removeParameter(LOGON_TIMEOUT);
    00515     }
    00516     if( copy.hasParameter(LOGOUT_TIMEOUT) )
    00517     {
    00518       int value = IntConvertor::convert( copy.getParameter(LOGOUT_TIMEOUT) );
    00519       pSession->setLogoutTimeout( value <= 0 ? 1 : value );
    00520       copy.removeParameter(LOGOUT_TIMEOUT);
    00521     }
    00522     if( copy.hasParameter(RESET_ON_LOGON) )
    00523     {
    00524       pSession->setResetOnLogon( copy.getParameter(RESET_ON_LOGON) != "0" );
    00525       copy.removeParameter(RESET_ON_LOGON);
    00526     }
    00527     if( copy.hasParameter(RESET_ON_LOGOUT) )
    00528     {
    00529       pSession->setResetOnLogout( copy.getParameter(RESET_ON_LOGOUT) != "0" );
    00530       copy.removeParameter(RESET_ON_LOGOUT);
    00531     }
    00532     if( copy.hasParameter(RESET_ON_DISCONNECT) )
    00533     {
    00534       pSession->setResetOnDisconnect( copy.getParameter(RESET_ON_DISCONNECT) != "0" );
    00535       copy.removeParameter(RESET_ON_DISCONNECT);
    00536     }
    00537     if( copy.hasParameter(REFRESH_ON_LOGON) )
    00538     {
    00539       pSession->setRefreshOnLogon( copy.getParameter(REFRESH_ON_LOGON) != "0" );
    00540       copy.removeParameter(REFRESH_ON_LOGON);
    00541     }
    00542     if( copy.hasParameter(MILLISECONDS_IN_TIMESTAMP) )
    00543     {
    00544       pSession->setMillisecondsInTimeStamp( copy.getParameter(MILLISECONDS_IN_TIMESTAMP) != "0" );
    00545       copy.removeParameter(MILLISECONDS_IN_TIMESTAMP);
    00546     }
    00547     if( copy.hasParameter(PERSIST_MESSAGES) )
    00548     {
    00549       pSession->setPersistMessages( copy.getParameter(PERSIST_MESSAGES) != "0" );
    00550       copy.removeParameter(PERSIST_MESSAGES);
    00551     }
    00552
    00553     if( url != copy.toString() )
    00554       h << "<META http-equiv='refresh' content=0;URL='" << copy.toString() << "'>";
    00555
    00556     TABLE table(b); table.border(1).cellspacing(2).width(100).text();
    00557
    00558     { CAPTION caption(b); caption.text();
    00559       EM em(b); em.text();
    00560       b << sessionID;
    00561       { HR hr(b); hr.text(); }
    00562       { b << NBSP; A a(b); a.href("/resetSession" + copy.getParameterString()).text("RESET"); }
    00563       { b << NBSP; A a(b); a.href("/refreshSession" + copy.getParameterString()).text("REFRESH"); }
    00564     }
    00565
    00566     showRow( b, "Enabled", pSession->isEnabled(), url );
    00567     showRow( b, "ConnectionType", std::string(pSession->isInitiator() ?"initiator" : "acceptor") );
    00568     showRow( b, "SessionTime", pSession->isSessionTime(UtcTimeStamp()) );
    00569     showRow( b, "Logged On", pSession->isLoggedOn() );
    00570     showRow( b, "Next Incoming", (int)pSession->getExpectedTargetNum(), url );
    00571     showRow( b, "Next Outgoing", (int)pSession->getExpectedSenderNum(), url );
    00572     showRow( b, SEND_REDUNDANT_RESENDREQUESTS, pSession->getSendRedundantResendRequests(), url );
    00573     showRow( b, CHECK_COMPID, pSession->getCheckCompId(), url );
    00574     showRow( b, CHECK_LATENCY, pSession->getCheckLatency(), url );
    00575     showRow( b, MAX_LATENCY, pSession->getMaxLatency(), url );
    00576     showRow( b, LOGON_TIMEOUT, pSession->getLogonTimeout(), url );
    00577     showRow( b, LOGOUT_TIMEOUT, pSession->getLogoutTimeout(), url );
    00578     showRow( b, RESET_ON_LOGON, pSession->getResetOnLogon(), url );
    00579     showRow( b, RESET_ON_LOGOUT, pSession->getResetOnLogout(), url );
    00580     showRow( b, RESET_ON_DISCONNECT, pSession->getResetOnDisconnect(), url );
    00581     showRow( b, REFRESH_ON_LOGON, pSession->getRefreshOnLogon(), url );
    00582     showRow( b, MILLISECONDS_IN_TIMESTAMP, pSession->getMillisecondsInTimeStamp(), url );
    00583     showRow( b, PERSIST_MESSAGES, pSession->getPersistMessages(), url );
    00584   }
    00585   catch( std::exception& e )
    00586   {
    00587     b << e.what();
    00588   }
    00589
    00590   QF_STACK_POP
    00591 }
    00592
    00593 void HttpConnection::processResetSession
    00594 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00595 { QF_STACK_PUSH(HttpConnection::processResetSession)
    00596
    00597   try
    00598   {
    00599     HttpMessage copy = request;
    00600     std::string beginString = request.getParameter( "BeginString" );
    00601     std::string senderCompID = request.getParameter( "SenderCompID" );
    00602     std::string targetCompID = request.getParameter( "TargetCompID" );
    00603     std::string sessionQualifier;
    00604     if( copy.hasParameter("SessionQualifier") )
    00605       sessionQualifier = copy.getParameter( "SessionQualifier" );
    00606
    00607     SessionID sessionID( beginString, senderCompID, targetCompID, sessionQualifier );
    00608     Session* pSession = Session::lookupSession( sessionID );
    00609     if( pSession == 0 ) throw SessionNotFound();
    00610
    00611     std::string sessionUrl = "/session" + request.getParameterString();
    00612
    00613     bool confirm = false;
    00614     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00615     {
    00616       confirm = true;
    00617       pSession->reset();
    00618       copy.removeParameter("confirm");
    00619     }
    00620
    00621     if( confirm )
    00622     {
    00623       h << "<META http-equiv='refresh' content=2;URL='" << "/session" << copy.getParameterString() << "'>";
    00624       CENTER center(b); center.text();
    00625       H2 h2(b); h2.text();
    00626       { A a(b); a.href("/session" + copy.getParameterString()).text(sessionID.toString()); }
    00627       b << " has been reset";
    00628     }
    00629     else
    00630     {
    00631       { CENTER center(b); center.text();
    00632         H2 h2(b); h2.text();
    00633         b << "Are you sure you want to reset session ";
    00634         { A a(b); a.href(sessionUrl + request.getParameterString()).text(sessionID.toString()); }
    00635         b << "?";
    00636       }
    00637       { CENTER center(b); center.text();
    00638         b << "[";
    00639         { A a(b); a.href(request.toString() + "&confirm=1").text("YES, reset session"); }
    00640         b << "]" << NBSP << "[";
    00641         { A a(b); a.href(sessionUrl).text("NO, do not reset session"); }
    00642         b << "]";
    00643       }
    00644     }
    00645   }
    00646   catch( std::exception& e )
    00647   {
    00648     b << e.what();
    00649   }
    00650
    00651   QF_STACK_POP
    00652 }
    00653
    00654 void HttpConnection::processRefreshSession
    00655 ( const HttpMessage& request, std::stringstream& h, std::stringstream& b )
    00656 { QF_STACK_PUSH(HttpConnection::processRefreshSession)
    00657
    00658   try
    00659   {
    00660     HttpMessage copy = request;
    00661     std::string beginString = request.getParameter( "BeginString" );
    00662     std::string senderCompID = request.getParameter( "SenderCompID" );
    00663     std::string targetCompID = request.getParameter( "TargetCompID" );
    00664     std::string sessionQualifier;
    00665     if( copy.hasParameter("SessionQualifier") )
    00666     sessionQualifier = copy.getParameter( "SessionQualifier" );
    00667
    00668     SessionID sessionID( beginString, senderCompID, targetCompID, sessionQualifier );
    00669     Session* pSession = Session::lookupSession( sessionID );
    00670     if( pSession == 0 ) throw SessionNotFound();
    00671
    00672     std::string sessionUrl = "/session" + request.getParameterString();
    00673
    00674     bool confirm = false;
    00675     if( copy.hasParameter("confirm") && copy.getParameter("confirm") != "0" )
    00676     {
    00677       confirm = true;
    00678       pSession->refresh();
    00679       copy.removeParameter("confirm");
    00680     }
    00681
    00682     if( confirm )
    00683     {
    00684       h << "<META http-equiv='refresh' content=2;URL='" << "/session" << copy.getParameterString() << "'>";
    00685       CENTER center(b); center.text();
    00686       H2 h2(b); h2.text();
    00687       { A a(b); a.href("/session" + copy.getParameterString()).text(sessionID.toString()); }
    00688       b << " has been refreshed";
    00689     }
    00690     else
    00691     {
    00692       { CENTER center(b); center.text();
    00693         H2 h2(b); h2.text();
    00694         b << "Are you sure you want to refresh session ";
    00695         { A a(b); a.href(sessionUrl + request.getParameterString()).text(sessionID.toString()); }
    00696         b << "?";
    00697       }
    00698       { CENTER center(b); center.text();
    00699         b << "[";
    00700         { A a(b); a.href(request.toString() + "&confirm=1").text("YES, refresh session"); }
    00701         b << "]" << NBSP << "[";
    00702         { A a(b); a.href(sessionUrl).text("NO, do not refresh session"); }
    00703         b << "]";
    00704       }
    00705     }
    00706   }
    00707   catch( std::exception& e )
    00708   {
    00709     b << e.what();
    00710   }
    00711
    00712   QF_STACK_POP
    00713 }
    00714
    00715 void HttpConnection::showRow
    00716 ( std::stringstream& s, const std::string& name, bool value, const std::string& url )
    00717 { QF_STACK_PUSH(HttpConnection::showRow)
    00718
    00719     { TR tr(s); tr.text();
    00720       { TD td(s); td.text(name); }
    00721       { TD td(s); td.text(value ? "yes" : "no"); }
    00722       { TD td(s); td.text();
    00723         CENTER center(s); center.text();
    00724         if( url.size() )
    00725         {
    00726           std::stringstream href;
    00727           href << url << "&" << name << "=" << !value;
    00728           A a(s); a.href(href.str()).text("toggle");
    00729         }
    00730       }
    00731     }
    00732
    00733   QF_STACK_POP
    00734 }
    00735
    00736 void HttpConnection::showRow
    00737 ( std::stringstream& s, const std::string& name, const std::string& value, const std::string& url )
    00738 { QF_STACK_PUSH(HttpConnection::showRow)
    00739
    00740     { TR tr(s); tr.text();
    00741       { TD td(s); td.text(name); }
    00742       { TD td(s); td.text(value); }
    00743       { TD td(s); td.text();
    00744         CENTER center(s); center.text();
    00745       }
    00746     }
    00747
    00748   QF_STACK_POP
    00749 }
    00750
    00751 void HttpConnection::showRow
    00752 ( std::stringstream& s, const std::string& name, int value, const std::string& url )
    00753 { QF_STACK_PUSH(HttpConnection::showRow)
    00754
    00755     { TR tr(s); tr.text();
    00756       { TD td(s); td.text(name); }
    00757       { TD td(s); td.text(value); }
    00758       { TD td(s); td.text();
    00759         CENTER center(s); center.text();
    00760         {
    00761           std::stringstream href;
    00762           href << url << "&" << name << "=" << value - 10;
    00763           A a(s); a.href(href.str()).text("<<");
    00764         }
    00765         s << NBSP;
    00766         {
    00767           std::stringstream href;
    00768           href << url << "&" << name << "=" << value - 1;
    00769           A a(s); a.href(href.str()).text("<");
    00770         }
    00771         s << NBSP << "|" << NBSP;
    00772         {
    00773           std::stringstream href;
    00774           href << url << "&" << name << "=" << value + 1;
    00775           A a(s); a.href(href.str()).text(">");
    00776         }
    00777         s << NBSP;
    00778         {
    00779           std::stringstream href;
    00780           href << url << "&" << name << "=" << value + 10;
    00781           A a(s); a.href(href.str()).text(">>");
    00782         }
    00783       }
    00784     }
    00785
    00786   QF_STACK_POP
    00787 }
    00788
    00789 } // namespace FIX