ClientHttpSessionFactory.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2006-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00023 #include "Qt.h"
00024 #include "ClientHttpSessionFactory.h"
00025 #include "ConcreteProtocol.h"
00026 #include "DataSerializer.h"
00027 #include "CompositeSingleHostClientHttpSession.h"
00028 #include "Imports.cpp"
00029 
00031 
00035 ClientHttpSessionFactory::ClientHttpSessionFactory (TransportFactory
00036                                                         *transportFactory)
00037  :  transportFactory_ (transportFactory)
00038 {
00039 }
00040 
00042 
00051 ClientHttpSessionFactory::~ClientHttpSessionFactory()
00052 {
00053     if (!establishingSessions_.empty())
00054         qDebug() << "Destroying ClientHttpSession while some sessions "
00055                     "are still being established! LEAKING MEMORY";
00056     if (!sessions_.empty())
00057         qDebug() << "Destroying ClientHttpSession before all established "
00058                     "sessions are destroyed! LEAKING MEMORY";
00059 /*  foreach (EstablishingSession *session, establishingSessions_)
00060         delete session;
00061     establishingSessions_.clear();
00062 
00063     // \todo in which order to destroy transport and session?
00064     // if transport's dtor does not invoke anything on its status (session in
00065     // this case), then it is better to delete transport after session
00066     foreach (ClientHttpSession *session, sessions_.keys())
00067         delete session;
00068     foreach (Transport *transport, sessions_.values())
00069         transportFactory_->destroyTransport (transport);
00070     sessions_.clear();*/
00071 }
00072 
00074 
00087 ClientHttpSession *
00088 ClientHttpSessionFactory::createSession (Transport *transport,
00089                                          ClientHttpSessionStatus *status)
00090 {
00091     auto_ptr <ClientHttpSession> session
00092         (new CompositeSingleHostClientHttpSession (transport,
00093                                                    status));
00094     sessions_.insert (session.get(), transport);
00095     return session.release();
00096 }
00097 
00099 
00109 void ClientHttpSessionFactory::createSession (const Uri &uri,
00110                                 ClientHttpSessionStatus *sessionStatus,
00111                                 ClientHttpSessionFactoryStatus *factoryStatus)
00112 {
00113     Uri transportUri = makeTransportUri (uri);
00114     if (transportUri == Uri()) {
00115         factoryStatus->clientHttpSessionFactoryFailed (uri);
00116     } else {
00117         auto_ptr <EstablishingSession> session (new EstablishingSession);
00118         session->uri = uri;
00119         session->sessionStatus = sessionStatus;
00120         session->factoryStatus = factoryStatus;
00121         establishingSessions_.insert (transportUri, session.get());
00122         session.release();
00123         transportFactory_->createTransport (transportUri, this);
00124     }
00125 }
00126 
00128 
00135 void ClientHttpSessionFactory::destroySession (ClientHttpSession *session)
00136 {
00137     Q_ASSERT (session != 0);
00138     Q_ASSERT (sessions_.contains (session));
00139     Transport *transport = sessions_.take (session);
00140     // \todo transport may call status->abort() thus jumping in session
00141     transportFactory_->destroyTransport (transport);
00142     delete session;
00143 }
00144 
00146 
00153 void
00154 ClientHttpSessionFactory::transportFactorySucceeded (const Uri &transportUri,
00155                                                      Transport *transport)
00156 {
00157     Q_ASSERT (establishingSessions_.contains (transportUri));
00158     Q_ASSERT (transport != 0);
00159     auto_ptr <EstablishingSession> session;
00160     session.reset (establishingSessions_.take (transportUri));
00161     ClientHttpSession *httpSession = createSession (transport,
00162                                                     session->sessionStatus);
00163     session->factoryStatus->clientHttpSessionFactorySucceeded (session->uri,
00164                                                                httpSession);
00165 }
00166 
00168 
00174 void ClientHttpSessionFactory::transportFactoryFailed (const Uri &transportUri)
00175 {
00176     Q_ASSERT (establishingSessions_.contains (transportUri));
00177     auto_ptr <EstablishingSession> session;
00178     session.reset (establishingSessions_.take (transportUri));
00179     session->factoryStatus->clientHttpSessionFactoryFailed (session->uri);
00180 }
00181 
00183 
00191 Uri ClientHttpSessionFactory::makeTransportUri (const Uri &uri)
00192 {
00193     Uri res;
00194     if (uri.scheme() == "http")
00195         return makeTcpUriFromHttpUri (uri);
00196     //else if (uri.scheme() == "https")
00197     //  return makeTcpUriFromHttpsUri (uri);
00198     else
00199         return Uri();
00200 }
00201 
00203 
00206 Uri ClientHttpSessionFactory::makeTcpUriFromHttpUri (const Uri &uri)
00207 {
00208     Uri res;
00209     res.setScheme ("tcp");
00210     // Set host and port:
00211     if (uri.port().isEmpty())
00212         res.setAuthority (QByteArray(), uri.host(), "80");
00213     else
00214         res.setAuthority (QByteArray(), uri.host(), uri.port());
00215     // Set read buffer (rb) and write buffer (wb) sizes:
00216     res.appendQueryItem ("rb", "8192");
00217     res.appendQueryItem ("wb", "8192");
00218     return res;
00219 }