fix tests (TODO filetransfer)
This commit is contained in:
parent
b9d0590c67
commit
20d8dd690e
1034
CMakeLists.txt
1034
CMakeLists.txt
File diff suppressed because it is too large
Load Diff
122
README.win32
122
README.win32
|
@ -1,61 +1,61 @@
|
|||
Prerequisites
|
||||
=============
|
||||
|
||||
1. Microsoft Visual C++ 2010 Express or higher edition (http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express)
|
||||
2. Git for Windows (http://code.google.com/p/msysgit/downloads/list)
|
||||
3. CMake 2.8 or newer (http://www.cmake.org/cmake/resources/software.html)
|
||||
4. Python 2.x for Swiften build scripts (scons) (http://www.python.org)
|
||||
|
||||
Libraries
|
||||
=========
|
||||
3. Swiften library (http://swift.im/git/swift)
|
||||
4. Boost 1.48 or newer (http://sourceforge.net/projects/boost/files/boost/1.49.0/)
|
||||
5. Google ProtoBuf library (http://code.google.com/p/protobuf/downloads/list)
|
||||
|
||||
|
||||
Environment
|
||||
===========
|
||||
|
||||
To create spectrum build environment do:
|
||||
|
||||
0. Create directory where we'll install all dependencies, e.g. C:\env-msvc-x64.
|
||||
Create C:\env-msvc-x64\bin and add it to %PATH%.
|
||||
Assuming you have git, python and cmake in %PATH%,
|
||||
launch "Visual Studio 2010 command prompt" or
|
||||
"Visual Studio 2010(x64) command prompt", depends on your target (Windows x86 or Windows x86_64).
|
||||
1. unpack and build boost libraries:
|
||||
|
||||
bootstrap.bat
|
||||
b2.exe --without-mpi --without-python
|
||||
b2.exe --without-mpi --without-python install --prefix=C:\env-msvc-x64 release
|
||||
|
||||
2. clone swift repository and build it. Don't forget to point it to our env directory:
|
||||
|
||||
git clone git://swift.im/swift
|
||||
cd swift
|
||||
echo boost_includedir="c:/env-msvc-x64/include/boost-1_49" > config.py
|
||||
echo boost_libdir="c:/env-msvc-x64/lib" >> config.py
|
||||
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 force_configure=1
|
||||
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 C:\env-msvc-x64
|
||||
|
||||
3. unpack and compile protobuf as described in its documentation.
|
||||
|
||||
Run extract_includes.bat in vsprojects/ directory and move resulting vsprojects/include/google/ directory to our C:\env-msvc-x64\include
|
||||
|
||||
Move protoc.exe to C:\env-msvc-x64\bin\ and libprotobuf.lib to C:\env-msvc-x64\lib
|
||||
|
||||
4. Install gtkmm
|
||||
|
||||
Download installer from https://live.gnome.org/gtkmm/MSWindows and install gtkmm into C:\env-msvc-x64\
|
||||
|
||||
5. Install libpurple headers
|
||||
|
||||
Download http://www.pidgin.im/download/source/ , extract it and copy libpurple directory in C:\env-msvc-x64\include
|
||||
|
||||
6. You're ready! :) Clone libtransport into C:\env-msvc-x64\libtransport (You *must* clone it into this directory, because libtransport will try to find the dependencies in ../lib and ../include)
|
||||
|
||||
Compile it as:
|
||||
|
||||
set CMAKE_INCLUDE_PATH=C:\env-msvc-x64\include
|
||||
cmake . -G "NMake Makefiles" -DBOOST_INCLUDEDIR=../include/boost-1_49 -DBOOST_LIBRARYDIR=../lib -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=C:\env-msvc-x64 -DGIT_EXECUTABLE="c:\Program Files (x86)\git\bin\git.exe"
|
||||
nmake
|
||||
Prerequisites
|
||||
=============
|
||||
|
||||
1. Microsoft Visual C++ 2010 Express or higher edition (http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express)
|
||||
2. Git for Windows (http://code.google.com/p/msysgit/downloads/list)
|
||||
3. CMake 2.8 or newer (http://www.cmake.org/cmake/resources/software.html)
|
||||
4. Python 2.x for Swiften build scripts (scons) (http://www.python.org)
|
||||
|
||||
Libraries
|
||||
=========
|
||||
3. Swiften library (http://swift.im/git/swift)
|
||||
4. Boost 1.48 or newer (http://sourceforge.net/projects/boost/files/boost/1.49.0/)
|
||||
5. Google ProtoBuf library (http://code.google.com/p/protobuf/downloads/list)
|
||||
|
||||
|
||||
Environment
|
||||
===========
|
||||
|
||||
To create spectrum build environment do:
|
||||
|
||||
0. Create directory where we'll install all dependencies, e.g. C:\env-msvc-x64.
|
||||
Create C:\env-msvc-x64\bin and add it to %PATH%.
|
||||
Assuming you have git, python and cmake in %PATH%,
|
||||
launch "Visual Studio 2010 command prompt" or
|
||||
"Visual Studio 2010(x64) command prompt", depends on your target (Windows x86 or Windows x86_64).
|
||||
1. unpack and build boost libraries:
|
||||
|
||||
bootstrap.bat
|
||||
b2.exe --without-mpi --without-python
|
||||
b2.exe --without-mpi --without-python install --prefix=C:\env-msvc-x64 release
|
||||
|
||||
2. clone swift repository and build it. Don't forget to point it to our env directory:
|
||||
|
||||
git clone git://swift.im/swift
|
||||
cd swift
|
||||
echo boost_includedir="c:/env-msvc-x64/include/boost-1_49" > config.py
|
||||
echo boost_libdir="c:/env-msvc-x64/lib" >> config.py
|
||||
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 force_configure=1
|
||||
scons.bat debug=no SWIFTEN_INSTALLDIR=C:\env-msvc-x64 C:\env-msvc-x64
|
||||
|
||||
3. unpack and compile protobuf as described in its documentation.
|
||||
|
||||
Run extract_includes.bat in vsprojects/ directory and move resulting vsprojects/include/google/ directory to our C:\env-msvc-x64\include
|
||||
|
||||
Move protoc.exe to C:\env-msvc-x64\bin\ and libprotobuf.lib to C:\env-msvc-x64\lib
|
||||
|
||||
4. Install gtkmm
|
||||
|
||||
Download installer from https://live.gnome.org/gtkmm/MSWindows and install gtkmm into C:\env-msvc-x64\
|
||||
|
||||
5. Install libpurple headers
|
||||
|
||||
Download http://www.pidgin.im/download/source/ , extract it and copy libpurple directory in C:\env-msvc-x64\include
|
||||
|
||||
6. You're ready! :) Clone libtransport into C:\env-msvc-x64\libtransport (You *must* clone it into this directory, because libtransport will try to find the dependencies in ../lib and ../include)
|
||||
|
||||
Compile it as:
|
||||
|
||||
set CMAKE_INCLUDE_PATH=C:\env-msvc-x64\include
|
||||
cmake . -G "NMake Makefiles" -DBOOST_INCLUDEDIR=../include/boost-1_49 -DBOOST_LIBRARYDIR=../lib -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=C:\env-msvc-x64 -DGIT_EXECUTABLE="c:\Program Files (x86)\git\bin\git.exe"
|
||||
nmake
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
ADD_SUBDIRECTORY(dfrotz)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_frotz_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_frotz_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_frotz_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
ADD_SUBDIRECTORY(dfrotz)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_frotz_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_frotz_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_frotz_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC common/*.c dumb/*.c)
|
||||
|
||||
ADD_EXECUTABLE(dfrotz ${SRC})
|
||||
|
||||
# target_link_libraries(dfrotz)
|
||||
|
||||
INSTALL(TARGETS dfrotz RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC common/*.c dumb/*.c)
|
||||
|
||||
ADD_EXECUTABLE(dfrotz ${SRC})
|
||||
|
||||
# target_link_libraries(dfrotz)
|
||||
|
||||
INSTALL(TARGETS dfrotz RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
FILE(GLOB HEADERS *.h)
|
||||
QT4_WRAP_CPP(SRC ${HEADERS} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
|
||||
ADD_EXECUTABLE(spectrum2_libcommuni_backend ${SRC})
|
||||
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport pthread)
|
||||
else ()
|
||||
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport)
|
||||
endif()
|
||||
INSTALL(TARGETS spectrum2_libcommuni_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
FILE(GLOB HEADERS *.h)
|
||||
QT4_WRAP_CPP(SRC ${HEADERS} OPTIONS -DBOOST_TT_HAS_OPERATOR_HPP_INCLUDED)
|
||||
ADD_EXECUTABLE(spectrum2_libcommuni_backend ${SRC})
|
||||
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport pthread)
|
||||
else ()
|
||||
target_link_libraries(spectrum2_libcommuni_backend ${IRC_LIBRARY} ${QT_LIBRARIES} transport)
|
||||
endif()
|
||||
INSTALL(TARGETS spectrum2_libcommuni_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
|
||||
else()
|
||||
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(spectrum2_libpurple_backend sqlite3 ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin ${PROTOBUF_LIBRARY})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_libpurple_backend ${SRC})
|
||||
|
||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin pthread)
|
||||
else()
|
||||
target_link_libraries(spectrum2_libpurple_backend ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin)
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(spectrum2_libpurple_backend sqlite3 ${PURPLE_LIBRARY} ${GLIB2_LIBRARIES} ${LIBXML2_LIBRARIES} ${EVENT_LIBRARIES} transport-plugin ${PROTOBUF_LIBRARY})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2_libpurple_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB_RECURSE SRC *.c *.cpp)
|
||||
|
||||
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB_RECURSE SRC *.c *.cpp)
|
||||
|
||||
ADD_DEFINITIONS(-DHAVE_STDINT_H=1)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/yahoo)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_libyahoo2_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_libyahoo2_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_libyahoo2_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_skype_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_skype_backend ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport pthread ${LIBDBUSGLIB_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_skype_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_skype_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_skype_backend ${GLIB2_LIBRARIES} ${EVENT_LIBRARIES} transport pthread ${LIBDBUSGLIB_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_skype_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_smstools3_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_smstools3_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_smstools3_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_smstools3_backend ${SRC})
|
||||
|
||||
target_link_libraries(spectrum2_smstools3_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
|
||||
INSTALL(TARGETS spectrum2_smstools3_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_swiften_backend ${SRC})
|
||||
|
||||
IF (NOT WIN32)
|
||||
target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_swiften_backend ${SRC})
|
||||
|
||||
IF (NOT WIN32)
|
||||
target_link_libraries(spectrum2_swiften_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(spectrum2_swiften_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2_swiften_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
|
@ -1,455 +1,455 @@
|
|||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
#ifndef WIN32
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#ifndef __MACH__
|
||||
// malloc_trim
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
DEFINE_LOGGER(logger, "Swiften");
|
||||
DEFINE_LOGGER(logger_xml, "backend.xml");
|
||||
|
||||
// eventloop
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
// Plugins
|
||||
class SwiftenPlugin;
|
||||
NetworkPlugin *np = NULL;
|
||||
Swift::XMPPSerializer *serializer;
|
||||
|
||||
class ForwardIQHandler : public Swift::IQHandler {
|
||||
public:
|
||||
std::map <std::string, std::string> m_id2resource;
|
||||
|
||||
ForwardIQHandler(NetworkPlugin *np, const std::string &user) {
|
||||
m_np = np;
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
bool handleIQ(boost::shared_ptr<Swift::IQ> iq) {
|
||||
if (iq->getPayload<Swift::RosterPayload>() != NULL) {
|
||||
return false;
|
||||
}
|
||||
if (iq->getType() == Swift::IQ::Get) {
|
||||
m_id2resource[iq->getID()] = iq->getFrom().getResource();
|
||||
}
|
||||
|
||||
iq->setTo(m_user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(iq));
|
||||
m_np->sendRawXML(xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
NetworkPlugin *m_np;
|
||||
std::string m_user;
|
||||
|
||||
};
|
||||
|
||||
class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
bool m_firstPing;
|
||||
|
||||
Swift::FullPayloadSerializerCollection collection;
|
||||
Swift::XMPPParser *m_xmppParser;
|
||||
Swift::FullPayloadParserFactoryCollection m_collection2;
|
||||
|
||||
SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
|
||||
this->config = config;
|
||||
m_firstPing = true;
|
||||
m_factories = new Swift::BoostNetworkFactories(loop);
|
||||
m_conn = m_factories->getConnectionFactory()->createConnection();
|
||||
m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1));
|
||||
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
|
||||
#if HAVE_SWIFTEN_3
|
||||
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType, false);
|
||||
#else
|
||||
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType);
|
||||
#endif
|
||||
m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory());
|
||||
m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting the plugin.");
|
||||
}
|
||||
|
||||
// NetworkPlugin uses this method to send the data to networkplugin server
|
||||
void sendData(const std::string &string) {
|
||||
m_conn->write(Swift::createSafeByteArray(string));
|
||||
}
|
||||
|
||||
// This method has to call handleDataRead with all received data from network plugin server
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
if (m_firstPing) {
|
||||
m_firstPing = false;
|
||||
NetworkPlugin::PluginConfig cfg;
|
||||
cfg.setRawXML(true);
|
||||
sendConfig(cfg);
|
||||
}
|
||||
std::string d(data->begin(), data->end());
|
||||
handleDataRead(d);
|
||||
}
|
||||
|
||||
void handleStreamStart(const Swift::ProtocolHeader&) {}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Swift::Element> element) {
|
||||
#endif
|
||||
boost::shared_ptr<Swift::Stanza> stanza = boost::dynamic_pointer_cast<Swift::Stanza>(element);
|
||||
if (!stanza) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string user = stanza->getFrom().toBare();
|
||||
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
stanza->setFrom(client->getJID());
|
||||
|
||||
boost::shared_ptr<Swift::Message> message = boost::dynamic_pointer_cast<Swift::Message>(stanza);
|
||||
if (message) {
|
||||
client->sendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Presence> presence = boost::dynamic_pointer_cast<Swift::Presence>(stanza);
|
||||
if (presence) {
|
||||
client->sendPresence(presence);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::IQ> iq = boost::dynamic_pointer_cast<Swift::IQ>(stanza);
|
||||
if (iq) {
|
||||
if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) {
|
||||
std::string resource = m_handlers[user]->m_id2resource[stanza->getID()];
|
||||
if (resource.empty()) {
|
||||
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain()));
|
||||
} else {
|
||||
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), resource));
|
||||
}
|
||||
|
||||
m_handlers[user]->m_id2resource.erase(stanza->getID());
|
||||
}
|
||||
client->getIQRouter()->sendIQ(iq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void handleStreamEnd() {}
|
||||
|
||||
void handleRawXML(const std::string &xml) {
|
||||
m_xmppParser->parse(xml);
|
||||
}
|
||||
|
||||
void handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
|
||||
std::string message = "";
|
||||
bool reconnect = false;
|
||||
if (error) {
|
||||
switch(error->getType()) {
|
||||
case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break;
|
||||
case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
|
||||
case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
|
||||
case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break;
|
||||
case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break;
|
||||
case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break;
|
||||
case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
|
||||
case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
|
||||
case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
|
||||
case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
|
||||
case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
|
||||
case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
|
||||
case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
|
||||
case Swift::ClientError::StreamError: message = ("Stream error"); break;
|
||||
case Swift::ClientError::TLSError: message = ("Encryption error"); break;
|
||||
case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
|
||||
case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
|
||||
|
||||
case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
|
||||
case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
|
||||
case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
|
||||
case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
|
||||
case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
|
||||
case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
|
||||
case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
|
||||
case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
|
||||
case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
|
||||
case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
|
||||
case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
|
||||
}
|
||||
}
|
||||
LOG4CXX_INFO(logger, user << ": Disconnected " << message);
|
||||
handleDisconnected(user, reconnect ? 0 : 3, message);
|
||||
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
m_users.erase(user);
|
||||
m_handlers.erase(user);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef __FreeBSD__
|
||||
#ifndef __MACH__
|
||||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleSwiftConnected(const std::string &user) {
|
||||
LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
|
||||
handleConnected(user);
|
||||
m_users[user]->requestRoster();
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setFrom(m_users[user]->getJID());
|
||||
m_users[user]->sendPresence(response);
|
||||
}
|
||||
|
||||
void handleSwiftRosterReceived(const std::string &user) {
|
||||
Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
|
||||
BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
|
||||
Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
|
||||
pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
|
||||
handleBuddyChanged(user, item.getJID().toBare().toString(),
|
||||
item.getName(), item.getGroups(), status);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
|
||||
// boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (presence->getPayload<Swift::MUCUserPayload>() != NULL || presence->getPayload<Swift::MUCPayload>() != NULL) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
|
||||
//
|
||||
// std::string message = presence->getStatus();
|
||||
// std::string photo = "";
|
||||
//
|
||||
// boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
|
||||
// if (update) {
|
||||
// photo = update->getPhotoHash();
|
||||
// }
|
||||
//
|
||||
// boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
|
||||
// if (item) {
|
||||
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
// }
|
||||
// else {
|
||||
// std::vector<std::string> groups;
|
||||
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
// }
|
||||
presence->setTo(user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(presence));
|
||||
sendRawXML(xml);
|
||||
}
|
||||
|
||||
void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
|
||||
message->setTo(user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(message));
|
||||
sendRawXML(xml);
|
||||
}
|
||||
|
||||
void handleSwiftenDataRead(const Swift::SafeByteArray &data) {
|
||||
std::string d = safeByteArrayToString(data);
|
||||
if (!boost::starts_with(d, "<auth")) {
|
||||
LOG4CXX_INFO(logger_xml, "XML IN " << d);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftenDataWritten(const Swift::SafeByteArray &data) {
|
||||
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
|
||||
boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName + "/Spectrum"), password, m_factories);
|
||||
m_users[user] = client;
|
||||
client->setAlwaysTrustCertificates();
|
||||
client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1));
|
||||
client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1));
|
||||
client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3));
|
||||
client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2));
|
||||
Swift::ClientOptions opt;
|
||||
opt.allowPLAINWithoutTLS = true;
|
||||
client->connect(opt);
|
||||
|
||||
boost::shared_ptr<ForwardIQHandler> handler = boost::make_shared<ForwardIQHandler>(this, user);
|
||||
client->getIQRouter()->addHandler(handler);
|
||||
m_handlers[user] = handler;
|
||||
}
|
||||
|
||||
void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) {
|
||||
handleSwiftPresenceChanged(user, presence);
|
||||
}
|
||||
|
||||
void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setTo(user);
|
||||
presence->setFrom(jid);
|
||||
presence->setType(Swift::Presence::Unsubscribe);
|
||||
handleSwiftPresenceChanged(user, presence);
|
||||
}
|
||||
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
client->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") {
|
||||
}
|
||||
|
||||
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
|
||||
if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) {
|
||||
Swift::RosterItemPayload item;
|
||||
item.setName(alias);
|
||||
item.setJID(buddyName);
|
||||
item.setGroups(groups);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
client->getSubscriptionManager()->requestSubscription(buddyName);
|
||||
}
|
||||
else {
|
||||
Swift::JID contact(buddyName);
|
||||
Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
|
||||
item.setGroups(groups);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
}
|
||||
}
|
||||
|
||||
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
|
||||
|
||||
}
|
||||
|
||||
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
Config *config;
|
||||
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
|
||||
std::map<std::string, boost::shared_ptr<ForwardIQHandler> > m_handlers;
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
#ifndef WIN32
|
||||
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
std::cout << "SIGCHLD handler can't be set\n";
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string error;
|
||||
Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
|
||||
if (cfg == NULL) {
|
||||
std::cerr << error;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logging::initBackendLogging(cfg);
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
loop_ = &eventLoop;
|
||||
np = new SwiftenPlugin(cfg, &eventLoop, host, port);
|
||||
loop_->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
// Transport includes
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
|
||||
#include "boost/date_time/posix_time/posix_time.hpp"
|
||||
|
||||
// Swiften
|
||||
#include "Swiften/Swiften.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
#ifndef WIN32
|
||||
// for signal handler
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#endif
|
||||
|
||||
#ifndef __FreeBSD__
|
||||
#ifndef __MACH__
|
||||
// malloc_trim
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Boost
|
||||
#include <boost/algorithm/string.hpp>
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
DEFINE_LOGGER(logger, "Swiften");
|
||||
DEFINE_LOGGER(logger_xml, "backend.xml");
|
||||
|
||||
// eventloop
|
||||
Swift::SimpleEventLoop *loop_;
|
||||
|
||||
// Plugins
|
||||
class SwiftenPlugin;
|
||||
NetworkPlugin *np = NULL;
|
||||
Swift::XMPPSerializer *serializer;
|
||||
|
||||
class ForwardIQHandler : public Swift::IQHandler {
|
||||
public:
|
||||
std::map <std::string, std::string> m_id2resource;
|
||||
|
||||
ForwardIQHandler(NetworkPlugin *np, const std::string &user) {
|
||||
m_np = np;
|
||||
m_user = user;
|
||||
}
|
||||
|
||||
bool handleIQ(boost::shared_ptr<Swift::IQ> iq) {
|
||||
if (iq->getPayload<Swift::RosterPayload>() != NULL) {
|
||||
return false;
|
||||
}
|
||||
if (iq->getType() == Swift::IQ::Get) {
|
||||
m_id2resource[iq->getID()] = iq->getFrom().getResource();
|
||||
}
|
||||
|
||||
iq->setTo(m_user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(iq));
|
||||
m_np->sendRawXML(xml);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
NetworkPlugin *m_np;
|
||||
std::string m_user;
|
||||
|
||||
};
|
||||
|
||||
class SwiftenPlugin : public NetworkPlugin, Swift::XMPPParserClient {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
bool m_firstPing;
|
||||
|
||||
Swift::FullPayloadSerializerCollection collection;
|
||||
Swift::XMPPParser *m_xmppParser;
|
||||
Swift::FullPayloadParserFactoryCollection m_collection2;
|
||||
|
||||
SwiftenPlugin(Config *config, Swift::SimpleEventLoop *loop, const std::string &host, int port) : NetworkPlugin() {
|
||||
this->config = config;
|
||||
m_firstPing = true;
|
||||
m_factories = new Swift::BoostNetworkFactories(loop);
|
||||
m_conn = m_factories->getConnectionFactory()->createConnection();
|
||||
m_conn->onDataRead.connect(boost::bind(&SwiftenPlugin::_handleDataRead, this, _1));
|
||||
m_conn->connect(Swift::HostAddressPort(Swift::HostAddress(host), port));
|
||||
#if HAVE_SWIFTEN_3
|
||||
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType, false);
|
||||
#else
|
||||
serializer = new Swift::XMPPSerializer(&collection, Swift::ClientStreamType);
|
||||
#endif
|
||||
m_xmppParser = new Swift::XMPPParser(this, &m_collection2, m_factories->getXMLParserFactory());
|
||||
m_xmppParser->parse("<stream:stream xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' to='localhost' version='1.0'>");
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting the plugin.");
|
||||
}
|
||||
|
||||
// NetworkPlugin uses this method to send the data to networkplugin server
|
||||
void sendData(const std::string &string) {
|
||||
m_conn->write(Swift::createSafeByteArray(string));
|
||||
}
|
||||
|
||||
// This method has to call handleDataRead with all received data from network plugin server
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data) {
|
||||
if (m_firstPing) {
|
||||
m_firstPing = false;
|
||||
NetworkPlugin::PluginConfig cfg;
|
||||
cfg.setRawXML(true);
|
||||
sendConfig(cfg);
|
||||
}
|
||||
std::string d(data->begin(), data->end());
|
||||
handleDataRead(d);
|
||||
}
|
||||
|
||||
void handleStreamStart(const Swift::ProtocolHeader&) {}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Swift::Element> element) {
|
||||
#endif
|
||||
boost::shared_ptr<Swift::Stanza> stanza = boost::dynamic_pointer_cast<Swift::Stanza>(element);
|
||||
if (!stanza) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::string user = stanza->getFrom().toBare();
|
||||
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (!client)
|
||||
return;
|
||||
|
||||
stanza->setFrom(client->getJID());
|
||||
|
||||
boost::shared_ptr<Swift::Message> message = boost::dynamic_pointer_cast<Swift::Message>(stanza);
|
||||
if (message) {
|
||||
client->sendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Presence> presence = boost::dynamic_pointer_cast<Swift::Presence>(stanza);
|
||||
if (presence) {
|
||||
client->sendPresence(presence);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::IQ> iq = boost::dynamic_pointer_cast<Swift::IQ>(stanza);
|
||||
if (iq) {
|
||||
if (m_handlers[user]->m_id2resource.find(stanza->getID()) != m_handlers[user]->m_id2resource.end()) {
|
||||
std::string resource = m_handlers[user]->m_id2resource[stanza->getID()];
|
||||
if (resource.empty()) {
|
||||
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain()));
|
||||
} else {
|
||||
iq->setTo(Swift::JID(iq->getTo().getNode(), iq->getTo().getDomain(), resource));
|
||||
}
|
||||
|
||||
m_handlers[user]->m_id2resource.erase(stanza->getID());
|
||||
}
|
||||
client->getIQRouter()->sendIQ(iq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void handleStreamEnd() {}
|
||||
|
||||
void handleRawXML(const std::string &xml) {
|
||||
m_xmppParser->parse(xml);
|
||||
}
|
||||
|
||||
void handleSwiftDisconnected(const std::string &user, const boost::optional<Swift::ClientError> &error) {
|
||||
std::string message = "";
|
||||
bool reconnect = false;
|
||||
if (error) {
|
||||
switch(error->getType()) {
|
||||
case Swift::ClientError::UnknownError: message = ("Unknown Error"); reconnect = true; break;
|
||||
case Swift::ClientError::DomainNameResolveError: message = ("Unable to find server"); break;
|
||||
case Swift::ClientError::ConnectionError: message = ("Error connecting to server"); break;
|
||||
case Swift::ClientError::ConnectionReadError: message = ("Error while receiving server data"); reconnect = true; break;
|
||||
case Swift::ClientError::ConnectionWriteError: message = ("Error while sending data to the server"); reconnect = true; break;
|
||||
case Swift::ClientError::XMLError: message = ("Error parsing server data"); reconnect = true; break;
|
||||
case Swift::ClientError::AuthenticationFailedError: message = ("Login/password invalid"); break;
|
||||
case Swift::ClientError::CompressionFailedError: message = ("Error while compressing stream"); break;
|
||||
case Swift::ClientError::ServerVerificationFailedError: message = ("Server verification failed"); break;
|
||||
case Swift::ClientError::NoSupportedAuthMechanismsError: message = ("Authentication mechanisms not supported"); break;
|
||||
case Swift::ClientError::UnexpectedElementError: message = ("Unexpected response"); break;
|
||||
case Swift::ClientError::ResourceBindError: message = ("Error binding resource"); break;
|
||||
case Swift::ClientError::SessionStartError: message = ("Error starting session"); break;
|
||||
case Swift::ClientError::StreamError: message = ("Stream error"); break;
|
||||
case Swift::ClientError::TLSError: message = ("Encryption error"); break;
|
||||
case Swift::ClientError::ClientCertificateLoadError: message = ("Error loading certificate (Invalid password?)"); break;
|
||||
case Swift::ClientError::ClientCertificateError: message = ("Certificate not authorized"); break;
|
||||
|
||||
case Swift::ClientError::UnknownCertificateError: message = ("Unknown certificate"); break;
|
||||
case Swift::ClientError::CertificateExpiredError: message = ("Certificate has expired"); break;
|
||||
case Swift::ClientError::CertificateNotYetValidError: message = ("Certificate is not yet valid"); break;
|
||||
case Swift::ClientError::CertificateSelfSignedError: message = ("Certificate is self-signed"); break;
|
||||
case Swift::ClientError::CertificateRejectedError: message = ("Certificate has been rejected"); break;
|
||||
case Swift::ClientError::CertificateUntrustedError: message = ("Certificate is not trusted"); break;
|
||||
case Swift::ClientError::InvalidCertificatePurposeError: message = ("Certificate cannot be used for encrypting your connection"); break;
|
||||
case Swift::ClientError::CertificatePathLengthExceededError: message = ("Certificate path length constraint exceeded"); break;
|
||||
case Swift::ClientError::InvalidCertificateSignatureError: message = ("Invalid certificate signature"); break;
|
||||
case Swift::ClientError::InvalidCAError: message = ("Invalid Certificate Authority"); break;
|
||||
case Swift::ClientError::InvalidServerIdentityError: message = ("Certificate does not match the host identity"); break;
|
||||
}
|
||||
}
|
||||
LOG4CXX_INFO(logger, user << ": Disconnected " << message);
|
||||
handleDisconnected(user, reconnect ? 0 : 3, message);
|
||||
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
m_users.erase(user);
|
||||
m_handlers.erase(user);
|
||||
}
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef __FreeBSD__
|
||||
#ifndef __MACH__
|
||||
// force returning of memory chunks allocated by libxml2 to kernel
|
||||
malloc_trim(0);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void handleSwiftConnected(const std::string &user) {
|
||||
LOG4CXX_INFO(logger, user << ": Connected to XMPP server.");
|
||||
handleConnected(user);
|
||||
m_users[user]->requestRoster();
|
||||
Swift::Presence::ref response = Swift::Presence::create();
|
||||
response->setFrom(m_users[user]->getJID());
|
||||
m_users[user]->sendPresence(response);
|
||||
}
|
||||
|
||||
void handleSwiftRosterReceived(const std::string &user) {
|
||||
Swift::PresenceOracle *oracle = m_users[user]->getPresenceOracle();
|
||||
BOOST_FOREACH(const Swift::XMPPRosterItem &item, m_users[user]->getRoster()->getItems()) {
|
||||
Swift::Presence::ref lastPresence = oracle->getLastPresence(item.getJID());
|
||||
pbnetwork::StatusType status = lastPresence ? ((pbnetwork::StatusType) lastPresence->getShow()) : pbnetwork::STATUS_NONE;
|
||||
handleBuddyChanged(user, item.getJID().toBare().toString(),
|
||||
item.getName(), item.getGroups(), status);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftPresenceChanged(const std::string &user, Swift::Presence::ref presence) {
|
||||
// boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
// if (client->getMUCRegistry()->isMUC(presence->getFrom().toBare())) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (presence->getPayload<Swift::MUCUserPayload>() != NULL || presence->getPayload<Swift::MUCPayload>() != NULL) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed");
|
||||
//
|
||||
// std::string message = presence->getStatus();
|
||||
// std::string photo = "";
|
||||
//
|
||||
// boost::shared_ptr<Swift::VCardUpdate> update = presence->getPayload<Swift::VCardUpdate>();
|
||||
// if (update) {
|
||||
// photo = update->getPhotoHash();
|
||||
// }
|
||||
//
|
||||
// boost::optional<Swift::XMPPRosterItem> item = m_users[user]->getRoster()->getItem(presence->getFrom());
|
||||
// if (item) {
|
||||
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), item->getName(), item->getGroups(), (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
// }
|
||||
// else {
|
||||
// std::vector<std::string> groups;
|
||||
// handleBuddyChanged(user, presence->getFrom().toBare().toString(), presence->getFrom().toBare(), groups, (pbnetwork::StatusType) presence->getShow(), message, photo);
|
||||
// }
|
||||
presence->setTo(user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(presence));
|
||||
sendRawXML(xml);
|
||||
}
|
||||
|
||||
void handleSwiftMessageReceived(const std::string &user, Swift::Message::ref message) {
|
||||
message->setTo(user);
|
||||
std::string xml = safeByteArrayToString(serializer->serializeElement(message));
|
||||
sendRawXML(xml);
|
||||
}
|
||||
|
||||
void handleSwiftenDataRead(const Swift::SafeByteArray &data) {
|
||||
std::string d = safeByteArrayToString(data);
|
||||
if (!boost::starts_with(d, "<auth")) {
|
||||
LOG4CXX_INFO(logger_xml, "XML IN " << d);
|
||||
}
|
||||
}
|
||||
|
||||
void handleSwiftenDataWritten(const Swift::SafeByteArray &data) {
|
||||
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
|
||||
}
|
||||
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password) {
|
||||
LOG4CXX_INFO(logger, user << ": connecting as " << legacyName);
|
||||
boost::shared_ptr<Swift::Client> client = boost::make_shared<Swift::Client>(Swift::JID(legacyName + "/Spectrum"), password, m_factories);
|
||||
m_users[user] = client;
|
||||
client->setAlwaysTrustCertificates();
|
||||
client->onConnected.connect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
client->onDisconnected.connect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.connect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.connect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.connect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
client->onDataRead.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataRead, this, _1));
|
||||
client->onDataWritten.connect(boost::bind(&SwiftenPlugin::handleSwiftenDataWritten, this, _1));
|
||||
client->getSubscriptionManager()->onPresenceSubscriptionRequest.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRequest, this, user, _1, _2, _3));
|
||||
client->getSubscriptionManager()->onPresenceSubscriptionRevoked.connect(boost::bind(&SwiftenPlugin::handleSubscriptionRevoked, this, user, _1, _2));
|
||||
Swift::ClientOptions opt;
|
||||
opt.allowPLAINWithoutTLS = true;
|
||||
client->connect(opt);
|
||||
|
||||
boost::shared_ptr<ForwardIQHandler> handler = boost::make_shared<ForwardIQHandler>(this, user);
|
||||
client->getIQRouter()->addHandler(handler);
|
||||
m_handlers[user] = handler;
|
||||
}
|
||||
|
||||
void handleSubscriptionRequest(const std::string &user, const Swift::JID& jid, const std::string& message, Swift::Presence::ref presence) {
|
||||
handleSwiftPresenceChanged(user, presence);
|
||||
}
|
||||
|
||||
void handleSubscriptionRevoked(const std::string &user, const Swift::JID& jid, const std::string& message) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setTo(user);
|
||||
presence->setFrom(jid);
|
||||
presence->setType(Swift::Presence::Unsubscribe);
|
||||
handleSwiftPresenceChanged(user, presence);
|
||||
}
|
||||
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
client->onConnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftConnected, this, user));
|
||||
// client->onDisconnected.disconnect(boost::bind(&SwiftenPlugin::handleSwiftDisconnected, this, user, _1));
|
||||
client->onMessageReceived.disconnect(boost::bind(&SwiftenPlugin::handleSwiftMessageReceived, this, user, _1));
|
||||
client->getRoster()->onInitialRosterPopulated.disconnect(boost::bind(&SwiftenPlugin::handleSwiftRosterReceived, this, user));
|
||||
client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1));
|
||||
client->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &msg, const std::string &xhtml = "", const std::string &id = "") {
|
||||
}
|
||||
|
||||
void handleVCardRequest(const std::string &user, const std::string &legacyName, unsigned int id) {
|
||||
}
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
LOG4CXX_INFO(logger, user << ": Added/Updated buddy " << buddyName << ".");
|
||||
if (!client->getRoster()->containsJID(buddyName) || client->getRoster()->getSubscriptionStateForJID(buddyName) != Swift::RosterItemPayload::Both) {
|
||||
Swift::RosterItemPayload item;
|
||||
item.setName(alias);
|
||||
item.setJID(buddyName);
|
||||
item.setGroups(groups);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
client->getSubscriptionManager()->requestSubscription(buddyName);
|
||||
}
|
||||
else {
|
||||
Swift::JID contact(buddyName);
|
||||
Swift::RosterItemPayload item(contact, alias, client->getRoster()->getSubscriptionStateForJID(contact));
|
||||
item.setGroups(groups);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups) {
|
||||
boost::shared_ptr<Swift::Client> client = m_users[user];
|
||||
if (client) {
|
||||
Swift::RosterItemPayload item(buddyName, "", Swift::RosterItemPayload::Remove);
|
||||
boost::shared_ptr<Swift::RosterPayload> roster(new Swift::RosterPayload());
|
||||
roster->addItem(item);
|
||||
Swift::SetRosterRequest::ref request = Swift::SetRosterRequest::create(roster, client->getIQRouter());
|
||||
// request->onResponse.connect(boost::bind(&RosterController::handleRosterSetError, this, _1, roster));
|
||||
request->send();
|
||||
}
|
||||
}
|
||||
|
||||
void handleJoinRoomRequest(const std::string &user, const std::string &room, const std::string &nickname, const std::string &password) {
|
||||
|
||||
}
|
||||
|
||||
void handleLeaveRoomRequest(const std::string &user, const std::string &room) {
|
||||
|
||||
}
|
||||
|
||||
private:
|
||||
Config *config;
|
||||
std::map<std::string, boost::shared_ptr<Swift::Client> > m_users;
|
||||
std::map<std::string, boost::shared_ptr<ForwardIQHandler> > m_handlers;
|
||||
};
|
||||
|
||||
#ifndef WIN32
|
||||
static void spectrum_sigchld_handler(int sig)
|
||||
{
|
||||
int status;
|
||||
pid_t pid;
|
||||
|
||||
do {
|
||||
pid = waitpid(-1, &status, WNOHANG);
|
||||
} while (pid != 0 && pid != (pid_t)-1);
|
||||
|
||||
if ((pid == (pid_t) - 1) && (errno != ECHILD)) {
|
||||
char errmsg[BUFSIZ];
|
||||
snprintf(errmsg, BUFSIZ, "Warning: waitpid() returned %d", pid);
|
||||
perror(errmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
int main (int argc, char* argv[]) {
|
||||
std::string host;
|
||||
int port;
|
||||
|
||||
#ifndef WIN32
|
||||
if (signal(SIGCHLD, spectrum_sigchld_handler) == SIG_ERR) {
|
||||
std::cout << "SIGCHLD handler can't be set\n";
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string error;
|
||||
Config *cfg = Config::createFromArgs(argc, argv, error, host, port);
|
||||
if (cfg == NULL) {
|
||||
std::cerr << error;
|
||||
return 1;
|
||||
}
|
||||
|
||||
Logging::initBackendLogging(cfg);
|
||||
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
loop_ = &eventLoop;
|
||||
np = new SwiftenPlugin(cfg, &eventLoop, host, port);
|
||||
loop_->run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_template_backend ${SRC})
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(spectrum2_template_backend transport ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
|
||||
#INSTALL(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin)
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
FILE(GLOB SRC *.c *.cpp)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_template_backend ${SRC})
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
target_link_libraries(spectrum2_template_backend transport pthread ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
else()
|
||||
target_link_libraries(spectrum2_template_backend transport ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
else()
|
||||
target_link_libraries(spectrum2_template_backend transport ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES})
|
||||
endif()
|
||||
|
||||
#INSTALL(TARGETS spectrum2_template_backend RUNTIME DESTINATION bin)
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,189 +1,189 @@
|
|||
#ifndef TWITTER_PLUGIN
|
||||
#define TWITTER_PLUGIN
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/mysqlbackend.h"
|
||||
#include "transport/pqxxbackend.h"
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/threadpool.h"
|
||||
|
||||
#include "Swiften/Swiften.h"
|
||||
#ifndef _WIN32
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#endif
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/signal.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include "twitcurl.h"
|
||||
#include "TwitterResponseParser.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <cstdio>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/Crypto/CryptoProvider.h>
|
||||
#include <Swiften/Crypto/PlatformCryptoProvider.h>
|
||||
#else
|
||||
#include "Swiften/StringCodecs/SHA1.h"
|
||||
#endif
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
#define STR(x) (std::string("(") + x.from + ", " + x.to + ", " + x.message + ")")
|
||||
|
||||
class TwitterPlugin;
|
||||
extern TwitterPlugin *np;
|
||||
extern Swift::SimpleEventLoop *loop_; // Event Loop
|
||||
|
||||
|
||||
class TwitterPlugin : public NetworkPlugin {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<Swift::CryptoProvider> cryptoProvider;
|
||||
#endif
|
||||
Swift::Timer::ref tweet_timer;
|
||||
Swift::Timer::ref message_timer;
|
||||
StorageBackend *storagebackend;
|
||||
|
||||
TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port);
|
||||
~TwitterPlugin();
|
||||
|
||||
// Send data to NetworkPlugin server
|
||||
void sendData(const std::string &string);
|
||||
|
||||
// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class)
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
// User trying to login into his twitter account
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
|
||||
|
||||
// User logging out
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
|
||||
|
||||
void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/);
|
||||
|
||||
void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/);
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "");
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups);
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups);
|
||||
|
||||
void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/);
|
||||
|
||||
void pollForTweets();
|
||||
|
||||
void pollForDirectMessages();
|
||||
|
||||
bool getUserOAuthKeyAndSecret(const std::string user, std::string &key, std::string &secret);
|
||||
|
||||
bool checkSpectrum1User(const std::string user);
|
||||
|
||||
bool storeUserOAuthKeyAndSecret(const std::string user, const std::string OAuthKey, const std::string OAuthSecret);
|
||||
|
||||
void initUserSession(const std::string user, const std::string legacyName, const std::string password);
|
||||
|
||||
void OAuthFlowComplete(const std::string user, twitCurl *obj);
|
||||
|
||||
void pinExchangeComplete(const std::string user, const std::string OAuthAccessTokenKey, const std::string OAuthAccessTokenSecret);
|
||||
|
||||
void updateLastTweetID(const std::string user, const std::string ID);
|
||||
|
||||
std::string getMostRecentTweetID(const std::string user);
|
||||
|
||||
void updateLastDMID(const std::string user, const std::string ID);
|
||||
|
||||
std::string getMostRecentDMID(const std::string user);
|
||||
|
||||
void clearRoster(const std::string user);
|
||||
|
||||
int getTwitterMode(const std::string user);
|
||||
|
||||
bool setTwitterMode(const std::string user, int m);
|
||||
|
||||
/****************** Twitter response handlers **************************************/
|
||||
void statusUpdateResponse(std::string &user, Error &errMsg);
|
||||
|
||||
void helpMessageResponse(std::string &user, std::string &msg);
|
||||
|
||||
void populateRoster(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
|
||||
|
||||
void displayFriendlist(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
|
||||
|
||||
void displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , Error &errMsg);
|
||||
|
||||
void directMessageResponse(std::string &user, std::string &username, std::vector<DirectMessage> &messages, Error &errMsg);
|
||||
|
||||
void createFriendResponse(std::string &user, User &frnd, std::string &img, Error &errMsg);
|
||||
|
||||
void deleteFriendResponse(std::string &user, User &frnd, Error &errMsg);
|
||||
|
||||
void RetweetResponse(std::string &user, Error &errMsg);
|
||||
|
||||
void profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, Error &errMsg);
|
||||
/***********************************************************************************/
|
||||
|
||||
private:
|
||||
std::string getMostRecentTweetIDUnsafe(const std::string user);
|
||||
std::string getMostRecentDMIDUnsafe(const std::string user);
|
||||
|
||||
enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED};
|
||||
enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM};
|
||||
|
||||
Config *config;
|
||||
std::string adminLegacyName;
|
||||
std::string adminChatRoom;
|
||||
std::string adminNickName;
|
||||
std::string adminAlias;
|
||||
|
||||
std::string consumerKey;
|
||||
std::string consumerSecret;
|
||||
std::string OAUTH_KEY;
|
||||
std::string OAUTH_SECRET;
|
||||
std::string MODE;
|
||||
|
||||
boost::mutex dblock, userlock;
|
||||
|
||||
ThreadPool *tp;
|
||||
std::set<std::string> onlineUsers;
|
||||
struct UserData
|
||||
{
|
||||
std::string legacyName;
|
||||
bool spectrum1User; //Legacy support
|
||||
User userTwitterObj;
|
||||
std::string userImg;
|
||||
twitCurl* sessions;
|
||||
status connectionState;
|
||||
std::string mostRecentTweetID;
|
||||
std::string mostRecentDirectMessageID;
|
||||
std::string nickName;
|
||||
std::set<std::string> buddies;
|
||||
std::map<std::string, User> buddiesInfo;
|
||||
std::map<std::string, std::string> buddiesImgs;
|
||||
mode twitterMode;
|
||||
|
||||
UserData() { sessions = NULL; }
|
||||
};
|
||||
std::map<std::string, UserData> userdb;
|
||||
bool m_firstPing;
|
||||
};
|
||||
#endif
|
||||
#ifndef TWITTER_PLUGIN
|
||||
#define TWITTER_PLUGIN
|
||||
|
||||
#include "transport/config.h"
|
||||
#include "transport/networkplugin.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/sqlite3backend.h"
|
||||
#include "transport/mysqlbackend.h"
|
||||
#include "transport/pqxxbackend.h"
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/threadpool.h"
|
||||
|
||||
#include "Swiften/Swiften.h"
|
||||
#ifndef _WIN32
|
||||
#include "unistd.h"
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
#include "sys/signal.h"
|
||||
#endif
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/signal.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
|
||||
#include "twitcurl.h"
|
||||
#include "TwitterResponseParser.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <cstdio>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/Crypto/CryptoProvider.h>
|
||||
#include <Swiften/Crypto/PlatformCryptoProvider.h>
|
||||
#else
|
||||
#include "Swiften/StringCodecs/SHA1.h"
|
||||
#endif
|
||||
using namespace boost::filesystem;
|
||||
using namespace boost::program_options;
|
||||
using namespace Transport;
|
||||
|
||||
#define STR(x) (std::string("(") + x.from + ", " + x.to + ", " + x.message + ")")
|
||||
|
||||
class TwitterPlugin;
|
||||
extern TwitterPlugin *np;
|
||||
extern Swift::SimpleEventLoop *loop_; // Event Loop
|
||||
|
||||
|
||||
class TwitterPlugin : public NetworkPlugin {
|
||||
public:
|
||||
Swift::BoostNetworkFactories *m_factories;
|
||||
Swift::BoostIOServiceThread m_boostIOServiceThread;
|
||||
boost::shared_ptr<Swift::Connection> m_conn;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<Swift::CryptoProvider> cryptoProvider;
|
||||
#endif
|
||||
Swift::Timer::ref tweet_timer;
|
||||
Swift::Timer::ref message_timer;
|
||||
StorageBackend *storagebackend;
|
||||
|
||||
TwitterPlugin(Config *config, Swift::SimpleEventLoop *loop, StorageBackend *storagebackend, const std::string &host, int port);
|
||||
~TwitterPlugin();
|
||||
|
||||
// Send data to NetworkPlugin server
|
||||
void sendData(const std::string &string);
|
||||
|
||||
// Receive date from the NetworkPlugin server and invoke the appropirate payload handler (implement in the NetworkPlugin class)
|
||||
void _handleDataRead(boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
// User trying to login into his twitter account
|
||||
void handleLoginRequest(const std::string &user, const std::string &legacyName, const std::string &password);
|
||||
|
||||
// User logging out
|
||||
void handleLogoutRequest(const std::string &user, const std::string &legacyName);
|
||||
|
||||
void handleJoinRoomRequest(const std::string &/*user*/, const std::string &/*room*/, const std::string &/*nickname*/, const std::string &/*pasword*/);
|
||||
|
||||
void handleLeaveRoomRequest(const std::string &/*user*/, const std::string &/*room*/);
|
||||
|
||||
void handleMessageSendRequest(const std::string &user, const std::string &legacyName, const std::string &message, const std::string &xhtml = "", const std::string &id = "");
|
||||
|
||||
void handleBuddyUpdatedRequest(const std::string &user, const std::string &buddyName, const std::string &alias, const std::vector<std::string> &groups);
|
||||
|
||||
void handleBuddyRemovedRequest(const std::string &user, const std::string &buddyName, const std::vector<std::string> &groups);
|
||||
|
||||
void handleVCardRequest(const std::string &/*user*/, const std::string &/*legacyName*/, unsigned int /*id*/);
|
||||
|
||||
void pollForTweets();
|
||||
|
||||
void pollForDirectMessages();
|
||||
|
||||
bool getUserOAuthKeyAndSecret(const std::string user, std::string &key, std::string &secret);
|
||||
|
||||
bool checkSpectrum1User(const std::string user);
|
||||
|
||||
bool storeUserOAuthKeyAndSecret(const std::string user, const std::string OAuthKey, const std::string OAuthSecret);
|
||||
|
||||
void initUserSession(const std::string user, const std::string legacyName, const std::string password);
|
||||
|
||||
void OAuthFlowComplete(const std::string user, twitCurl *obj);
|
||||
|
||||
void pinExchangeComplete(const std::string user, const std::string OAuthAccessTokenKey, const std::string OAuthAccessTokenSecret);
|
||||
|
||||
void updateLastTweetID(const std::string user, const std::string ID);
|
||||
|
||||
std::string getMostRecentTweetID(const std::string user);
|
||||
|
||||
void updateLastDMID(const std::string user, const std::string ID);
|
||||
|
||||
std::string getMostRecentDMID(const std::string user);
|
||||
|
||||
void clearRoster(const std::string user);
|
||||
|
||||
int getTwitterMode(const std::string user);
|
||||
|
||||
bool setTwitterMode(const std::string user, int m);
|
||||
|
||||
/****************** Twitter response handlers **************************************/
|
||||
void statusUpdateResponse(std::string &user, Error &errMsg);
|
||||
|
||||
void helpMessageResponse(std::string &user, std::string &msg);
|
||||
|
||||
void populateRoster(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
|
||||
|
||||
void displayFriendlist(std::string &user, std::vector<User> &friends, std::vector<std::string> &friendAvatars, Error &errMsg);
|
||||
|
||||
void displayTweets(std::string &user, std::string &userRequested, std::vector<Status> &tweets , Error &errMsg);
|
||||
|
||||
void directMessageResponse(std::string &user, std::string &username, std::vector<DirectMessage> &messages, Error &errMsg);
|
||||
|
||||
void createFriendResponse(std::string &user, User &frnd, std::string &img, Error &errMsg);
|
||||
|
||||
void deleteFriendResponse(std::string &user, User &frnd, Error &errMsg);
|
||||
|
||||
void RetweetResponse(std::string &user, Error &errMsg);
|
||||
|
||||
void profileImageResponse(std::string &user, std::string &buddy, std::string &img, unsigned int reqID, Error &errMsg);
|
||||
/***********************************************************************************/
|
||||
|
||||
private:
|
||||
std::string getMostRecentTweetIDUnsafe(const std::string user);
|
||||
std::string getMostRecentDMIDUnsafe(const std::string user);
|
||||
|
||||
enum status {NEW, WAITING_FOR_PIN, CONNECTED, DISCONNECTED};
|
||||
enum mode {SINGLECONTACT, MULTIPLECONTACT, CHATROOM};
|
||||
|
||||
Config *config;
|
||||
std::string adminLegacyName;
|
||||
std::string adminChatRoom;
|
||||
std::string adminNickName;
|
||||
std::string adminAlias;
|
||||
|
||||
std::string consumerKey;
|
||||
std::string consumerSecret;
|
||||
std::string OAUTH_KEY;
|
||||
std::string OAUTH_SECRET;
|
||||
std::string MODE;
|
||||
|
||||
boost::mutex dblock, userlock;
|
||||
|
||||
ThreadPool *tp;
|
||||
std::set<std::string> onlineUsers;
|
||||
struct UserData
|
||||
{
|
||||
std::string legacyName;
|
||||
bool spectrum1User; //Legacy support
|
||||
User userTwitterObj;
|
||||
std::string userImg;
|
||||
twitCurl* sessions;
|
||||
status connectionState;
|
||||
std::string mostRecentTweetID;
|
||||
std::string mostRecentDirectMessageID;
|
||||
std::string nickName;
|
||||
std::set<std::string> buddies;
|
||||
std::map<std::string, User> buddiesInfo;
|
||||
std::map<std::string, std::string> buddiesImgs;
|
||||
mode twitterMode;
|
||||
|
||||
UserData() { sessions = NULL; }
|
||||
};
|
||||
std::map<std::string, UserData> userdb;
|
||||
bool m_firstPing;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,64 +1,64 @@
|
|||
//******************************************************************************
|
||||
//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm
|
||||
//* Comfort to RFC 2104
|
||||
//*
|
||||
//******************************************************************************
|
||||
#include "HMAC_SHA1.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
void CHMAC_SHA1::HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest)
|
||||
{
|
||||
memset(SHA1_Key, 0, SHA1_BLOCK_SIZE);
|
||||
|
||||
/* repeated 64 times for values in ipad and opad */
|
||||
memset(m_ipad, 0x36, sizeof(m_ipad));
|
||||
memset(m_opad, 0x5c, sizeof(m_opad));
|
||||
|
||||
/* STEP 1 */
|
||||
if (key_len > SHA1_BLOCK_SIZE)
|
||||
{
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)key, key_len);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)SHA1_Key);
|
||||
}
|
||||
else
|
||||
memcpy(SHA1_Key, key, key_len);
|
||||
|
||||
/* STEP 2 */
|
||||
for (size_t i=0; i<sizeof(m_ipad); i++)
|
||||
{
|
||||
m_ipad[i] ^= SHA1_Key[i];
|
||||
}
|
||||
|
||||
/* STEP 3 */
|
||||
memcpy(AppendBuf1, m_ipad, sizeof(m_ipad));
|
||||
memcpy(AppendBuf1 + sizeof(m_ipad), text, text_len);
|
||||
|
||||
/* STEP 4 */
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)AppendBuf1, sizeof(m_ipad) + text_len);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)szReport);
|
||||
|
||||
/* STEP 5 */
|
||||
for (size_t j=0; j<sizeof(m_opad); j++)
|
||||
{
|
||||
m_opad[j] ^= SHA1_Key[j];
|
||||
}
|
||||
|
||||
/* STEP 6 */
|
||||
memcpy(AppendBuf2, m_opad, sizeof(m_opad));
|
||||
memcpy(AppendBuf2 + sizeof(m_opad), szReport, SHA1_DIGEST_LENGTH);
|
||||
|
||||
/*STEP 7 */
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)AppendBuf2, sizeof(m_opad) + SHA1_DIGEST_LENGTH);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)digest);
|
||||
}
|
||||
//******************************************************************************
|
||||
//* HMAC_SHA1.cpp : Implementation of HMAC SHA1 algorithm
|
||||
//* Comfort to RFC 2104
|
||||
//*
|
||||
//******************************************************************************
|
||||
#include "HMAC_SHA1.h"
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
|
||||
void CHMAC_SHA1::HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest)
|
||||
{
|
||||
memset(SHA1_Key, 0, SHA1_BLOCK_SIZE);
|
||||
|
||||
/* repeated 64 times for values in ipad and opad */
|
||||
memset(m_ipad, 0x36, sizeof(m_ipad));
|
||||
memset(m_opad, 0x5c, sizeof(m_opad));
|
||||
|
||||
/* STEP 1 */
|
||||
if (key_len > SHA1_BLOCK_SIZE)
|
||||
{
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)key, key_len);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)SHA1_Key);
|
||||
}
|
||||
else
|
||||
memcpy(SHA1_Key, key, key_len);
|
||||
|
||||
/* STEP 2 */
|
||||
for (size_t i=0; i<sizeof(m_ipad); i++)
|
||||
{
|
||||
m_ipad[i] ^= SHA1_Key[i];
|
||||
}
|
||||
|
||||
/* STEP 3 */
|
||||
memcpy(AppendBuf1, m_ipad, sizeof(m_ipad));
|
||||
memcpy(AppendBuf1 + sizeof(m_ipad), text, text_len);
|
||||
|
||||
/* STEP 4 */
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)AppendBuf1, sizeof(m_ipad) + text_len);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)szReport);
|
||||
|
||||
/* STEP 5 */
|
||||
for (size_t j=0; j<sizeof(m_opad); j++)
|
||||
{
|
||||
m_opad[j] ^= SHA1_Key[j];
|
||||
}
|
||||
|
||||
/* STEP 6 */
|
||||
memcpy(AppendBuf2, m_opad, sizeof(m_opad));
|
||||
memcpy(AppendBuf2 + sizeof(m_opad), szReport, SHA1_DIGEST_LENGTH);
|
||||
|
||||
/*STEP 7 */
|
||||
CSHA1::Reset();
|
||||
CSHA1::Update((UINT_8 *)AppendBuf2, sizeof(m_opad) + SHA1_DIGEST_LENGTH);
|
||||
CSHA1::Final();
|
||||
|
||||
CSHA1::GetHash((UINT_8 *)digest);
|
||||
}
|
||||
|
|
|
@ -1,53 +1,53 @@
|
|||
/*
|
||||
100% free public domain implementation of the HMAC-SHA1 algorithm
|
||||
by Chien-Chung, Chung (Jim Chung) <jimchung1221@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __HMAC_SHA1_H__
|
||||
#define __HMAC_SHA1_H__
|
||||
|
||||
#include "SHA1.h"
|
||||
|
||||
typedef unsigned char BYTE ;
|
||||
|
||||
class CHMAC_SHA1 : public CSHA1
|
||||
{
|
||||
private:
|
||||
BYTE m_ipad[64];
|
||||
BYTE m_opad[64];
|
||||
|
||||
char * szReport ;
|
||||
char * SHA1_Key ;
|
||||
char * AppendBuf1 ;
|
||||
char * AppendBuf2 ;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
SHA1_DIGEST_LENGTH = 20,
|
||||
SHA1_BLOCK_SIZE = 64,
|
||||
HMAC_BUF_LEN = 4096
|
||||
} ;
|
||||
|
||||
CHMAC_SHA1()
|
||||
:szReport(new char[HMAC_BUF_LEN]),
|
||||
SHA1_Key(new char[HMAC_BUF_LEN]),
|
||||
AppendBuf1(new char[HMAC_BUF_LEN]),
|
||||
AppendBuf2(new char[HMAC_BUF_LEN])
|
||||
{}
|
||||
|
||||
~CHMAC_SHA1()
|
||||
{
|
||||
delete[] szReport ;
|
||||
delete[] AppendBuf1 ;
|
||||
delete[] AppendBuf2 ;
|
||||
delete[] SHA1_Key ;
|
||||
}
|
||||
|
||||
void HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __HMAC_SHA1_H__ */
|
||||
/*
|
||||
100% free public domain implementation of the HMAC-SHA1 algorithm
|
||||
by Chien-Chung, Chung (Jim Chung) <jimchung1221@gmail.com>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __HMAC_SHA1_H__
|
||||
#define __HMAC_SHA1_H__
|
||||
|
||||
#include "SHA1.h"
|
||||
|
||||
typedef unsigned char BYTE ;
|
||||
|
||||
class CHMAC_SHA1 : public CSHA1
|
||||
{
|
||||
private:
|
||||
BYTE m_ipad[64];
|
||||
BYTE m_opad[64];
|
||||
|
||||
char * szReport ;
|
||||
char * SHA1_Key ;
|
||||
char * AppendBuf1 ;
|
||||
char * AppendBuf2 ;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
enum {
|
||||
SHA1_DIGEST_LENGTH = 20,
|
||||
SHA1_BLOCK_SIZE = 64,
|
||||
HMAC_BUF_LEN = 4096
|
||||
} ;
|
||||
|
||||
CHMAC_SHA1()
|
||||
:szReport(new char[HMAC_BUF_LEN]),
|
||||
SHA1_Key(new char[HMAC_BUF_LEN]),
|
||||
AppendBuf1(new char[HMAC_BUF_LEN]),
|
||||
AppendBuf2(new char[HMAC_BUF_LEN])
|
||||
{}
|
||||
|
||||
~CHMAC_SHA1()
|
||||
{
|
||||
delete[] szReport ;
|
||||
delete[] AppendBuf1 ;
|
||||
delete[] AppendBuf2 ;
|
||||
delete[] SHA1_Key ;
|
||||
}
|
||||
|
||||
void HMAC_SHA1(BYTE *text, int text_len, BYTE *key, int key_len, BYTE *digest);
|
||||
};
|
||||
|
||||
|
||||
#endif /* __HMAC_SHA1_H__ */
|
||||
|
|
|
@ -1,274 +1,274 @@
|
|||
/*
|
||||
100% free public domain implementation of the SHA-1 algorithm
|
||||
by Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Web: http://www.dominik-reichl.de/
|
||||
|
||||
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
|
||||
- You can set the endianness in your files, no need to modify the
|
||||
header file of the CSHA1 class any more
|
||||
- Aligned data support
|
||||
- Made support/compilation of the utility functions (ReportHash
|
||||
and HashFile) optional (useful, if bytes count, for example in
|
||||
embedded environments)
|
||||
|
||||
Version 1.5 - 2005-01-01
|
||||
- 64-bit compiler compatibility added
|
||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
|
||||
- Removed unnecessary variable initializations
|
||||
- ROL32 improvement for the Microsoft compiler (using _rotl)
|
||||
|
||||
======== Test Vectors (from FIPS PUB 180-1) ========
|
||||
|
||||
SHA1("abc") =
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
|
||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
|
||||
SHA1(A million repetitions of "a") =
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#include "SHA1.h"
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
#define SHA1_MAX_FILE_BUFFER 8000
|
||||
#endif
|
||||
|
||||
// Rotate x bits to the left
|
||||
#ifndef ROL32
|
||||
#ifdef _MSC_VER
|
||||
#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
|
||||
#else
|
||||
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SHA1_LITTLE_ENDIAN
|
||||
#define SHABLK0(i) (m_block->l[i] = \
|
||||
(ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
|
||||
#else
|
||||
#define SHABLK0(i) (m_block->l[i])
|
||||
#endif
|
||||
|
||||
#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \
|
||||
^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
|
||||
|
||||
// SHA-1 rounds
|
||||
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
|
||||
|
||||
CSHA1::CSHA1()
|
||||
{
|
||||
m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
CSHA1::~CSHA1()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void CSHA1::Reset()
|
||||
{
|
||||
// SHA1 initialization constants
|
||||
m_state[0] = 0x67452301;
|
||||
m_state[1] = 0xEFCDAB89;
|
||||
m_state[2] = 0x98BADCFE;
|
||||
m_state[3] = 0x10325476;
|
||||
m_state[4] = 0xC3D2E1F0;
|
||||
|
||||
m_count[0] = 0;
|
||||
m_count[1] = 0;
|
||||
}
|
||||
|
||||
void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer)
|
||||
{
|
||||
// Copy state[] to working vars
|
||||
UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
|
||||
|
||||
memcpy(m_block, buffer, 64);
|
||||
|
||||
// 4 rounds of 20 operations each. Loop unrolled.
|
||||
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
|
||||
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
|
||||
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
|
||||
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
|
||||
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
|
||||
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
|
||||
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
|
||||
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
|
||||
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
|
||||
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
|
||||
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
|
||||
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
|
||||
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
|
||||
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
|
||||
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
|
||||
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
|
||||
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
|
||||
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
|
||||
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
|
||||
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
|
||||
|
||||
// Add the working vars back into state
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
// Wipe variables
|
||||
#ifdef SHA1_WIPE_VARIABLES
|
||||
a = b = c = d = e = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use this function to hash in binary data and strings
|
||||
void CSHA1::Update(UINT_8 *data, UINT_32 len)
|
||||
{
|
||||
UINT_32 i, j;
|
||||
|
||||
j = (m_count[0] >> 3) & 63;
|
||||
|
||||
if((m_count[0] += len << 3) < (len << 3)) m_count[1]++;
|
||||
|
||||
m_count[1] += (len >> 29);
|
||||
|
||||
if((j + len) > 63)
|
||||
{
|
||||
i = 64 - j;
|
||||
memcpy(&m_buffer[j], data, i);
|
||||
Transform(m_state, m_buffer);
|
||||
|
||||
for(; i + 63 < len; i += 64) Transform(m_state, &data[i]);
|
||||
|
||||
j = 0;
|
||||
}
|
||||
else i = 0;
|
||||
|
||||
memcpy(&m_buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Hash in file contents
|
||||
bool CSHA1::HashFile(char *szFileName)
|
||||
{
|
||||
unsigned long ulFileSize, ulRest, ulBlocks;
|
||||
unsigned long i;
|
||||
UINT_8 uData[SHA1_MAX_FILE_BUFFER];
|
||||
FILE *fIn;
|
||||
|
||||
if(szFileName == NULL) return false;
|
||||
|
||||
fIn = fopen(szFileName, "rb");
|
||||
if(fIn == NULL) return false;
|
||||
|
||||
fseek(fIn, 0, SEEK_END);
|
||||
ulFileSize = (unsigned long)ftell(fIn);
|
||||
fseek(fIn, 0, SEEK_SET);
|
||||
|
||||
if(ulFileSize != 0)
|
||||
{
|
||||
ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
|
||||
ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulBlocks = 0;
|
||||
ulRest = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < ulBlocks; i++)
|
||||
{
|
||||
fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
|
||||
Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER);
|
||||
}
|
||||
|
||||
if(ulRest != 0)
|
||||
{
|
||||
fread(uData, 1, ulRest, fIn);
|
||||
Update((UINT_8 *)uData, ulRest);
|
||||
}
|
||||
|
||||
fclose(fIn); fIn = NULL;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CSHA1::Final()
|
||||
{
|
||||
UINT_32 i;
|
||||
UINT_8 finalcount[8];
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
|
||||
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
|
||||
|
||||
Update((UINT_8 *)"\200", 1);
|
||||
|
||||
while ((m_count[0] & 504) != 448)
|
||||
Update((UINT_8 *)"\0", 1);
|
||||
|
||||
Update(finalcount, 8); // Cause a SHA1Transform()
|
||||
|
||||
for(i = 0; i < 20; i++)
|
||||
{
|
||||
m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255);
|
||||
}
|
||||
|
||||
// Wipe variables for security reasons
|
||||
#ifdef SHA1_WIPE_VARIABLES
|
||||
i = 0;
|
||||
memset(m_buffer, 0, 64);
|
||||
memset(m_state, 0, 20);
|
||||
memset(m_count, 0, 8);
|
||||
memset(finalcount, 0, 8);
|
||||
Transform(m_state, m_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Get the final hash as a pre-formatted string
|
||||
void CSHA1::ReportHash(char *szReport, unsigned char uReportType)
|
||||
{
|
||||
unsigned char i;
|
||||
char szTemp[16];
|
||||
|
||||
if(szReport == NULL) return;
|
||||
|
||||
if(uReportType == REPORT_HEX)
|
||||
{
|
||||
sprintf(szTemp, "%02X", m_digest[0]);
|
||||
strcat(szReport, szTemp);
|
||||
|
||||
for(i = 1; i < 20; i++)
|
||||
{
|
||||
sprintf(szTemp, " %02X", m_digest[i]);
|
||||
strcat(szReport, szTemp);
|
||||
}
|
||||
}
|
||||
else if(uReportType == REPORT_DIGIT)
|
||||
{
|
||||
sprintf(szTemp, "%u", m_digest[0]);
|
||||
strcat(szReport, szTemp);
|
||||
|
||||
for(i = 1; i < 20; i++)
|
||||
{
|
||||
sprintf(szTemp, " %u", m_digest[i]);
|
||||
strcat(szReport, szTemp);
|
||||
}
|
||||
}
|
||||
else strcpy(szReport, "Error: Unknown report type!");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the raw message digest
|
||||
void CSHA1::GetHash(UINT_8 *puDest)
|
||||
{
|
||||
memcpy(puDest, m_digest, 20);
|
||||
}
|
||||
/*
|
||||
100% free public domain implementation of the SHA-1 algorithm
|
||||
by Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Web: http://www.dominik-reichl.de/
|
||||
|
||||
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
|
||||
- You can set the endianness in your files, no need to modify the
|
||||
header file of the CSHA1 class any more
|
||||
- Aligned data support
|
||||
- Made support/compilation of the utility functions (ReportHash
|
||||
and HashFile) optional (useful, if bytes count, for example in
|
||||
embedded environments)
|
||||
|
||||
Version 1.5 - 2005-01-01
|
||||
- 64-bit compiler compatibility added
|
||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
|
||||
- Removed unnecessary variable initializations
|
||||
- ROL32 improvement for the Microsoft compiler (using _rotl)
|
||||
|
||||
======== Test Vectors (from FIPS PUB 180-1) ========
|
||||
|
||||
SHA1("abc") =
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
|
||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
|
||||
SHA1(A million repetitions of "a") =
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#include "SHA1.h"
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
#define SHA1_MAX_FILE_BUFFER 8000
|
||||
#endif
|
||||
|
||||
// Rotate x bits to the left
|
||||
#ifndef ROL32
|
||||
#ifdef _MSC_VER
|
||||
#define ROL32(_val32, _nBits) _rotl(_val32, _nBits)
|
||||
#else
|
||||
#define ROL32(_val32, _nBits) (((_val32)<<(_nBits))|((_val32)>>(32-(_nBits))))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SHA1_LITTLE_ENDIAN
|
||||
#define SHABLK0(i) (m_block->l[i] = \
|
||||
(ROL32(m_block->l[i],24) & 0xFF00FF00) | (ROL32(m_block->l[i],8) & 0x00FF00FF))
|
||||
#else
|
||||
#define SHABLK0(i) (m_block->l[i])
|
||||
#endif
|
||||
|
||||
#define SHABLK(i) (m_block->l[i&15] = ROL32(m_block->l[(i+13)&15] ^ m_block->l[(i+8)&15] \
|
||||
^ m_block->l[(i+2)&15] ^ m_block->l[i&15],1))
|
||||
|
||||
// SHA-1 rounds
|
||||
#define _R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
|
||||
#define _R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
|
||||
|
||||
CSHA1::CSHA1()
|
||||
{
|
||||
m_block = (SHA1_WORKSPACE_BLOCK *)m_workspace;
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
CSHA1::~CSHA1()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
void CSHA1::Reset()
|
||||
{
|
||||
// SHA1 initialization constants
|
||||
m_state[0] = 0x67452301;
|
||||
m_state[1] = 0xEFCDAB89;
|
||||
m_state[2] = 0x98BADCFE;
|
||||
m_state[3] = 0x10325476;
|
||||
m_state[4] = 0xC3D2E1F0;
|
||||
|
||||
m_count[0] = 0;
|
||||
m_count[1] = 0;
|
||||
}
|
||||
|
||||
void CSHA1::Transform(UINT_32 *state, UINT_8 *buffer)
|
||||
{
|
||||
// Copy state[] to working vars
|
||||
UINT_32 a = state[0], b = state[1], c = state[2], d = state[3], e = state[4];
|
||||
|
||||
memcpy(m_block, buffer, 64);
|
||||
|
||||
// 4 rounds of 20 operations each. Loop unrolled.
|
||||
_R0(a,b,c,d,e, 0); _R0(e,a,b,c,d, 1); _R0(d,e,a,b,c, 2); _R0(c,d,e,a,b, 3);
|
||||
_R0(b,c,d,e,a, 4); _R0(a,b,c,d,e, 5); _R0(e,a,b,c,d, 6); _R0(d,e,a,b,c, 7);
|
||||
_R0(c,d,e,a,b, 8); _R0(b,c,d,e,a, 9); _R0(a,b,c,d,e,10); _R0(e,a,b,c,d,11);
|
||||
_R0(d,e,a,b,c,12); _R0(c,d,e,a,b,13); _R0(b,c,d,e,a,14); _R0(a,b,c,d,e,15);
|
||||
_R1(e,a,b,c,d,16); _R1(d,e,a,b,c,17); _R1(c,d,e,a,b,18); _R1(b,c,d,e,a,19);
|
||||
_R2(a,b,c,d,e,20); _R2(e,a,b,c,d,21); _R2(d,e,a,b,c,22); _R2(c,d,e,a,b,23);
|
||||
_R2(b,c,d,e,a,24); _R2(a,b,c,d,e,25); _R2(e,a,b,c,d,26); _R2(d,e,a,b,c,27);
|
||||
_R2(c,d,e,a,b,28); _R2(b,c,d,e,a,29); _R2(a,b,c,d,e,30); _R2(e,a,b,c,d,31);
|
||||
_R2(d,e,a,b,c,32); _R2(c,d,e,a,b,33); _R2(b,c,d,e,a,34); _R2(a,b,c,d,e,35);
|
||||
_R2(e,a,b,c,d,36); _R2(d,e,a,b,c,37); _R2(c,d,e,a,b,38); _R2(b,c,d,e,a,39);
|
||||
_R3(a,b,c,d,e,40); _R3(e,a,b,c,d,41); _R3(d,e,a,b,c,42); _R3(c,d,e,a,b,43);
|
||||
_R3(b,c,d,e,a,44); _R3(a,b,c,d,e,45); _R3(e,a,b,c,d,46); _R3(d,e,a,b,c,47);
|
||||
_R3(c,d,e,a,b,48); _R3(b,c,d,e,a,49); _R3(a,b,c,d,e,50); _R3(e,a,b,c,d,51);
|
||||
_R3(d,e,a,b,c,52); _R3(c,d,e,a,b,53); _R3(b,c,d,e,a,54); _R3(a,b,c,d,e,55);
|
||||
_R3(e,a,b,c,d,56); _R3(d,e,a,b,c,57); _R3(c,d,e,a,b,58); _R3(b,c,d,e,a,59);
|
||||
_R4(a,b,c,d,e,60); _R4(e,a,b,c,d,61); _R4(d,e,a,b,c,62); _R4(c,d,e,a,b,63);
|
||||
_R4(b,c,d,e,a,64); _R4(a,b,c,d,e,65); _R4(e,a,b,c,d,66); _R4(d,e,a,b,c,67);
|
||||
_R4(c,d,e,a,b,68); _R4(b,c,d,e,a,69); _R4(a,b,c,d,e,70); _R4(e,a,b,c,d,71);
|
||||
_R4(d,e,a,b,c,72); _R4(c,d,e,a,b,73); _R4(b,c,d,e,a,74); _R4(a,b,c,d,e,75);
|
||||
_R4(e,a,b,c,d,76); _R4(d,e,a,b,c,77); _R4(c,d,e,a,b,78); _R4(b,c,d,e,a,79);
|
||||
|
||||
// Add the working vars back into state
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
state[4] += e;
|
||||
|
||||
// Wipe variables
|
||||
#ifdef SHA1_WIPE_VARIABLES
|
||||
a = b = c = d = e = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Use this function to hash in binary data and strings
|
||||
void CSHA1::Update(UINT_8 *data, UINT_32 len)
|
||||
{
|
||||
UINT_32 i, j;
|
||||
|
||||
j = (m_count[0] >> 3) & 63;
|
||||
|
||||
if((m_count[0] += len << 3) < (len << 3)) m_count[1]++;
|
||||
|
||||
m_count[1] += (len >> 29);
|
||||
|
||||
if((j + len) > 63)
|
||||
{
|
||||
i = 64 - j;
|
||||
memcpy(&m_buffer[j], data, i);
|
||||
Transform(m_state, m_buffer);
|
||||
|
||||
for(; i + 63 < len; i += 64) Transform(m_state, &data[i]);
|
||||
|
||||
j = 0;
|
||||
}
|
||||
else i = 0;
|
||||
|
||||
memcpy(&m_buffer[j], &data[i], len - i);
|
||||
}
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Hash in file contents
|
||||
bool CSHA1::HashFile(char *szFileName)
|
||||
{
|
||||
unsigned long ulFileSize, ulRest, ulBlocks;
|
||||
unsigned long i;
|
||||
UINT_8 uData[SHA1_MAX_FILE_BUFFER];
|
||||
FILE *fIn;
|
||||
|
||||
if(szFileName == NULL) return false;
|
||||
|
||||
fIn = fopen(szFileName, "rb");
|
||||
if(fIn == NULL) return false;
|
||||
|
||||
fseek(fIn, 0, SEEK_END);
|
||||
ulFileSize = (unsigned long)ftell(fIn);
|
||||
fseek(fIn, 0, SEEK_SET);
|
||||
|
||||
if(ulFileSize != 0)
|
||||
{
|
||||
ulBlocks = ulFileSize / SHA1_MAX_FILE_BUFFER;
|
||||
ulRest = ulFileSize % SHA1_MAX_FILE_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
ulBlocks = 0;
|
||||
ulRest = 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < ulBlocks; i++)
|
||||
{
|
||||
fread(uData, 1, SHA1_MAX_FILE_BUFFER, fIn);
|
||||
Update((UINT_8 *)uData, SHA1_MAX_FILE_BUFFER);
|
||||
}
|
||||
|
||||
if(ulRest != 0)
|
||||
{
|
||||
fread(uData, 1, ulRest, fIn);
|
||||
Update((UINT_8 *)uData, ulRest);
|
||||
}
|
||||
|
||||
fclose(fIn); fIn = NULL;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void CSHA1::Final()
|
||||
{
|
||||
UINT_32 i;
|
||||
UINT_8 finalcount[8];
|
||||
|
||||
for(i = 0; i < 8; i++)
|
||||
finalcount[i] = (UINT_8)((m_count[((i >= 4) ? 0 : 1)]
|
||||
>> ((3 - (i & 3)) * 8) ) & 255); // Endian independent
|
||||
|
||||
Update((UINT_8 *)"\200", 1);
|
||||
|
||||
while ((m_count[0] & 504) != 448)
|
||||
Update((UINT_8 *)"\0", 1);
|
||||
|
||||
Update(finalcount, 8); // Cause a SHA1Transform()
|
||||
|
||||
for(i = 0; i < 20; i++)
|
||||
{
|
||||
m_digest[i] = (UINT_8)((m_state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255);
|
||||
}
|
||||
|
||||
// Wipe variables for security reasons
|
||||
#ifdef SHA1_WIPE_VARIABLES
|
||||
i = 0;
|
||||
memset(m_buffer, 0, 64);
|
||||
memset(m_state, 0, 20);
|
||||
memset(m_count, 0, 8);
|
||||
memset(finalcount, 0, 8);
|
||||
Transform(m_state, m_buffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Get the final hash as a pre-formatted string
|
||||
void CSHA1::ReportHash(char *szReport, unsigned char uReportType)
|
||||
{
|
||||
unsigned char i;
|
||||
char szTemp[16];
|
||||
|
||||
if(szReport == NULL) return;
|
||||
|
||||
if(uReportType == REPORT_HEX)
|
||||
{
|
||||
sprintf(szTemp, "%02X", m_digest[0]);
|
||||
strcat(szReport, szTemp);
|
||||
|
||||
for(i = 1; i < 20; i++)
|
||||
{
|
||||
sprintf(szTemp, " %02X", m_digest[i]);
|
||||
strcat(szReport, szTemp);
|
||||
}
|
||||
}
|
||||
else if(uReportType == REPORT_DIGIT)
|
||||
{
|
||||
sprintf(szTemp, "%u", m_digest[0]);
|
||||
strcat(szReport, szTemp);
|
||||
|
||||
for(i = 1; i < 20; i++)
|
||||
{
|
||||
sprintf(szTemp, " %u", m_digest[i]);
|
||||
strcat(szReport, szTemp);
|
||||
}
|
||||
}
|
||||
else strcpy(szReport, "Error: Unknown report type!");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Get the raw message digest
|
||||
void CSHA1::GetHash(UINT_8 *puDest)
|
||||
{
|
||||
memcpy(puDest, m_digest, 20);
|
||||
}
|
||||
|
|
|
@ -1,148 +1,148 @@
|
|||
/*
|
||||
100% free public domain implementation of the SHA-1 algorithm
|
||||
by Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Web: http://www.dominik-reichl.de/
|
||||
|
||||
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
|
||||
- You can set the endianness in your files, no need to modify the
|
||||
header file of the CSHA1 class any more
|
||||
- Aligned data support
|
||||
- Made support/compilation of the utility functions (ReportHash
|
||||
and HashFile) optional (useful, if bytes count, for example in
|
||||
embedded environments)
|
||||
|
||||
Version 1.5 - 2005-01-01
|
||||
- 64-bit compiler compatibility added
|
||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
|
||||
- Removed unnecessary variable initializations
|
||||
- ROL32 improvement for the Microsoft compiler (using _rotl)
|
||||
|
||||
======== Test Vectors (from FIPS PUB 180-1) ========
|
||||
|
||||
SHA1("abc") =
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
|
||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
|
||||
SHA1(A million repetitions of "a") =
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#ifndef ___SHA1_HDR___
|
||||
#define ___SHA1_HDR___
|
||||
|
||||
#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
|
||||
#define SHA1_UTILITY_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include <memory.h> // Needed for memset and memcpy
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
#include <stdio.h> // Needed for file access and sprintf
|
||||
#include <string.h> // Needed for strcat and strcpy
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
// You can define the endian mode in your files, without modifying the SHA1
|
||||
// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
|
||||
// in your files, before including the SHA1.h header file. If you don't
|
||||
// define anything, the class defaults to little endian.
|
||||
|
||||
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
|
||||
#define SHA1_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
|
||||
// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
|
||||
// defaults to wiping.
|
||||
|
||||
#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
|
||||
#define SHA1_WIPE_VARIABLES
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Define 8- and 32-bit variables
|
||||
|
||||
#ifndef UINT_32
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define UINT_8 unsigned __int8
|
||||
#define UINT_32 unsigned __int32
|
||||
|
||||
#else
|
||||
|
||||
#define UINT_8 unsigned char
|
||||
|
||||
#if (ULONG_MAX == 0xFFFFFFFF)
|
||||
#define UINT_32 unsigned long
|
||||
#else
|
||||
#define UINT_32 unsigned int
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Declare SHA1 workspace
|
||||
|
||||
typedef union
|
||||
{
|
||||
UINT_8 c[64];
|
||||
UINT_32 l[16];
|
||||
} SHA1_WORKSPACE_BLOCK;
|
||||
|
||||
class CSHA1
|
||||
{
|
||||
public:
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Two different formats for ReportHash(...)
|
||||
enum
|
||||
{
|
||||
REPORT_HEX = 0,
|
||||
REPORT_DIGIT = 1
|
||||
};
|
||||
#endif
|
||||
|
||||
// Constructor and Destructor
|
||||
CSHA1();
|
||||
~CSHA1();
|
||||
|
||||
UINT_32 m_state[5];
|
||||
UINT_32 m_count[2];
|
||||
UINT_32 __reserved1[1];
|
||||
UINT_8 m_buffer[64];
|
||||
UINT_8 m_digest[20];
|
||||
UINT_32 __reserved2[3];
|
||||
|
||||
void Reset();
|
||||
|
||||
// Update the hash value
|
||||
void Update(UINT_8 *data, UINT_32 len);
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
bool HashFile(char *szFileName);
|
||||
#endif
|
||||
|
||||
// Finalize hash and report
|
||||
void Final();
|
||||
|
||||
// Report functions: as pre-formatted and raw data
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
|
||||
#endif
|
||||
void GetHash(UINT_8 *puDest);
|
||||
|
||||
private:
|
||||
// Private SHA-1 transformation
|
||||
void Transform(UINT_32 *state, UINT_8 *buffer);
|
||||
|
||||
// Member variables
|
||||
UINT_8 m_workspace[64];
|
||||
SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
|
||||
};
|
||||
|
||||
#endif
|
||||
/*
|
||||
100% free public domain implementation of the SHA-1 algorithm
|
||||
by Dominik Reichl <dominik.reichl@t-online.de>
|
||||
Web: http://www.dominik-reichl.de/
|
||||
|
||||
Version 1.6 - 2005-02-07 (thanks to Howard Kapustein for patches)
|
||||
- You can set the endianness in your files, no need to modify the
|
||||
header file of the CSHA1 class any more
|
||||
- Aligned data support
|
||||
- Made support/compilation of the utility functions (ReportHash
|
||||
and HashFile) optional (useful, if bytes count, for example in
|
||||
embedded environments)
|
||||
|
||||
Version 1.5 - 2005-01-01
|
||||
- 64-bit compiler compatibility added
|
||||
- Made variable wiping optional (define SHA1_WIPE_VARIABLES)
|
||||
- Removed unnecessary variable initializations
|
||||
- ROL32 improvement for the Microsoft compiler (using _rotl)
|
||||
|
||||
======== Test Vectors (from FIPS PUB 180-1) ========
|
||||
|
||||
SHA1("abc") =
|
||||
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||
|
||||
SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") =
|
||||
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||
|
||||
SHA1(A million repetitions of "a") =
|
||||
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||
*/
|
||||
|
||||
#ifndef ___SHA1_HDR___
|
||||
#define ___SHA1_HDR___
|
||||
|
||||
#if !defined(SHA1_UTILITY_FUNCTIONS) && !defined(SHA1_NO_UTILITY_FUNCTIONS)
|
||||
#define SHA1_UTILITY_FUNCTIONS
|
||||
#endif
|
||||
|
||||
#include <memory.h> // Needed for memset and memcpy
|
||||
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
#include <stdio.h> // Needed for file access and sprintf
|
||||
#include <string.h> // Needed for strcat and strcpy
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
// You can define the endian mode in your files, without modifying the SHA1
|
||||
// source files. Just #define SHA1_LITTLE_ENDIAN or #define SHA1_BIG_ENDIAN
|
||||
// in your files, before including the SHA1.h header file. If you don't
|
||||
// define anything, the class defaults to little endian.
|
||||
|
||||
#if !defined(SHA1_LITTLE_ENDIAN) && !defined(SHA1_BIG_ENDIAN)
|
||||
#define SHA1_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
// Same here. If you want variable wiping, #define SHA1_WIPE_VARIABLES, if
|
||||
// not, #define SHA1_NO_WIPE_VARIABLES. If you don't define anything, it
|
||||
// defaults to wiping.
|
||||
|
||||
#if !defined(SHA1_WIPE_VARIABLES) && !defined(SHA1_NO_WIPE_VARIABLES)
|
||||
#define SHA1_WIPE_VARIABLES
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Define 8- and 32-bit variables
|
||||
|
||||
#ifndef UINT_32
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
#define UINT_8 unsigned __int8
|
||||
#define UINT_32 unsigned __int32
|
||||
|
||||
#else
|
||||
|
||||
#define UINT_8 unsigned char
|
||||
|
||||
#if (ULONG_MAX == 0xFFFFFFFF)
|
||||
#define UINT_32 unsigned long
|
||||
#else
|
||||
#define UINT_32 unsigned int
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Declare SHA1 workspace
|
||||
|
||||
typedef union
|
||||
{
|
||||
UINT_8 c[64];
|
||||
UINT_32 l[16];
|
||||
} SHA1_WORKSPACE_BLOCK;
|
||||
|
||||
class CSHA1
|
||||
{
|
||||
public:
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
// Two different formats for ReportHash(...)
|
||||
enum
|
||||
{
|
||||
REPORT_HEX = 0,
|
||||
REPORT_DIGIT = 1
|
||||
};
|
||||
#endif
|
||||
|
||||
// Constructor and Destructor
|
||||
CSHA1();
|
||||
~CSHA1();
|
||||
|
||||
UINT_32 m_state[5];
|
||||
UINT_32 m_count[2];
|
||||
UINT_32 __reserved1[1];
|
||||
UINT_8 m_buffer[64];
|
||||
UINT_8 m_digest[20];
|
||||
UINT_32 __reserved2[3];
|
||||
|
||||
void Reset();
|
||||
|
||||
// Update the hash value
|
||||
void Update(UINT_8 *data, UINT_32 len);
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
bool HashFile(char *szFileName);
|
||||
#endif
|
||||
|
||||
// Finalize hash and report
|
||||
void Final();
|
||||
|
||||
// Report functions: as pre-formatted and raw data
|
||||
#ifdef SHA1_UTILITY_FUNCTIONS
|
||||
void ReportHash(char *szReport, unsigned char uReportType = REPORT_HEX);
|
||||
#endif
|
||||
void GetHash(UINT_8 *puDest);
|
||||
|
||||
private:
|
||||
// Private SHA-1 transformation
|
||||
void Transform(UINT_32 *state, UINT_8 *buffer);
|
||||
|
||||
// Member variables
|
||||
UINT_8 m_workspace[64];
|
||||
SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,123 +1,123 @@
|
|||
/*
|
||||
base64.cpp and base64.h
|
||||
|
||||
Copyright (C) 2004-2008 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
#include <iostream>
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
/*
|
||||
base64.cpp and base64.h
|
||||
|
||||
Copyright (C) 2004-2008 René Nyffenegger
|
||||
|
||||
This source code is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this source code must not be misrepresented; you must not
|
||||
claim that you wrote the original source code. If you use this source code
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original source code.
|
||||
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
René Nyffenegger rene.nyffenegger@adp-gmbh.ch
|
||||
|
||||
*/
|
||||
|
||||
#include "base64.h"
|
||||
#include <iostream>
|
||||
|
||||
static const std::string base64_chars =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
|
||||
static inline bool is_base64(unsigned char c) {
|
||||
return (isalnum(c) || (c == '+') || (c == '/'));
|
||||
}
|
||||
|
||||
std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
|
||||
std::string ret;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
unsigned char char_array_3[3];
|
||||
unsigned char char_array_4[4];
|
||||
|
||||
while (in_len--) {
|
||||
char_array_3[i++] = *(bytes_to_encode++);
|
||||
if (i == 3) {
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for(i = 0; (i <4) ; i++)
|
||||
ret += base64_chars[char_array_4[i]];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i)
|
||||
{
|
||||
for(j = i; j < 3; j++)
|
||||
char_array_3[j] = '\0';
|
||||
|
||||
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
|
||||
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
|
||||
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
|
||||
char_array_4[3] = char_array_3[2] & 0x3f;
|
||||
|
||||
for (j = 0; (j < i + 1); j++)
|
||||
ret += base64_chars[char_array_4[j]];
|
||||
|
||||
while((i++ < 3))
|
||||
ret += '=';
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
std::string base64_decode(std::string const& encoded_string) {
|
||||
int in_len = encoded_string.size();
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
int in_ = 0;
|
||||
unsigned char char_array_4[4], char_array_3[3];
|
||||
std::string ret;
|
||||
|
||||
while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
|
||||
char_array_4[i++] = encoded_string[in_]; in_++;
|
||||
if (i ==4) {
|
||||
for (i = 0; i <4; i++)
|
||||
char_array_4[i] = base64_chars.find(char_array_4[i]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (i = 0; (i < 3); i++)
|
||||
ret += char_array_3[i];
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (i) {
|
||||
for (j = i; j <4; j++)
|
||||
char_array_4[j] = 0;
|
||||
|
||||
for (j = 0; j <4; j++)
|
||||
char_array_4[j] = base64_chars.find(char_array_4[j]);
|
||||
|
||||
char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
|
||||
char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
|
||||
char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
|
||||
|
||||
for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#include <string>
|
||||
|
||||
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||
#include <string>
|
||||
|
||||
std::string base64_encode(unsigned char const* , unsigned int len);
|
||||
std::string base64_decode(std::string const& s);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,93 +1,93 @@
|
|||
#ifndef __OAUTHLIB_H__
|
||||
#define __OAUTHLIB_H__
|
||||
|
||||
#include "time.h"
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
typedef enum _eOAuthHttpRequestType
|
||||
{
|
||||
eOAuthHttpInvalid = 0,
|
||||
eOAuthHttpGet,
|
||||
eOAuthHttpPost,
|
||||
eOAuthHttpDelete
|
||||
} eOAuthHttpRequestType;
|
||||
|
||||
typedef std::list<std::string> oAuthKeyValueList;
|
||||
typedef std::map<std::string, std::string> oAuthKeyValuePairs;
|
||||
|
||||
class oAuth
|
||||
{
|
||||
public:
|
||||
oAuth();
|
||||
~oAuth();
|
||||
|
||||
/* OAuth public methods used by twitCurl */
|
||||
void getConsumerKey( std::string& consumerKey /* out */ );
|
||||
void setConsumerKey( const std::string& consumerKey /* in */ );
|
||||
|
||||
void getConsumerSecret( std::string& consumerSecret /* out */ );
|
||||
void setConsumerSecret( const std::string& consumerSecret /* in */ );
|
||||
|
||||
void getOAuthTokenKey( std::string& oAuthTokenKey /* out */ );
|
||||
void setOAuthTokenKey( const std::string& oAuthTokenKey /* in */ );
|
||||
|
||||
void getOAuthTokenSecret( std::string& oAuthTokenSecret /* out */ );
|
||||
void setOAuthTokenSecret( const std::string& oAuthTokenSecret /* in */ );
|
||||
|
||||
void getOAuthScreenName( std::string& oAuthScreenName /* out */ );
|
||||
void setOAuthScreenName( const std::string& oAuthScreenName /* in */ );
|
||||
|
||||
void getOAuthPin( std::string& oAuthPin /* out */ );
|
||||
void setOAuthPin( const std::string& oAuthPin /* in */ );
|
||||
|
||||
bool getOAuthHeader( const eOAuthHttpRequestType eType, /* in */
|
||||
const std::string& rawUrl, /* in */
|
||||
const std::string& rawData, /* in */
|
||||
std::string& oAuthHttpHeader, /* out */
|
||||
const bool includeOAuthVerifierPin = false /* in */ );
|
||||
|
||||
bool extractOAuthTokenKeySecret( const std::string& requestTokenResponse /* in */ );
|
||||
|
||||
oAuth clone();
|
||||
|
||||
private:
|
||||
|
||||
/* OAuth data */
|
||||
std::string m_consumerKey;
|
||||
std::string m_consumerSecret;
|
||||
std::string m_oAuthTokenKey;
|
||||
std::string m_oAuthTokenSecret;
|
||||
std::string m_oAuthPin;
|
||||
std::string m_nonce;
|
||||
std::string m_timeStamp;
|
||||
std::string m_oAuthScreenName;
|
||||
|
||||
/* OAuth twitter related utility methods */
|
||||
void buildOAuthRawDataKeyValPairs( const std::string& rawData, /* in */
|
||||
bool urlencodeData, /* in */
|
||||
oAuthKeyValuePairs& rawDataKeyValuePairs /* out */ );
|
||||
|
||||
bool buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, /* in */
|
||||
const std::string& oauthSignature, /* in */
|
||||
oAuthKeyValuePairs& keyValueMap /* out */,
|
||||
const bool generateTimestamp /* in */ );
|
||||
|
||||
bool getStringFromOAuthKeyValuePairs( const oAuthKeyValuePairs& rawParamMap, /* in */
|
||||
std::string& rawParams, /* out */
|
||||
const std::string& paramsSeperator /* in */ );
|
||||
|
||||
bool getSignature( const eOAuthHttpRequestType eType, /* in */
|
||||
const std::string& rawUrl, /* in */
|
||||
const oAuthKeyValuePairs& rawKeyValuePairs, /* in */
|
||||
std::string& oAuthSignature /* out */ );
|
||||
|
||||
void generateNonceTimeStamp();
|
||||
};
|
||||
|
||||
#endif // __OAUTHLIB_H__
|
||||
#ifndef __OAUTHLIB_H__
|
||||
#define __OAUTHLIB_H__
|
||||
|
||||
#include "time.h"
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <map>
|
||||
|
||||
typedef enum _eOAuthHttpRequestType
|
||||
{
|
||||
eOAuthHttpInvalid = 0,
|
||||
eOAuthHttpGet,
|
||||
eOAuthHttpPost,
|
||||
eOAuthHttpDelete
|
||||
} eOAuthHttpRequestType;
|
||||
|
||||
typedef std::list<std::string> oAuthKeyValueList;
|
||||
typedef std::map<std::string, std::string> oAuthKeyValuePairs;
|
||||
|
||||
class oAuth
|
||||
{
|
||||
public:
|
||||
oAuth();
|
||||
~oAuth();
|
||||
|
||||
/* OAuth public methods used by twitCurl */
|
||||
void getConsumerKey( std::string& consumerKey /* out */ );
|
||||
void setConsumerKey( const std::string& consumerKey /* in */ );
|
||||
|
||||
void getConsumerSecret( std::string& consumerSecret /* out */ );
|
||||
void setConsumerSecret( const std::string& consumerSecret /* in */ );
|
||||
|
||||
void getOAuthTokenKey( std::string& oAuthTokenKey /* out */ );
|
||||
void setOAuthTokenKey( const std::string& oAuthTokenKey /* in */ );
|
||||
|
||||
void getOAuthTokenSecret( std::string& oAuthTokenSecret /* out */ );
|
||||
void setOAuthTokenSecret( const std::string& oAuthTokenSecret /* in */ );
|
||||
|
||||
void getOAuthScreenName( std::string& oAuthScreenName /* out */ );
|
||||
void setOAuthScreenName( const std::string& oAuthScreenName /* in */ );
|
||||
|
||||
void getOAuthPin( std::string& oAuthPin /* out */ );
|
||||
void setOAuthPin( const std::string& oAuthPin /* in */ );
|
||||
|
||||
bool getOAuthHeader( const eOAuthHttpRequestType eType, /* in */
|
||||
const std::string& rawUrl, /* in */
|
||||
const std::string& rawData, /* in */
|
||||
std::string& oAuthHttpHeader, /* out */
|
||||
const bool includeOAuthVerifierPin = false /* in */ );
|
||||
|
||||
bool extractOAuthTokenKeySecret( const std::string& requestTokenResponse /* in */ );
|
||||
|
||||
oAuth clone();
|
||||
|
||||
private:
|
||||
|
||||
/* OAuth data */
|
||||
std::string m_consumerKey;
|
||||
std::string m_consumerSecret;
|
||||
std::string m_oAuthTokenKey;
|
||||
std::string m_oAuthTokenSecret;
|
||||
std::string m_oAuthPin;
|
||||
std::string m_nonce;
|
||||
std::string m_timeStamp;
|
||||
std::string m_oAuthScreenName;
|
||||
|
||||
/* OAuth twitter related utility methods */
|
||||
void buildOAuthRawDataKeyValPairs( const std::string& rawData, /* in */
|
||||
bool urlencodeData, /* in */
|
||||
oAuthKeyValuePairs& rawDataKeyValuePairs /* out */ );
|
||||
|
||||
bool buildOAuthTokenKeyValuePairs( const bool includeOAuthVerifierPin, /* in */
|
||||
const std::string& oauthSignature, /* in */
|
||||
oAuthKeyValuePairs& keyValueMap /* out */,
|
||||
const bool generateTimestamp /* in */ );
|
||||
|
||||
bool getStringFromOAuthKeyValuePairs( const oAuthKeyValuePairs& rawParamMap, /* in */
|
||||
std::string& rawParams, /* out */
|
||||
const std::string& paramsSeperator /* in */ );
|
||||
|
||||
bool getSignature( const eOAuthHttpRequestType eType, /* in */
|
||||
const std::string& rawUrl, /* in */
|
||||
const oAuthKeyValuePairs& rawKeyValuePairs, /* in */
|
||||
std::string& oAuthSignature /* out */ );
|
||||
|
||||
void generateNonceTimeStamp();
|
||||
};
|
||||
|
||||
#endif // __OAUTHLIB_H__
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,140 +1,140 @@
|
|||
# Microsoft Developer Studio Project File - Name="twitcurl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=twitcurl - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "twitcurl.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "twitcurl.mak" CFG="twitcurl - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "twitcurl - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "twitcurl - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "twitcurl - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "twitcurl - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "./curl" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "twitcurl - Win32 Release"
|
||||
# Name "twitcurl - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HMAC_SHA1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\oauthlib.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SHA1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\twitcurl.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlencode.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HMAC_SHA1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\oauthlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SHA1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\twitcurl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlencode.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
# Microsoft Developer Studio Project File - Name="twitcurl" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Static Library" 0x0104
|
||||
|
||||
CFG=twitcurl - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "twitcurl.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "twitcurl.mak" CFG="twitcurl - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "twitcurl - Win32 Release" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE "twitcurl - Win32 Debug" (based on "Win32 (x86) Static Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "twitcurl - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ELSEIF "$(CFG)" == "twitcurl - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "./curl" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LIB32=link.exe -lib
|
||||
# ADD BASE LIB32 /nologo
|
||||
# ADD LIB32 /nologo
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "twitcurl - Win32 Release"
|
||||
# Name "twitcurl - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HMAC_SHA1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\oauthlib.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SHA1.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\twitcurl.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlencode.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\base64.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\HMAC_SHA1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\oauthlib.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\SHA1.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\twitcurl.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\urlencode.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
|
|
|
@ -1,29 +1,29 @@
|
|||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "twitcurl"=.\twitcurl.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "twitcurl"=.\twitcurl.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
|
|
@ -1,190 +1,190 @@
|
|||
#ifndef _TWITCURL_H_
|
||||
#define _TWITCURL_H_
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "oauthlib.h"
|
||||
#include "curl/curl.h"
|
||||
|
||||
/* Few common types used by twitCurl */
|
||||
namespace twitCurlTypes
|
||||
{
|
||||
typedef enum _eTwitCurlApiFormatType
|
||||
{
|
||||
eTwitCurlApiFormatJson = 0,
|
||||
eTwitCurlApiFormatXml,
|
||||
eTwitCurlApiFormatMax
|
||||
} eTwitCurlApiFormatType;
|
||||
|
||||
typedef enum _eTwitCurlProtocolType
|
||||
{
|
||||
eTwitCurlProtocolHttps = 0,
|
||||
eTwitCurlProtocolHttp,
|
||||
eTwitCurlProtocolMax
|
||||
} eTwitCurlProtocolType;
|
||||
};
|
||||
|
||||
/* twitCurl class */
|
||||
class twitCurl
|
||||
{
|
||||
public:
|
||||
twitCurl();
|
||||
~twitCurl();
|
||||
|
||||
/* Twitter OAuth authorization methods */
|
||||
oAuth& getOAuth();
|
||||
bool oAuthRequestToken( std::string& authorizeUrl /* out */ );
|
||||
bool oAuthAccessToken();
|
||||
bool oAuthHandlePIN( const std::string& authorizeUrl /* in */ );
|
||||
|
||||
/* Twitter login APIs, set once and forget */
|
||||
std::string& getTwitterUsername();
|
||||
std::string& getTwitterPassword();
|
||||
void setTwitterUsername( std::string& userName /* in */ );
|
||||
void setTwitterPassword( std::string& passWord /* in */ );
|
||||
|
||||
/* Twitter search APIs */
|
||||
bool search( std::string& searchQuery /* in */, std::string resultCount = "" /* in */ );
|
||||
|
||||
/* Twitter status APIs */
|
||||
bool statusUpdate( std::string& newStatus /* in */, std::string inReplyToStatusId = "" /* in */ );
|
||||
bool statusShowById( std::string& statusId /* in */ );
|
||||
bool statusDestroyById( std::string& statusId /* in */ );
|
||||
bool retweetById( std::string& statusId /* in */ );
|
||||
|
||||
/* Twitter timeline APIs */
|
||||
bool timelineHomeGet( std::string sinceId = "" /* in */ );
|
||||
bool timelinePublicGet();
|
||||
bool timelineFriendsGet();
|
||||
bool timelineUserGet( bool trimUser /* in */, bool includeRetweets /* in */,
|
||||
unsigned int tweetCount /* in */,
|
||||
std::string userInfo = "" /* in */,
|
||||
bool isUserId = false /* in */ );
|
||||
bool featuredUsersGet();
|
||||
bool mentionsGet( std::string sinceId = "" /* in */ );
|
||||
|
||||
/* Twitter user APIs */
|
||||
bool userLookup( std::vector<std::string> &userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool userGet( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendsGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
|
||||
bool followersGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter direct message APIs */
|
||||
bool directMessageGet( std::string sinceId = "" /* in */ );
|
||||
bool directMessageSend( std::string& userInfo /* in */, std::string& dMsg /* in */, bool isUserId = false /* in */ );
|
||||
bool directMessageGetSent();
|
||||
bool directMessageDestroyById( std::string& dMsgId /* in */ );
|
||||
|
||||
/* Twitter friendships APIs */
|
||||
bool friendshipCreate( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendshipDestroy( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendshipShow( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter social graphs APIs */
|
||||
bool friendsIdsGet( std::string& nextCursor /* in */,
|
||||
std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool followersIdsGet( std::string& nextCursor /* in */,
|
||||
std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter account APIs */
|
||||
bool accountRateLimitGet();
|
||||
bool accountVerifyCredGet();
|
||||
|
||||
/* Twitter favorites APIs */
|
||||
bool favoriteGet();
|
||||
bool favoriteCreate( std::string& statusId /* in */ );
|
||||
bool favoriteDestroy( std::string& statusId /* in */ );
|
||||
|
||||
/* Twitter block APIs */
|
||||
bool blockCreate( std::string& userInfo /* in */ );
|
||||
bool blockDestroy( std::string& userInfo /* in */ );
|
||||
bool blockListGet( std::string& nextCursor /* in */,
|
||||
bool includeEntities /* in */, bool skipStatus /* in */ );
|
||||
bool blockIdsGet( std::string& nextCursor /* in */, bool stringifyIds /* in */ );
|
||||
|
||||
/* Twitter search APIs */
|
||||
bool savedSearchGet();
|
||||
bool savedSearchCreate( std::string& query /* in */ );
|
||||
bool savedSearchShow( std::string& searchId /* in */ );
|
||||
bool savedSearchDestroy( std::string& searchId /* in */ );
|
||||
|
||||
/* Twitter trends APIs (JSON) */
|
||||
bool trendsGet();
|
||||
bool trendsDailyGet();
|
||||
bool trendsWeeklyGet();
|
||||
bool trendsCurrentGet();
|
||||
bool trendsAvailableGet();
|
||||
|
||||
/* cURL APIs */
|
||||
bool isCurlInit();
|
||||
void getLastWebResponse( std::string& outWebResp /* out */ );
|
||||
void getLastCurlError( std::string& outErrResp /* out */);
|
||||
|
||||
/* Internal cURL related methods */
|
||||
int saveLastWebResponse( char*& data, size_t size );
|
||||
|
||||
/* cURL proxy APIs */
|
||||
std::string& getProxyServerIp();
|
||||
std::string& getProxyServerPort();
|
||||
std::string& getProxyUserName();
|
||||
std::string& getProxyPassword();
|
||||
void setProxyServerIp( std::string& proxyServerIp /* in */ );
|
||||
void setProxyServerPort( std::string& proxyServerPort /* in */ );
|
||||
void setProxyUserName( std::string& proxyUserName /* in */ );
|
||||
void setProxyPassword( std::string& proxyPassword /* in */ );
|
||||
|
||||
/* Clones this object */
|
||||
twitCurl* clone();
|
||||
|
||||
private:
|
||||
/* cURL data */
|
||||
CURL* m_curlHandle;
|
||||
char* m_errorBuffer;
|
||||
std::string m_callbackData;
|
||||
|
||||
/* cURL flags */
|
||||
bool m_curlProxyParamsSet;
|
||||
bool m_curlLoginParamsSet;
|
||||
bool m_curlCallbackParamsSet;
|
||||
|
||||
/* cURL proxy data */
|
||||
std::string m_proxyServerIp;
|
||||
std::string m_proxyServerPort;
|
||||
std::string m_proxyUserName;
|
||||
std::string m_proxyPassword;
|
||||
|
||||
/* Twitter data */
|
||||
std::string m_twitterUsername;
|
||||
std::string m_twitterPassword;
|
||||
|
||||
/* Twitter API type */
|
||||
twitCurlTypes::eTwitCurlApiFormatType m_eApiFormatType;
|
||||
twitCurlTypes::eTwitCurlProtocolType m_eProtocolType;
|
||||
|
||||
/* OAuth data */
|
||||
oAuth m_oAuth;
|
||||
|
||||
/* Private methods */
|
||||
void clearCurlCallbackBuffers();
|
||||
void prepareCurlProxy();
|
||||
void prepareCurlCallback();
|
||||
void prepareCurlUserPass();
|
||||
void prepareStandardParams();
|
||||
bool performGet( const std::string& getUrl );
|
||||
bool performGetInternal( const std::string& getUrl,
|
||||
const std::string& oAuthHttpHeader );
|
||||
bool performDelete( const std::string& deleteUrl );
|
||||
bool performPost( const std::string& postUrl, std::string dataStr = "" );
|
||||
|
||||
/* Internal cURL related methods */
|
||||
static int curlCallback( char* data, size_t size, size_t nmemb, twitCurl* pTwitCurlObj );
|
||||
};
|
||||
|
||||
|
||||
/* Private functions */
|
||||
void utilMakeCurlParams( std::string& outStr, std::string& inParam1, std::string& inParam2 );
|
||||
void utilMakeUrlForUser( std::string& outUrl, const std::string& baseUrl, std::string& userInfo, bool isUserId );
|
||||
|
||||
#endif // _TWITCURL_H_
|
||||
#ifndef _TWITCURL_H_
|
||||
#define _TWITCURL_H_
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
#include "oauthlib.h"
|
||||
#include "curl/curl.h"
|
||||
|
||||
/* Few common types used by twitCurl */
|
||||
namespace twitCurlTypes
|
||||
{
|
||||
typedef enum _eTwitCurlApiFormatType
|
||||
{
|
||||
eTwitCurlApiFormatJson = 0,
|
||||
eTwitCurlApiFormatXml,
|
||||
eTwitCurlApiFormatMax
|
||||
} eTwitCurlApiFormatType;
|
||||
|
||||
typedef enum _eTwitCurlProtocolType
|
||||
{
|
||||
eTwitCurlProtocolHttps = 0,
|
||||
eTwitCurlProtocolHttp,
|
||||
eTwitCurlProtocolMax
|
||||
} eTwitCurlProtocolType;
|
||||
};
|
||||
|
||||
/* twitCurl class */
|
||||
class twitCurl
|
||||
{
|
||||
public:
|
||||
twitCurl();
|
||||
~twitCurl();
|
||||
|
||||
/* Twitter OAuth authorization methods */
|
||||
oAuth& getOAuth();
|
||||
bool oAuthRequestToken( std::string& authorizeUrl /* out */ );
|
||||
bool oAuthAccessToken();
|
||||
bool oAuthHandlePIN( const std::string& authorizeUrl /* in */ );
|
||||
|
||||
/* Twitter login APIs, set once and forget */
|
||||
std::string& getTwitterUsername();
|
||||
std::string& getTwitterPassword();
|
||||
void setTwitterUsername( std::string& userName /* in */ );
|
||||
void setTwitterPassword( std::string& passWord /* in */ );
|
||||
|
||||
/* Twitter search APIs */
|
||||
bool search( std::string& searchQuery /* in */, std::string resultCount = "" /* in */ );
|
||||
|
||||
/* Twitter status APIs */
|
||||
bool statusUpdate( std::string& newStatus /* in */, std::string inReplyToStatusId = "" /* in */ );
|
||||
bool statusShowById( std::string& statusId /* in */ );
|
||||
bool statusDestroyById( std::string& statusId /* in */ );
|
||||
bool retweetById( std::string& statusId /* in */ );
|
||||
|
||||
/* Twitter timeline APIs */
|
||||
bool timelineHomeGet( std::string sinceId = "" /* in */ );
|
||||
bool timelinePublicGet();
|
||||
bool timelineFriendsGet();
|
||||
bool timelineUserGet( bool trimUser /* in */, bool includeRetweets /* in */,
|
||||
unsigned int tweetCount /* in */,
|
||||
std::string userInfo = "" /* in */,
|
||||
bool isUserId = false /* in */ );
|
||||
bool featuredUsersGet();
|
||||
bool mentionsGet( std::string sinceId = "" /* in */ );
|
||||
|
||||
/* Twitter user APIs */
|
||||
bool userLookup( std::vector<std::string> &userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool userGet( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendsGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
|
||||
bool followersGet( std::string userInfo = "" /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter direct message APIs */
|
||||
bool directMessageGet( std::string sinceId = "" /* in */ );
|
||||
bool directMessageSend( std::string& userInfo /* in */, std::string& dMsg /* in */, bool isUserId = false /* in */ );
|
||||
bool directMessageGetSent();
|
||||
bool directMessageDestroyById( std::string& dMsgId /* in */ );
|
||||
|
||||
/* Twitter friendships APIs */
|
||||
bool friendshipCreate( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendshipDestroy( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool friendshipShow( std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter social graphs APIs */
|
||||
bool friendsIdsGet( std::string& nextCursor /* in */,
|
||||
std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
bool followersIdsGet( std::string& nextCursor /* in */,
|
||||
std::string& userInfo /* in */, bool isUserId = false /* in */ );
|
||||
|
||||
/* Twitter account APIs */
|
||||
bool accountRateLimitGet();
|
||||
bool accountVerifyCredGet();
|
||||
|
||||
/* Twitter favorites APIs */
|
||||
bool favoriteGet();
|
||||
bool favoriteCreate( std::string& statusId /* in */ );
|
||||
bool favoriteDestroy( std::string& statusId /* in */ );
|
||||
|
||||
/* Twitter block APIs */
|
||||
bool blockCreate( std::string& userInfo /* in */ );
|
||||
bool blockDestroy( std::string& userInfo /* in */ );
|
||||
bool blockListGet( std::string& nextCursor /* in */,
|
||||
bool includeEntities /* in */, bool skipStatus /* in */ );
|
||||
bool blockIdsGet( std::string& nextCursor /* in */, bool stringifyIds /* in */ );
|
||||
|
||||
/* Twitter search APIs */
|
||||
bool savedSearchGet();
|
||||
bool savedSearchCreate( std::string& query /* in */ );
|
||||
bool savedSearchShow( std::string& searchId /* in */ );
|
||||
bool savedSearchDestroy( std::string& searchId /* in */ );
|
||||
|
||||
/* Twitter trends APIs (JSON) */
|
||||
bool trendsGet();
|
||||
bool trendsDailyGet();
|
||||
bool trendsWeeklyGet();
|
||||
bool trendsCurrentGet();
|
||||
bool trendsAvailableGet();
|
||||
|
||||
/* cURL APIs */
|
||||
bool isCurlInit();
|
||||
void getLastWebResponse( std::string& outWebResp /* out */ );
|
||||
void getLastCurlError( std::string& outErrResp /* out */);
|
||||
|
||||
/* Internal cURL related methods */
|
||||
int saveLastWebResponse( char*& data, size_t size );
|
||||
|
||||
/* cURL proxy APIs */
|
||||
std::string& getProxyServerIp();
|
||||
std::string& getProxyServerPort();
|
||||
std::string& getProxyUserName();
|
||||
std::string& getProxyPassword();
|
||||
void setProxyServerIp( std::string& proxyServerIp /* in */ );
|
||||
void setProxyServerPort( std::string& proxyServerPort /* in */ );
|
||||
void setProxyUserName( std::string& proxyUserName /* in */ );
|
||||
void setProxyPassword( std::string& proxyPassword /* in */ );
|
||||
|
||||
/* Clones this object */
|
||||
twitCurl* clone();
|
||||
|
||||
private:
|
||||
/* cURL data */
|
||||
CURL* m_curlHandle;
|
||||
char* m_errorBuffer;
|
||||
std::string m_callbackData;
|
||||
|
||||
/* cURL flags */
|
||||
bool m_curlProxyParamsSet;
|
||||
bool m_curlLoginParamsSet;
|
||||
bool m_curlCallbackParamsSet;
|
||||
|
||||
/* cURL proxy data */
|
||||
std::string m_proxyServerIp;
|
||||
std::string m_proxyServerPort;
|
||||
std::string m_proxyUserName;
|
||||
std::string m_proxyPassword;
|
||||
|
||||
/* Twitter data */
|
||||
std::string m_twitterUsername;
|
||||
std::string m_twitterPassword;
|
||||
|
||||
/* Twitter API type */
|
||||
twitCurlTypes::eTwitCurlApiFormatType m_eApiFormatType;
|
||||
twitCurlTypes::eTwitCurlProtocolType m_eProtocolType;
|
||||
|
||||
/* OAuth data */
|
||||
oAuth m_oAuth;
|
||||
|
||||
/* Private methods */
|
||||
void clearCurlCallbackBuffers();
|
||||
void prepareCurlProxy();
|
||||
void prepareCurlCallback();
|
||||
void prepareCurlUserPass();
|
||||
void prepareStandardParams();
|
||||
bool performGet( const std::string& getUrl );
|
||||
bool performGetInternal( const std::string& getUrl,
|
||||
const std::string& oAuthHttpHeader );
|
||||
bool performDelete( const std::string& deleteUrl );
|
||||
bool performPost( const std::string& postUrl, std::string dataStr = "" );
|
||||
|
||||
/* Internal cURL related methods */
|
||||
static int curlCallback( char* data, size_t size, size_t nmemb, twitCurl* pTwitCurlObj );
|
||||
};
|
||||
|
||||
|
||||
/* Private functions */
|
||||
void utilMakeCurlParams( std::string& outStr, std::string& inParam1, std::string& inParam2 );
|
||||
void utilMakeUrlForUser( std::string& outUrl, const std::string& baseUrl, std::string& userInfo, bool isUserId );
|
||||
|
||||
#endif // _TWITCURL_H_
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: twitcurl - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/twitcurl.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"C:\Projects\twitcurl\base64.cpp"
|
||||
"C:\Projects\twitcurl\HMAC_SHA1.cpp"
|
||||
"C:\Projects\twitcurl\oauthlib.cpp"
|
||||
"C:\Projects\twitcurl\SHA1.cpp"
|
||||
"C:\Projects\twitcurl\twitcurl.cpp"
|
||||
"C:\Projects\twitcurl\urlencode.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp"
|
||||
Creating command line "link.exe -lib /nologo /out:"Release\twitcurl.lib" .\Release\base64.obj .\Release\HMAC_SHA1.obj .\Release\oauthlib.obj .\Release\SHA1.obj .\Release\twitcurl.obj .\Release\urlencode.obj "
|
||||
<h3>Output Window</h3>
|
||||
Compiling...
|
||||
base64.cpp
|
||||
HMAC_SHA1.cpp
|
||||
oauthlib.cpp
|
||||
SHA1.cpp
|
||||
twitcurl.cpp
|
||||
urlencode.cpp
|
||||
Creating library...
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
twitcurl.lib - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: twitcurl - Win32 Release--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp" with contents
|
||||
[
|
||||
/nologo /ML /W3 /GX /O2 /I "./curl" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fp"Release/twitcurl.pch" /YX /Fo"Release/" /Fd"Release/" /FD /c
|
||||
"C:\Projects\twitcurl\base64.cpp"
|
||||
"C:\Projects\twitcurl\HMAC_SHA1.cpp"
|
||||
"C:\Projects\twitcurl\oauthlib.cpp"
|
||||
"C:\Projects\twitcurl\SHA1.cpp"
|
||||
"C:\Projects\twitcurl\twitcurl.cpp"
|
||||
"C:\Projects\twitcurl\urlencode.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\Mahesh\LOCALS~1\Temp\RSP239.tmp"
|
||||
Creating command line "link.exe -lib /nologo /out:"Release\twitcurl.lib" .\Release\base64.obj .\Release\HMAC_SHA1.obj .\Release\oauthlib.obj .\Release\SHA1.obj .\Release\twitcurl.obj .\Release\urlencode.obj "
|
||||
<h3>Output Window</h3>
|
||||
Compiling...
|
||||
base64.cpp
|
||||
HMAC_SHA1.cpp
|
||||
oauthlib.cpp
|
||||
SHA1.cpp
|
||||
twitcurl.cpp
|
||||
urlencode.cpp
|
||||
Creating library...
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
twitcurl.lib - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twitcurl", "twitcurl.vcproj", "{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.Build.0 = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 10.00
|
||||
# Visual C++ Express 2008
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "twitcurl", "twitcurl.vcproj", "{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.ActiveCfg = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Debug|Win32.Build.0 = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
@ -1,347 +1,347 @@
|
|||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="twitcurl"
|
||||
ProjectGUID="{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./curl"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/twitcurl.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Debug\twitcurl.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/twitcurl.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="./include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;CURL_STATICLIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\Release/twitcurl.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
LinkLibraryDependencies="true"
|
||||
AdditionalDependencies="libcurl.lib"
|
||||
OutputFile=".\Release\twitcurl.lib"
|
||||
AdditionalLibraryDirectories="./lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/twitcurl.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="base64.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="HMAC_SHA1.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="oauthlib.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SHA1.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="twitcurl.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="urlencode.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="base64.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="HMAC_SHA1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="oauthlib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SHA1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="twitcurl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\twitcurlurls.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="urlencode.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9.00"
|
||||
Name="twitcurl"
|
||||
ProjectGUID="{00175D8C-EA44-48AE-AC59-B3B7BE04E65C}"
|
||||
TargetFrameworkVersion="0"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory=".\Debug"
|
||||
IntermediateDirectory=".\Debug"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./curl"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="1"
|
||||
PrecompiledHeaderFile=".\Debug/twitcurl.pch"
|
||||
AssemblerListingLocation=".\Debug/"
|
||||
ObjectFile=".\Debug/"
|
||||
ProgramDataBaseFileName=".\Debug/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="_DEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
OutputFile=".\Debug\twitcurl.lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Debug/twitcurl.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory=".\Release"
|
||||
IntermediateDirectory=".\Release"
|
||||
ConfigurationType="4"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC60.vsprops"
|
||||
UseOfMFC="0"
|
||||
ATLMinimizesCRunTimeLibraryUsage="false"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="1"
|
||||
AdditionalIncludeDirectories="./include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;CURL_STATICLIB"
|
||||
StringPooling="true"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
PrecompiledHeaderFile=".\Release/twitcurl.pch"
|
||||
AssemblerListingLocation=".\Release/"
|
||||
ObjectFile=".\Release/"
|
||||
ProgramDataBaseFileName=".\Release/"
|
||||
WarningLevel="3"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
PreprocessorDefinitions="NDEBUG"
|
||||
Culture="1033"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLibrarianTool"
|
||||
LinkLibraryDependencies="true"
|
||||
AdditionalDependencies="libcurl.lib"
|
||||
OutputFile=".\Release\twitcurl.lib"
|
||||
AdditionalLibraryDirectories="./lib"
|
||||
SuppressStartupBanner="true"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
SuppressStartupBanner="true"
|
||||
OutputFile=".\Release/twitcurl.bsc"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
>
|
||||
<File
|
||||
RelativePath="base64.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="HMAC_SHA1.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="oauthlib.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SHA1.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="twitcurl.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="urlencode.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories=""
|
||||
PreprocessorDefinitions=""
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl"
|
||||
>
|
||||
<File
|
||||
RelativePath="base64.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="HMAC_SHA1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="oauthlib.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="SHA1.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="twitcurl.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\twitcurlurls.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="urlencode.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
|
|
|
@ -1,156 +1,156 @@
|
|||
#ifndef _TWITCURLURLS_H_
|
||||
#define _TWITCURLURLS_H_
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
/* Default values used in twitcurl */
|
||||
namespace twitCurlDefaults
|
||||
{
|
||||
/* Constants */
|
||||
const int TWITCURL_DEFAULT_BUFFSIZE = 1024;
|
||||
const std::string TWITCURL_COLON = ":";
|
||||
const char TWITCURL_EOS = '\0';
|
||||
const unsigned int MAX_TIMELINE_TWEET_COUNT = 200;
|
||||
|
||||
/* Miscellaneous data used to build twitter URLs*/
|
||||
const std::string TWITCURL_STATUSSTRING = "status=";
|
||||
const std::string TWITCURL_TEXTSTRING = "text=";
|
||||
const std::string TWITCURL_QUERYSTRING = "query=";
|
||||
const std::string TWITCURL_SEARCHQUERYSTRING = "q=";
|
||||
const std::string TWITCURL_SCREENNAME = "screen_name=";
|
||||
const std::string TWITCURL_USERID = "user_id=";
|
||||
const std::string TWITCURL_EXTENSIONFORMATS[2] = { ".json",
|
||||
".xml"
|
||||
};
|
||||
const std::string TWITCURL_PROTOCOLS[2] = { "https://",
|
||||
"http://"
|
||||
};
|
||||
const std::string TWITCURL_TARGETSCREENNAME = "target_screen_name=";
|
||||
const std::string TWITCURL_TARGETUSERID = "target_id=";
|
||||
const std::string TWITCURL_SINCEID = "since_id=";
|
||||
const std::string TWITCURL_TRIMUSER = "trim_user=true";
|
||||
const std::string TWITCURL_INCRETWEETS = "include_rts=true";
|
||||
const std::string TWITCURL_COUNT = "count=";
|
||||
const std::string TWITCURL_NEXT_CURSOR = "cursor=";
|
||||
const std::string TWITCURL_SKIP_STATUS = "skip_status=";
|
||||
const std::string TWITCURL_INCLUDE_ENTITIES = "include_entities=";
|
||||
const std::string TWITCURL_STRINGIFY_IDS = "stringify_ids=";
|
||||
const std::string TWITCURL_INREPLYTOSTATUSID = "in_reply_to_status_id=";
|
||||
|
||||
/* URL separators */
|
||||
const std::string TWITCURL_URL_SEP_AMP = "&";
|
||||
const std::string TWITCURL_URL_SEP_QUES = "?";
|
||||
};
|
||||
|
||||
/* Default twitter URLs */
|
||||
namespace twitterDefaults
|
||||
{
|
||||
/* Base URL */
|
||||
const std::string TWITCURL_BASE_URL = "api.twitter.com/1.1/";
|
||||
|
||||
/* Search URLs */
|
||||
const std::string TWITCURL_SEARCH_URL = TWITCURL_BASE_URL + "search/tweets";
|
||||
|
||||
/* Status URLs */
|
||||
const std::string TWITCURL_STATUSUPDATE_URL = TWITCURL_BASE_URL + "statuses/update";
|
||||
const std::string TWITCURL_STATUSSHOW_URL = TWITCURL_BASE_URL + "statuses/show/";
|
||||
const std::string TWITCURL_STATUDESTROY_URL = TWITCURL_BASE_URL + "statuses/destroy/";
|
||||
const std::string TWITCURL_RETWEET_URL = TWITCURL_BASE_URL + "statuses/retweet/";
|
||||
|
||||
/* Timeline URLs */
|
||||
const std::string TWITCURL_HOME_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/home_timeline";
|
||||
const std::string TWITCURL_PUBLIC_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/public_timeline";
|
||||
const std::string TWITCURL_FEATURED_USERS_URL = TWITCURL_BASE_URL + "statuses/featured";
|
||||
const std::string TWITCURL_FRIENDS_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/friends_timeline";
|
||||
const std::string TWITCURL_MENTIONS_URL = TWITCURL_BASE_URL + "statuses/mentions";
|
||||
const std::string TWITCURL_USERTIMELINE_URL = TWITCURL_BASE_URL + "statuses/user_timeline";
|
||||
|
||||
/* Users URLs */
|
||||
const std::string TWITCURL_LOOKUPUSERS_URL = TWITCURL_BASE_URL + "users/lookup";
|
||||
const std::string TWITCURL_SHOWUSERS_URL = TWITCURL_BASE_URL + "users/show";
|
||||
const std::string TWITCURL_SHOWFRIENDS_URL = TWITCURL_BASE_URL + "statuses/friends";
|
||||
const std::string TWITCURL_SHOWFOLLOWERS_URL = TWITCURL_BASE_URL + "statuses/followers";
|
||||
|
||||
/* Direct messages URLs */
|
||||
const std::string TWITCURL_DIRECTMESSAGES_URL = TWITCURL_BASE_URL + "direct_messages";
|
||||
const std::string TWITCURL_DIRECTMESSAGENEW_URL = TWITCURL_BASE_URL + "direct_messages/new";
|
||||
const std::string TWITCURL_DIRECTMESSAGESSENT_URL = TWITCURL_BASE_URL + "direct_messages/sent";
|
||||
const std::string TWITCURL_DIRECTMESSAGEDESTROY_URL = TWITCURL_BASE_URL + "direct_messages/destroy/";
|
||||
|
||||
/* Friendships URLs */
|
||||
const std::string TWITCURL_FRIENDSHIPSCREATE_URL = TWITCURL_BASE_URL + "friendships/create";
|
||||
const std::string TWITCURL_FRIENDSHIPSDESTROY_URL = TWITCURL_BASE_URL + "friendships/destroy";
|
||||
const std::string TWITCURL_FRIENDSHIPSSHOW_URL = TWITCURL_BASE_URL + "friendships/show";
|
||||
|
||||
/* Social graphs URLs */
|
||||
const std::string TWITCURL_FRIENDSIDS_URL = TWITCURL_BASE_URL + "friends/ids";
|
||||
const std::string TWITCURL_FOLLOWERSIDS_URL = TWITCURL_BASE_URL + "followers/ids";
|
||||
|
||||
/* Account URLs */
|
||||
const std::string TWITCURL_ACCOUNTRATELIMIT_URL = TWITCURL_BASE_URL + "account/rate_limit_status";
|
||||
const std::string TWITCURL_ACCOUNTVERIFYCRED_URL = TWITCURL_BASE_URL + "account/verify_credentials";
|
||||
|
||||
/* Favorites URLs */
|
||||
const std::string TWITCURL_FAVORITESGET_URL = TWITCURL_BASE_URL + "favorites";
|
||||
const std::string TWITCURL_FAVORITECREATE_URL = TWITCURL_BASE_URL + "favorites/create/";
|
||||
const std::string TWITCURL_FAVORITEDESTROY_URL = TWITCURL_BASE_URL + "favorites/destroy/";
|
||||
|
||||
/* Block URLs */
|
||||
const std::string TWITCURL_BLOCKSCREATE_URL = TWITCURL_BASE_URL + "blocks/create/";
|
||||
const std::string TWITCURL_BLOCKSDESTROY_URL = TWITCURL_BASE_URL + "blocks/destroy/";
|
||||
const std::string TWITCURL_BLOCKSLIST_URL = TWITCURL_BASE_URL + "blocks/list";
|
||||
const std::string TWITCURL_BLOCKSIDS_URL = TWITCURL_BASE_URL + "blocks/ids";
|
||||
|
||||
/* Saved Search URLs */
|
||||
const std::string TWITCURL_SAVEDSEARCHGET_URL = TWITCURL_BASE_URL + "saved_searches";
|
||||
const std::string TWITCURL_SAVEDSEARCHSHOW_URL = TWITCURL_BASE_URL + "saved_searches/show/";
|
||||
const std::string TWITCURL_SAVEDSEARCHCREATE_URL = TWITCURL_BASE_URL + "saved_searches/create";
|
||||
const std::string TWITCURL_SAVEDSEARCHDESTROY_URL = TWITCURL_BASE_URL + "saved_searches/destroy/";
|
||||
|
||||
/* Trends URLs */
|
||||
const std::string TWITCURL_TRENDS_URL = TWITCURL_BASE_URL + "trends";
|
||||
const std::string TWITCURL_TRENDSDAILY_URL = TWITCURL_BASE_URL + "trends/daily";
|
||||
const std::string TWITCURL_TRENDSCURRENT_URL = TWITCURL_BASE_URL + "trends/current";
|
||||
const std::string TWITCURL_TRENDSWEEKLY_URL = TWITCURL_BASE_URL + "trends/weekly";
|
||||
const std::string TWITCURL_TRENDSAVAILABLE_URL = TWITCURL_BASE_URL + "trends/available";
|
||||
|
||||
};
|
||||
|
||||
namespace oAuthLibDefaults
|
||||
{
|
||||
/* Constants */
|
||||
const int OAUTHLIB_BUFFSIZE = 1024;
|
||||
const int OAUTHLIB_BUFFSIZE_LARGE = 1024;
|
||||
const std::string OAUTHLIB_CONSUMERKEY_KEY = "oauth_consumer_key";
|
||||
const std::string OAUTHLIB_CALLBACK_KEY = "oauth_callback";
|
||||
const std::string OAUTHLIB_VERSION_KEY = "oauth_version";
|
||||
const std::string OAUTHLIB_SIGNATUREMETHOD_KEY = "oauth_signature_method";
|
||||
const std::string OAUTHLIB_SIGNATURE_KEY = "oauth_signature";
|
||||
const std::string OAUTHLIB_TIMESTAMP_KEY = "oauth_timestamp";
|
||||
const std::string OAUTHLIB_NONCE_KEY = "oauth_nonce";
|
||||
const std::string OAUTHLIB_TOKEN_KEY = "oauth_token";
|
||||
const std::string OAUTHLIB_TOKENSECRET_KEY = "oauth_token_secret";
|
||||
const std::string OAUTHLIB_VERIFIER_KEY = "oauth_verifier";
|
||||
const std::string OAUTHLIB_SCREENNAME_KEY = "screen_name";
|
||||
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_KEY = "authenticity_token";
|
||||
const std::string OAUTHLIB_SESSIONUSERNAME_KEY = "session[username_or_email]";
|
||||
const std::string OAUTHLIB_SESSIONPASSWORD_KEY = "session[password]";
|
||||
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY = "authenticity_token\" type=\"hidden\" value=\"";
|
||||
const std::string OAUTHLIB_TOKEN_TWITTER_RESP_KEY = "oauth_token\" type=\"hidden\" value=\"";
|
||||
const std::string OAUTHLIB_PIN_TWITTER_RESP_KEY = "code-desc\"><code>";
|
||||
const std::string OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP = "\" />";
|
||||
const std::string OAUTHLIB_PIN_END_TAG_TWITTER_RESP = "</code>";
|
||||
|
||||
const std::string OAUTHLIB_AUTHHEADER_STRING = "Authorization: OAuth ";
|
||||
};
|
||||
|
||||
namespace oAuthTwitterApiUrls
|
||||
{
|
||||
/* Twitter OAuth API URLs */
|
||||
const std::string OAUTHLIB_TWITTER_REQUEST_TOKEN_URL = "api.twitter.com/oauth/request_token";
|
||||
const std::string OAUTHLIB_TWITTER_AUTHORIZE_URL = "api.twitter.com/oauth/authorize?oauth_token=";
|
||||
const std::string OAUTHLIB_TWITTER_ACCESS_TOKEN_URL = "api.twitter.com/oauth/access_token";
|
||||
};
|
||||
|
||||
#endif // _TWITCURLURLS_H_
|
||||
#ifndef _TWITCURLURLS_H_
|
||||
#define _TWITCURLURLS_H_
|
||||
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
|
||||
/* Default values used in twitcurl */
|
||||
namespace twitCurlDefaults
|
||||
{
|
||||
/* Constants */
|
||||
const int TWITCURL_DEFAULT_BUFFSIZE = 1024;
|
||||
const std::string TWITCURL_COLON = ":";
|
||||
const char TWITCURL_EOS = '\0';
|
||||
const unsigned int MAX_TIMELINE_TWEET_COUNT = 200;
|
||||
|
||||
/* Miscellaneous data used to build twitter URLs*/
|
||||
const std::string TWITCURL_STATUSSTRING = "status=";
|
||||
const std::string TWITCURL_TEXTSTRING = "text=";
|
||||
const std::string TWITCURL_QUERYSTRING = "query=";
|
||||
const std::string TWITCURL_SEARCHQUERYSTRING = "q=";
|
||||
const std::string TWITCURL_SCREENNAME = "screen_name=";
|
||||
const std::string TWITCURL_USERID = "user_id=";
|
||||
const std::string TWITCURL_EXTENSIONFORMATS[2] = { ".json",
|
||||
".xml"
|
||||
};
|
||||
const std::string TWITCURL_PROTOCOLS[2] = { "https://",
|
||||
"http://"
|
||||
};
|
||||
const std::string TWITCURL_TARGETSCREENNAME = "target_screen_name=";
|
||||
const std::string TWITCURL_TARGETUSERID = "target_id=";
|
||||
const std::string TWITCURL_SINCEID = "since_id=";
|
||||
const std::string TWITCURL_TRIMUSER = "trim_user=true";
|
||||
const std::string TWITCURL_INCRETWEETS = "include_rts=true";
|
||||
const std::string TWITCURL_COUNT = "count=";
|
||||
const std::string TWITCURL_NEXT_CURSOR = "cursor=";
|
||||
const std::string TWITCURL_SKIP_STATUS = "skip_status=";
|
||||
const std::string TWITCURL_INCLUDE_ENTITIES = "include_entities=";
|
||||
const std::string TWITCURL_STRINGIFY_IDS = "stringify_ids=";
|
||||
const std::string TWITCURL_INREPLYTOSTATUSID = "in_reply_to_status_id=";
|
||||
|
||||
/* URL separators */
|
||||
const std::string TWITCURL_URL_SEP_AMP = "&";
|
||||
const std::string TWITCURL_URL_SEP_QUES = "?";
|
||||
};
|
||||
|
||||
/* Default twitter URLs */
|
||||
namespace twitterDefaults
|
||||
{
|
||||
/* Base URL */
|
||||
const std::string TWITCURL_BASE_URL = "api.twitter.com/1.1/";
|
||||
|
||||
/* Search URLs */
|
||||
const std::string TWITCURL_SEARCH_URL = TWITCURL_BASE_URL + "search/tweets";
|
||||
|
||||
/* Status URLs */
|
||||
const std::string TWITCURL_STATUSUPDATE_URL = TWITCURL_BASE_URL + "statuses/update";
|
||||
const std::string TWITCURL_STATUSSHOW_URL = TWITCURL_BASE_URL + "statuses/show/";
|
||||
const std::string TWITCURL_STATUDESTROY_URL = TWITCURL_BASE_URL + "statuses/destroy/";
|
||||
const std::string TWITCURL_RETWEET_URL = TWITCURL_BASE_URL + "statuses/retweet/";
|
||||
|
||||
/* Timeline URLs */
|
||||
const std::string TWITCURL_HOME_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/home_timeline";
|
||||
const std::string TWITCURL_PUBLIC_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/public_timeline";
|
||||
const std::string TWITCURL_FEATURED_USERS_URL = TWITCURL_BASE_URL + "statuses/featured";
|
||||
const std::string TWITCURL_FRIENDS_TIMELINE_URL = TWITCURL_BASE_URL + "statuses/friends_timeline";
|
||||
const std::string TWITCURL_MENTIONS_URL = TWITCURL_BASE_URL + "statuses/mentions";
|
||||
const std::string TWITCURL_USERTIMELINE_URL = TWITCURL_BASE_URL + "statuses/user_timeline";
|
||||
|
||||
/* Users URLs */
|
||||
const std::string TWITCURL_LOOKUPUSERS_URL = TWITCURL_BASE_URL + "users/lookup";
|
||||
const std::string TWITCURL_SHOWUSERS_URL = TWITCURL_BASE_URL + "users/show";
|
||||
const std::string TWITCURL_SHOWFRIENDS_URL = TWITCURL_BASE_URL + "statuses/friends";
|
||||
const std::string TWITCURL_SHOWFOLLOWERS_URL = TWITCURL_BASE_URL + "statuses/followers";
|
||||
|
||||
/* Direct messages URLs */
|
||||
const std::string TWITCURL_DIRECTMESSAGES_URL = TWITCURL_BASE_URL + "direct_messages";
|
||||
const std::string TWITCURL_DIRECTMESSAGENEW_URL = TWITCURL_BASE_URL + "direct_messages/new";
|
||||
const std::string TWITCURL_DIRECTMESSAGESSENT_URL = TWITCURL_BASE_URL + "direct_messages/sent";
|
||||
const std::string TWITCURL_DIRECTMESSAGEDESTROY_URL = TWITCURL_BASE_URL + "direct_messages/destroy/";
|
||||
|
||||
/* Friendships URLs */
|
||||
const std::string TWITCURL_FRIENDSHIPSCREATE_URL = TWITCURL_BASE_URL + "friendships/create";
|
||||
const std::string TWITCURL_FRIENDSHIPSDESTROY_URL = TWITCURL_BASE_URL + "friendships/destroy";
|
||||
const std::string TWITCURL_FRIENDSHIPSSHOW_URL = TWITCURL_BASE_URL + "friendships/show";
|
||||
|
||||
/* Social graphs URLs */
|
||||
const std::string TWITCURL_FRIENDSIDS_URL = TWITCURL_BASE_URL + "friends/ids";
|
||||
const std::string TWITCURL_FOLLOWERSIDS_URL = TWITCURL_BASE_URL + "followers/ids";
|
||||
|
||||
/* Account URLs */
|
||||
const std::string TWITCURL_ACCOUNTRATELIMIT_URL = TWITCURL_BASE_URL + "account/rate_limit_status";
|
||||
const std::string TWITCURL_ACCOUNTVERIFYCRED_URL = TWITCURL_BASE_URL + "account/verify_credentials";
|
||||
|
||||
/* Favorites URLs */
|
||||
const std::string TWITCURL_FAVORITESGET_URL = TWITCURL_BASE_URL + "favorites";
|
||||
const std::string TWITCURL_FAVORITECREATE_URL = TWITCURL_BASE_URL + "favorites/create/";
|
||||
const std::string TWITCURL_FAVORITEDESTROY_URL = TWITCURL_BASE_URL + "favorites/destroy/";
|
||||
|
||||
/* Block URLs */
|
||||
const std::string TWITCURL_BLOCKSCREATE_URL = TWITCURL_BASE_URL + "blocks/create/";
|
||||
const std::string TWITCURL_BLOCKSDESTROY_URL = TWITCURL_BASE_URL + "blocks/destroy/";
|
||||
const std::string TWITCURL_BLOCKSLIST_URL = TWITCURL_BASE_URL + "blocks/list";
|
||||
const std::string TWITCURL_BLOCKSIDS_URL = TWITCURL_BASE_URL + "blocks/ids";
|
||||
|
||||
/* Saved Search URLs */
|
||||
const std::string TWITCURL_SAVEDSEARCHGET_URL = TWITCURL_BASE_URL + "saved_searches";
|
||||
const std::string TWITCURL_SAVEDSEARCHSHOW_URL = TWITCURL_BASE_URL + "saved_searches/show/";
|
||||
const std::string TWITCURL_SAVEDSEARCHCREATE_URL = TWITCURL_BASE_URL + "saved_searches/create";
|
||||
const std::string TWITCURL_SAVEDSEARCHDESTROY_URL = TWITCURL_BASE_URL + "saved_searches/destroy/";
|
||||
|
||||
/* Trends URLs */
|
||||
const std::string TWITCURL_TRENDS_URL = TWITCURL_BASE_URL + "trends";
|
||||
const std::string TWITCURL_TRENDSDAILY_URL = TWITCURL_BASE_URL + "trends/daily";
|
||||
const std::string TWITCURL_TRENDSCURRENT_URL = TWITCURL_BASE_URL + "trends/current";
|
||||
const std::string TWITCURL_TRENDSWEEKLY_URL = TWITCURL_BASE_URL + "trends/weekly";
|
||||
const std::string TWITCURL_TRENDSAVAILABLE_URL = TWITCURL_BASE_URL + "trends/available";
|
||||
|
||||
};
|
||||
|
||||
namespace oAuthLibDefaults
|
||||
{
|
||||
/* Constants */
|
||||
const int OAUTHLIB_BUFFSIZE = 1024;
|
||||
const int OAUTHLIB_BUFFSIZE_LARGE = 1024;
|
||||
const std::string OAUTHLIB_CONSUMERKEY_KEY = "oauth_consumer_key";
|
||||
const std::string OAUTHLIB_CALLBACK_KEY = "oauth_callback";
|
||||
const std::string OAUTHLIB_VERSION_KEY = "oauth_version";
|
||||
const std::string OAUTHLIB_SIGNATUREMETHOD_KEY = "oauth_signature_method";
|
||||
const std::string OAUTHLIB_SIGNATURE_KEY = "oauth_signature";
|
||||
const std::string OAUTHLIB_TIMESTAMP_KEY = "oauth_timestamp";
|
||||
const std::string OAUTHLIB_NONCE_KEY = "oauth_nonce";
|
||||
const std::string OAUTHLIB_TOKEN_KEY = "oauth_token";
|
||||
const std::string OAUTHLIB_TOKENSECRET_KEY = "oauth_token_secret";
|
||||
const std::string OAUTHLIB_VERIFIER_KEY = "oauth_verifier";
|
||||
const std::string OAUTHLIB_SCREENNAME_KEY = "screen_name";
|
||||
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_KEY = "authenticity_token";
|
||||
const std::string OAUTHLIB_SESSIONUSERNAME_KEY = "session[username_or_email]";
|
||||
const std::string OAUTHLIB_SESSIONPASSWORD_KEY = "session[password]";
|
||||
const std::string OAUTHLIB_AUTHENTICITY_TOKEN_TWITTER_RESP_KEY = "authenticity_token\" type=\"hidden\" value=\"";
|
||||
const std::string OAUTHLIB_TOKEN_TWITTER_RESP_KEY = "oauth_token\" type=\"hidden\" value=\"";
|
||||
const std::string OAUTHLIB_PIN_TWITTER_RESP_KEY = "code-desc\"><code>";
|
||||
const std::string OAUTHLIB_TOKEN_END_TAG_TWITTER_RESP = "\" />";
|
||||
const std::string OAUTHLIB_PIN_END_TAG_TWITTER_RESP = "</code>";
|
||||
|
||||
const std::string OAUTHLIB_AUTHHEADER_STRING = "Authorization: OAuth ";
|
||||
};
|
||||
|
||||
namespace oAuthTwitterApiUrls
|
||||
{
|
||||
/* Twitter OAuth API URLs */
|
||||
const std::string OAUTHLIB_TWITTER_REQUEST_TOKEN_URL = "api.twitter.com/oauth/request_token";
|
||||
const std::string OAUTHLIB_TWITTER_AUTHORIZE_URL = "api.twitter.com/oauth/authorize?oauth_token=";
|
||||
const std::string OAUTHLIB_TWITTER_ACCESS_TOKEN_URL = "api.twitter.com/oauth/access_token";
|
||||
};
|
||||
|
||||
#endif // _TWITCURLURLS_H_
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
#include "urlencode.h"
|
||||
|
||||
std::string char2hex( char dec )
|
||||
{
|
||||
char dig1 = (dec&0xF0)>>4;
|
||||
char dig2 = (dec&0x0F);
|
||||
if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48 in ascii
|
||||
if (10<= dig1 && dig1<=15) dig1+=65-10; //A,65 in ascii
|
||||
if ( 0<= dig2 && dig2<= 9) dig2+=48;
|
||||
if (10<= dig2 && dig2<=15) dig2+=65-10;
|
||||
|
||||
std::string r;
|
||||
r.append( &dig1, 1);
|
||||
r.append( &dig2, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string urlencode( const std::string &c )
|
||||
{
|
||||
|
||||
std::string escaped;
|
||||
int max = c.length();
|
||||
for(int i=0; i<max; i++)
|
||||
{
|
||||
if ( (48 <= c[i] && c[i] <= 57) ||//0-9
|
||||
(65 <= c[i] && c[i] <= 90) ||//ABC...XYZ
|
||||
(97 <= c[i] && c[i] <= 122) || //abc...xyz
|
||||
(c[i]=='~' || c[i]=='-' || c[i]=='_' || c[i]=='.')
|
||||
)
|
||||
{
|
||||
escaped.append( &c[i], 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
escaped.append("%");
|
||||
escaped.append( char2hex(c[i]) );//converts char 255 to string "FF"
|
||||
}
|
||||
}
|
||||
return escaped;
|
||||
#include "urlencode.h"
|
||||
|
||||
std::string char2hex( char dec )
|
||||
{
|
||||
char dig1 = (dec&0xF0)>>4;
|
||||
char dig2 = (dec&0x0F);
|
||||
if ( 0<= dig1 && dig1<= 9) dig1+=48; //0,48 in ascii
|
||||
if (10<= dig1 && dig1<=15) dig1+=65-10; //A,65 in ascii
|
||||
if ( 0<= dig2 && dig2<= 9) dig2+=48;
|
||||
if (10<= dig2 && dig2<=15) dig2+=65-10;
|
||||
|
||||
std::string r;
|
||||
r.append( &dig1, 1);
|
||||
r.append( &dig2, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
std::string urlencode( const std::string &c )
|
||||
{
|
||||
|
||||
std::string escaped;
|
||||
int max = c.length();
|
||||
for(int i=0; i<max; i++)
|
||||
{
|
||||
if ( (48 <= c[i] && c[i] <= 57) ||//0-9
|
||||
(65 <= c[i] && c[i] <= 90) ||//ABC...XYZ
|
||||
(97 <= c[i] && c[i] <= 122) || //abc...xyz
|
||||
(c[i]=='~' || c[i]=='-' || c[i]=='_' || c[i]=='.')
|
||||
)
|
||||
{
|
||||
escaped.append( &c[i], 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
escaped.append("%");
|
||||
escaped.append( char2hex(c[i]) );//converts char 255 to string "FF"
|
||||
}
|
||||
}
|
||||
return escaped;
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
#ifndef __URLENCODE_H__
|
||||
#define __URLENCODE_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
std::string char2hex( char dec );
|
||||
std::string urlencode( const std::string &c );
|
||||
|
||||
#ifndef __URLENCODE_H__
|
||||
#define __URLENCODE_H__
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
std::string char2hex( char dec );
|
||||
std::string urlencode( const std::string &c );
|
||||
|
||||
#endif // __URLENCODE_H__
|
|
@ -1,38 +1,45 @@
|
|||
FIND_LIBRARY(SWIFTEN_LIBRARY NAMES Swiften Swiften3 HINTS ../lib)
|
||||
FIND_PATH(SWIFTEN_INCLUDE_DIR NAMES "Swiften/Swiften.h" PATH_SUFFIXES libSwiften Swiften HINTS ../include)
|
||||
|
||||
if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
find_program(SWIFTEN_CONFIG_EXECUTABLE NAMES swiften-config DOC "swiften-config executable" HINTS ../bin)
|
||||
set( SWIFTEN_CFLAGS "" )
|
||||
if (SWIFTEN_CONFIG_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${SWIFTEN_CONFIG_EXECUTABLE} --libs
|
||||
OUTPUT_VARIABLE SWIFTEN_LIB)
|
||||
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
string(REGEX REPLACE " +$" "" SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
string(REGEX REPLACE " " ";" SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
set(SWIFTEN_LIBRARY "")
|
||||
foreach(f ${SWIFTEN_LIB})
|
||||
STRING(SUBSTRING ${f} 0 2 f_out)
|
||||
STRING(COMPARE EQUAL ${f_out} "/L" IS_PATH)
|
||||
if(${IS_PATH})
|
||||
string(REGEX REPLACE "/LIBPATH:" "" f_replaced "${f}")
|
||||
message("Added link directory: ${f_replaced}")
|
||||
link_directories(${f_replaced})
|
||||
else()
|
||||
list(APPEND SWIFTEN_LIBRARY ${f})
|
||||
endif()
|
||||
endforeach(f)
|
||||
set( SWIFTEN_FOUND 1 )
|
||||
else()
|
||||
message( STATUS "Could NOT find swiften-config" )
|
||||
endif()
|
||||
|
||||
if (SWIFTEN_FOUND)
|
||||
set( SWIFTEN_INCLUDE_DIR ${SWIFTEN_INCLUDE_DIR} )
|
||||
message( STATUS "Found libSwiften: ${SWIFTEN_LIBRARY}, ${SWIFTEN_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
else( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
message( STATUS "Could NOT find libSwiften" )
|
||||
endif( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
FIND_LIBRARY(SWIFTEN_LIBRARY NAMES Swiften Swiften3 HINTS ../lib)
|
||||
FIND_PATH(SWIFTEN_INCLUDE_DIR NAMES "Swiften/Swiften.h" PATH_SUFFIXES libSwiften Swiften HINTS ../include)
|
||||
|
||||
if( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
find_program(SWIFTEN_CONFIG_EXECUTABLE NAMES swiften-config DOC "swiften-config executable" HINTS ../bin)
|
||||
set( SWIFTEN_CFLAGS "" )
|
||||
if (SWIFTEN_CONFIG_EXECUTABLE)
|
||||
execute_process(
|
||||
COMMAND ${SWIFTEN_CONFIG_EXECUTABLE} --libs
|
||||
OUTPUT_VARIABLE SWIFTEN_LIB)
|
||||
string(REGEX REPLACE "[\r\n]" " " SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
string(REGEX REPLACE " +$" "" SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
set(SWIFTEN_LIBRARY "")
|
||||
if (APPLE)
|
||||
string(REGEX MATCHALL "-framework [A-Za-z]+" APPLE_FRAMEWORKS ${SWIFTEN_LIB})
|
||||
foreach(framework ${APPLE_FRAMEWORKS})
|
||||
list(APPEND SWIFTEN_LIBRARY ${framework} )
|
||||
endforeach(framework)
|
||||
string(REGEX REPLACE "-framework [A-Za-z]+" "" SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
endif(APPLE)
|
||||
string(REGEX REPLACE " " ";" SWIFTEN_LIB ${SWIFTEN_LIB})
|
||||
foreach(f ${SWIFTEN_LIB})
|
||||
STRING(SUBSTRING ${f} 0 2 f_out)
|
||||
STRING(COMPARE EQUAL ${f_out} "/L" IS_PATH)
|
||||
if(${IS_PATH})
|
||||
string(REGEX REPLACE "/LIBPATH:" "" f_replaced "${f}")
|
||||
message("Added link directory: ${f_replaced}")
|
||||
link_directories(${f_replaced})
|
||||
else()
|
||||
list(APPEND SWIFTEN_LIBRARY ${f})
|
||||
endif()
|
||||
endforeach(f)
|
||||
set( SWIFTEN_FOUND 1 )
|
||||
else()
|
||||
message( STATUS "Could NOT find swiften-config" )
|
||||
endif()
|
||||
|
||||
if (SWIFTEN_FOUND)
|
||||
set( SWIFTEN_INCLUDE_DIR ${SWIFTEN_INCLUDE_DIR} )
|
||||
message( STATUS "Found libSwiften: ${SWIFTEN_LIBRARY}, ${SWIFTEN_INCLUDE_DIR}")
|
||||
endif()
|
||||
|
||||
else( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
message( STATUS "Could NOT find libSwiften" )
|
||||
endif( SWIFTEN_LIBRARY AND SWIFTEN_INCLUDE_DIR )
|
||||
|
|
|
@ -1 +1 @@
|
|||
ADD_SUBDIRECTORY(transport)
|
||||
ADD_SUBDIRECTORY(transport)
|
||||
|
|
|
@ -1,110 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Tobias Markmann
|
||||
* Licensed under the simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include "CombinedOutgoingFileTransferManager.h"
|
||||
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include "Swiften/Disco/EntityCapsProvider.h"
|
||||
#include <Swiften/Jingle/JingleSessionManager.h>
|
||||
#include <Swiften/Jingle/JingleSessionImpl.h>
|
||||
#include <Swiften/Jingle/JingleContentID.h>
|
||||
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/Base/IDGenerator.h>
|
||||
#include <Swiften/Elements/Presence.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
|
||||
|
||||
namespace Swift {
|
||||
|
||||
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
|
||||
idGenerator = new IDGenerator();
|
||||
}
|
||||
|
||||
CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() {
|
||||
delete idGenerator;
|
||||
}
|
||||
|
||||
boost::shared_ptr<OutgoingFileTransfer> CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) {
|
||||
// check if receipient support Jingle FT
|
||||
boost::optional<JID> fullJID = highestPriorityJIDSupportingJingle(receipient);
|
||||
if (!fullJID.is_initialized()) {
|
||||
fullJID = highestPriorityJIDSupportingSI(receipient);
|
||||
}
|
||||
else {
|
||||
JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter);
|
||||
|
||||
//jsManager->getSession(receipient, idGenerator->generateID());
|
||||
assert(jingleSession);
|
||||
jsManager->registerOutgoingSession(from, jingleSession);
|
||||
#if !HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT = boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy));
|
||||
return jingleFT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!fullJID.is_initialized()) {
|
||||
return boost::shared_ptr<OutgoingFileTransfer>();
|
||||
}
|
||||
|
||||
// otherwise try SI
|
||||
boost::shared_ptr<MyOutgoingSIFileTransfer> jingleFT = boost::shared_ptr<MyOutgoingSIFileTransfer>(new MyOutgoingSIFileTransfer(idGenerator->generateID(), from, fullJID.get(), fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription(), readBytestream, iqRouter, bytestreamServer, bytestreamRegistry));
|
||||
// else fail
|
||||
|
||||
return jingleFT;
|
||||
}
|
||||
|
||||
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingJingle(const JID& bareJID) {
|
||||
JID fullReceipientJID;
|
||||
int priority = INT_MIN;
|
||||
|
||||
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
|
||||
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
|
||||
|
||||
//iterate over them
|
||||
foreach(Presence::ref pres, presences) {
|
||||
if (pres->getPriority() > priority) {
|
||||
// look up caps from the jid
|
||||
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
|
||||
if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) &&
|
||||
info->hasFeature(DiscoInfo::JingleTransportsIBBFeature)) {
|
||||
|
||||
priority = pres->getPriority();
|
||||
fullReceipientJID = pres->getFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
|
||||
}
|
||||
|
||||
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingSI(const JID& bareJID) {
|
||||
JID fullReceipientJID;
|
||||
int priority = INT_MIN;
|
||||
|
||||
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
|
||||
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
|
||||
|
||||
//iterate over them
|
||||
foreach(Presence::ref pres, presences) {
|
||||
if (pres->getPriority() > priority) {
|
||||
// look up caps from the jid
|
||||
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
|
||||
if (info && info->hasFeature("http://jabber.org/protocol/si/profile/file-transfer")) {
|
||||
|
||||
priority = pres->getPriority();
|
||||
fullReceipientJID = pres->getFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2011 Tobias Markmann
|
||||
* Licensed under the simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#include "CombinedOutgoingFileTransferManager.h"
|
||||
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include "Swiften/Disco/EntityCapsProvider.h"
|
||||
#include <Swiften/Jingle/JingleSessionManager.h>
|
||||
#include <Swiften/Jingle/JingleSessionImpl.h>
|
||||
#include <Swiften/Jingle/JingleContentID.h>
|
||||
#include <Swiften/FileTransfer/OutgoingJingleFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/Base/IDGenerator.h>
|
||||
#include <Swiften/Elements/Presence.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
|
||||
|
||||
namespace Swift {
|
||||
|
||||
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
|
||||
idGenerator = new IDGenerator();
|
||||
}
|
||||
|
||||
CombinedOutgoingFileTransferManager::~CombinedOutgoingFileTransferManager() {
|
||||
delete idGenerator;
|
||||
}
|
||||
|
||||
boost::shared_ptr<OutgoingFileTransfer> CombinedOutgoingFileTransferManager::createOutgoingFileTransfer(const JID& from, const JID& receipient, boost::shared_ptr<ReadBytestream> readBytestream, const StreamInitiationFileInfo& fileInfo) {
|
||||
// check if receipient support Jingle FT
|
||||
boost::optional<JID> fullJID = highestPriorityJIDSupportingJingle(receipient);
|
||||
if (!fullJID.is_initialized()) {
|
||||
fullJID = highestPriorityJIDSupportingSI(receipient);
|
||||
}
|
||||
else {
|
||||
JingleSessionImpl::ref jingleSession = boost::make_shared<JingleSessionImpl>(from, receipient, idGenerator->generateID(), iqRouter);
|
||||
|
||||
//jsManager->getSession(receipient, idGenerator->generateID());
|
||||
assert(jingleSession);
|
||||
jsManager->registerOutgoingSession(from, jingleSession);
|
||||
#if !HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<OutgoingJingleFileTransfer> jingleFT = boost::shared_ptr<OutgoingJingleFileTransfer>(new OutgoingJingleFileTransfer(jingleSession, remoteFactory, localFactory, iqRouter, idGenerator, from, receipient, readBytestream, fileInfo, bytestreamRegistry, bytestreamProxy));
|
||||
return jingleFT;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!fullJID.is_initialized()) {
|
||||
return boost::shared_ptr<OutgoingFileTransfer>();
|
||||
}
|
||||
|
||||
// otherwise try SI
|
||||
boost::shared_ptr<MyOutgoingSIFileTransfer> jingleFT = boost::shared_ptr<MyOutgoingSIFileTransfer>(new MyOutgoingSIFileTransfer(idGenerator->generateID(), from, fullJID.get(), fileInfo.getName(), fileInfo.getSize(), fileInfo.getDescription(), readBytestream, iqRouter, bytestreamServer, bytestreamRegistry));
|
||||
// else fail
|
||||
|
||||
return jingleFT;
|
||||
}
|
||||
|
||||
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingJingle(const JID& bareJID) {
|
||||
JID fullReceipientJID;
|
||||
int priority = INT_MIN;
|
||||
|
||||
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
|
||||
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
|
||||
|
||||
//iterate over them
|
||||
foreach(Presence::ref pres, presences) {
|
||||
if (pres->getPriority() > priority) {
|
||||
// look up caps from the jid
|
||||
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
|
||||
if (info && info->hasFeature(DiscoInfo::JingleFeature) && info->hasFeature(DiscoInfo::JingleFTFeature) &&
|
||||
info->hasFeature(DiscoInfo::JingleTransportsIBBFeature)) {
|
||||
|
||||
priority = pres->getPriority();
|
||||
fullReceipientJID = pres->getFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
|
||||
}
|
||||
|
||||
boost::optional<JID> CombinedOutgoingFileTransferManager::highestPriorityJIDSupportingSI(const JID& bareJID) {
|
||||
JID fullReceipientJID;
|
||||
int priority = INT_MIN;
|
||||
|
||||
//getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11
|
||||
std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
|
||||
|
||||
//iterate over them
|
||||
foreach(Presence::ref pres, presences) {
|
||||
if (pres->getPriority() > priority) {
|
||||
// look up caps from the jid
|
||||
DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom());
|
||||
if (info && info->hasFeature("http://jabber.org/protocol/si/profile/file-transfer")) {
|
||||
|
||||
priority = pres->getPriority();
|
||||
fullReceipientJID = pres->getFrom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullReceipientJID.isValid() ? boost::optional<JID>(fullReceipientJID) : boost::optional<JID>();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2011 Tobias Markmann
|
||||
* Licensed under the simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
#include "transport/presenceoracle.h"
|
||||
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
|
||||
class JingleSessionManager;
|
||||
class IQRouter;
|
||||
class EntityCapsProvider;
|
||||
class RemoteJingleTransportCandidateSelectorFactory;
|
||||
class LocalJingleTransportCandidateGeneratorFactory;
|
||||
class OutgoingFileTransfer;
|
||||
class JID;
|
||||
class IDGenerator;
|
||||
class ReadBytestream;
|
||||
class StreamInitiationFileInfo;
|
||||
class SOCKS5BytestreamRegistry;
|
||||
class SOCKS5BytestreamProxy;
|
||||
class SOCKS5BytestreamServer;
|
||||
class PresenceOracle;
|
||||
|
||||
class CombinedOutgoingFileTransferManager {
|
||||
public:
|
||||
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
|
||||
~CombinedOutgoingFileTransferManager();
|
||||
|
||||
boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
|
||||
|
||||
private:
|
||||
boost::optional<JID> highestPriorityJIDSupportingJingle(const JID& bareJID);
|
||||
boost::optional<JID> highestPriorityJIDSupportingSI(const JID& bareJID);
|
||||
JingleSessionManager* jsManager;
|
||||
IQRouter* iqRouter;
|
||||
EntityCapsProvider* capsProvider;
|
||||
RemoteJingleTransportCandidateSelectorFactory* remoteFactory;
|
||||
LocalJingleTransportCandidateGeneratorFactory* localFactory;
|
||||
IDGenerator *idGenerator;
|
||||
SOCKS5BytestreamRegistry* bytestreamRegistry;
|
||||
SOCKS5BytestreamProxy* bytestreamProxy;
|
||||
Transport::PresenceOracle* presenceOracle;
|
||||
SOCKS5BytestreamServer *bytestreamServer;
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2011 Tobias Markmann
|
||||
* Licensed under the simplified BSD license.
|
||||
* See Documentation/Licenses/BSD-simplified.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
#include "transport/presenceoracle.h"
|
||||
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
|
||||
class JingleSessionManager;
|
||||
class IQRouter;
|
||||
class EntityCapsProvider;
|
||||
class RemoteJingleTransportCandidateSelectorFactory;
|
||||
class LocalJingleTransportCandidateGeneratorFactory;
|
||||
class OutgoingFileTransfer;
|
||||
class JID;
|
||||
class IDGenerator;
|
||||
class ReadBytestream;
|
||||
class StreamInitiationFileInfo;
|
||||
class SOCKS5BytestreamRegistry;
|
||||
class SOCKS5BytestreamProxy;
|
||||
class SOCKS5BytestreamServer;
|
||||
class PresenceOracle;
|
||||
|
||||
class CombinedOutgoingFileTransferManager {
|
||||
public:
|
||||
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
|
||||
~CombinedOutgoingFileTransferManager();
|
||||
|
||||
boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
|
||||
|
||||
private:
|
||||
boost::optional<JID> highestPriorityJIDSupportingJingle(const JID& bareJID);
|
||||
boost::optional<JID> highestPriorityJIDSupportingSI(const JID& bareJID);
|
||||
JingleSessionManager* jsManager;
|
||||
IQRouter* iqRouter;
|
||||
EntityCapsProvider* capsProvider;
|
||||
RemoteJingleTransportCandidateSelectorFactory* remoteFactory;
|
||||
LocalJingleTransportCandidateGeneratorFactory* localFactory;
|
||||
IDGenerator *idGenerator;
|
||||
SOCKS5BytestreamRegistry* bytestreamRegistry;
|
||||
SOCKS5BytestreamProxy* bytestreamProxy;
|
||||
Transport::PresenceOracle* presenceOracle;
|
||||
SOCKS5BytestreamServer *bytestreamServer;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,118 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <Swiften/FileTransfer/StreamInitiationRequest.h>
|
||||
#include <Swiften/FileTransfer/BytestreamsRequest.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
|
||||
#include <Swiften/FileTransfer/IBBSendSession.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
MyOutgoingSIFileTransfer::MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer), registry(registry) {
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::start() {
|
||||
StreamInitiation::ref streamInitiation(new StreamInitiation());
|
||||
streamInitiation->setID(id);
|
||||
streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size));
|
||||
streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");
|
||||
streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb");
|
||||
StreamInitiationRequest::ref request = StreamInitiationRequest::create(from, to, streamInitiation, iqRouter);
|
||||
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2));
|
||||
request->send();
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::stop() {
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::cancel() {
|
||||
// TODO
|
||||
// session->sendTerminate(JinglePayload::Reason::Cancel);
|
||||
|
||||
if (ibbSession) {
|
||||
ibbSession->stop();
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
|
||||
if (serverSession) {
|
||||
serverSession->stop();
|
||||
}
|
||||
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) {
|
||||
if (error) {
|
||||
finish(FileTransferError());
|
||||
}
|
||||
else {
|
||||
if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") {
|
||||
#if !HAVE_SWIFTEN_3
|
||||
registry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(id, from, to), bytestream);
|
||||
socksServer->addReadBytestream(id, from, to, bytestream);
|
||||
#endif
|
||||
Bytestreams::ref bytestreams(new Bytestreams());
|
||||
bytestreams->setStreamID(id);
|
||||
HostAddressPort addressPort = socksServer->getAddressPort();
|
||||
bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort()));
|
||||
BytestreamsRequest::ref request = BytestreamsRequest::create(from, to, bytestreams, iqRouter);
|
||||
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2));
|
||||
request->send();
|
||||
}
|
||||
else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") {
|
||||
ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, from, to, bytestream, iqRouter));
|
||||
ibbSession->onFinished.connect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
|
||||
ibbSession->start();
|
||||
#if !HAVE_SWIFTEN_3
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) {
|
||||
if (error) {
|
||||
finish(FileTransferError());
|
||||
return;
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
|
||||
// serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1));
|
||||
// serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1));
|
||||
serverSession->startTransfer();
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
|
||||
#endif
|
||||
//socksServer->onTransferFinished.connect();
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) {
|
||||
if (ibbSession) {
|
||||
ibbSession->onFinished.disconnect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
|
||||
ibbSession.reset();
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
socksServer->removeReadBytestream(id, from, to);
|
||||
if(error) {
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
|
||||
}
|
||||
else {
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Finished));
|
||||
}
|
||||
#endif
|
||||
onFinished(error);
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) {
|
||||
finish(error);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/FileTransfer/MyOutgoingSIFileTransfer.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <Swiften/FileTransfer/StreamInitiationRequest.h>
|
||||
#include <Swiften/FileTransfer/BytestreamsRequest.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
|
||||
#include <Swiften/FileTransfer/IBBSendSession.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
MyOutgoingSIFileTransfer::MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry) : id(id), from(from), to(to), name(name), size(size), description(description), bytestream(bytestream), iqRouter(iqRouter), socksServer(socksServer), registry(registry) {
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::start() {
|
||||
StreamInitiation::ref streamInitiation(new StreamInitiation());
|
||||
streamInitiation->setID(id);
|
||||
streamInitiation->setFileInfo(StreamInitiationFileInfo(name, description, size));
|
||||
streamInitiation->addProvidedMethod("http://jabber.org/protocol/bytestreams");
|
||||
streamInitiation->addProvidedMethod("http://jabber.org/protocol/ibb");
|
||||
StreamInitiationRequest::ref request = StreamInitiationRequest::create(from, to, streamInitiation, iqRouter);
|
||||
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse, this, _1, _2));
|
||||
request->send();
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::stop() {
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::cancel() {
|
||||
// TODO
|
||||
// session->sendTerminate(JinglePayload::Reason::Cancel);
|
||||
|
||||
if (ibbSession) {
|
||||
ibbSession->stop();
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
|
||||
if (serverSession) {
|
||||
serverSession->stop();
|
||||
}
|
||||
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
|
||||
#endif
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleStreamInitiationRequestResponse(StreamInitiation::ref response, ErrorPayload::ref error) {
|
||||
if (error) {
|
||||
finish(FileTransferError());
|
||||
}
|
||||
else {
|
||||
if (response->getRequestedMethod() == "http://jabber.org/protocol/bytestreams") {
|
||||
#if !HAVE_SWIFTEN_3
|
||||
registry->addReadBytestream(SOCKS5BytestreamRegistry::getHostname(id, from, to), bytestream);
|
||||
socksServer->addReadBytestream(id, from, to, bytestream);
|
||||
#endif
|
||||
Bytestreams::ref bytestreams(new Bytestreams());
|
||||
bytestreams->setStreamID(id);
|
||||
HostAddressPort addressPort = socksServer->getAddressPort();
|
||||
bytestreams->addStreamHost(Bytestreams::StreamHost(addressPort.getAddress().toString(), from, addressPort.getPort()));
|
||||
BytestreamsRequest::ref request = BytestreamsRequest::create(from, to, bytestreams, iqRouter);
|
||||
request->onResponse.connect(boost::bind(&MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse, this, _1, _2));
|
||||
request->send();
|
||||
}
|
||||
else if (response->getRequestedMethod() == "http://jabber.org/protocol/ibb") {
|
||||
ibbSession = boost::shared_ptr<IBBSendSession>(new IBBSendSession(id, from, to, bytestream, iqRouter));
|
||||
ibbSession->onFinished.connect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
|
||||
ibbSession->start();
|
||||
#if !HAVE_SWIFTEN_3
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref error) {
|
||||
if (error) {
|
||||
finish(FileTransferError());
|
||||
return;
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
SOCKS5BytestreamServerSession *serverSession = registry->getConnectedSession(SOCKS5BytestreamRegistry::getHostname(id, from, to));
|
||||
// serverSession->onBytesSent.connect(boost::bind(boost::ref(onProcessedBytes), _1));
|
||||
// serverSession->onFinished.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransferFinished, this, _1));
|
||||
serverSession->startTransfer();
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Transferring));
|
||||
#endif
|
||||
//socksServer->onTransferFinished.connect();
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::finish(boost::optional<FileTransferError> error) {
|
||||
if (ibbSession) {
|
||||
ibbSession->onFinished.disconnect(boost::bind(&MyOutgoingSIFileTransfer::handleIBBSessionFinished, this, _1));
|
||||
ibbSession.reset();
|
||||
}
|
||||
#if !HAVE_SWIFTEN_3
|
||||
socksServer->removeReadBytestream(id, from, to);
|
||||
if(error) {
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Canceled));
|
||||
}
|
||||
else {
|
||||
onStateChange(FileTransfer::State(FileTransfer::State::Finished));
|
||||
}
|
||||
#endif
|
||||
onFinished(error);
|
||||
}
|
||||
|
||||
void MyOutgoingSIFileTransfer::handleIBBSessionFinished(boost::optional<FileTransferError> error) {
|
||||
finish(error);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,58 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/ReadBytestream.h>
|
||||
#include <Swiften/Base/boost_bsignals.h>
|
||||
#include <Swiften/FileTransfer/FileTransferError.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include <Swiften/Elements/StreamInitiation.h>
|
||||
#include <Swiften/Elements/Bytestreams.h>
|
||||
#include <Swiften/Elements/ErrorPayload.h>
|
||||
#include <Swiften/FileTransfer/IBBSendSession.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class IQRouter;
|
||||
class SOCKS5BytestreamServer;
|
||||
class SOCKS5BytestreamRegistry;
|
||||
|
||||
class MyOutgoingSIFileTransfer : public OutgoingFileTransfer {
|
||||
public:
|
||||
MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry);
|
||||
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void cancel();
|
||||
|
||||
boost::signal<void (const boost::optional<FileTransferError>&)> onFinished;
|
||||
|
||||
private:
|
||||
void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref);
|
||||
void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref);
|
||||
void finish(boost::optional<FileTransferError> error);
|
||||
void handleIBBSessionFinished(boost::optional<FileTransferError> error);
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
JID from;
|
||||
JID to;
|
||||
std::string name;
|
||||
int size;
|
||||
std::string description;
|
||||
boost::shared_ptr<ReadBytestream> bytestream;
|
||||
IQRouter* iqRouter;
|
||||
SOCKS5BytestreamServer* socksServer;
|
||||
boost::shared_ptr<IBBSendSession> ibbSession;
|
||||
SOCKS5BytestreamRegistry *registry;
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <Swiften/FileTransfer/OutgoingFileTransfer.h>
|
||||
#include <Swiften/FileTransfer/ReadBytestream.h>
|
||||
#include <Swiften/Base/boost_bsignals.h>
|
||||
#include <Swiften/FileTransfer/FileTransferError.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include <Swiften/Elements/StreamInitiation.h>
|
||||
#include <Swiften/Elements/Bytestreams.h>
|
||||
#include <Swiften/Elements/ErrorPayload.h>
|
||||
#include <Swiften/FileTransfer/IBBSendSession.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class IQRouter;
|
||||
class SOCKS5BytestreamServer;
|
||||
class SOCKS5BytestreamRegistry;
|
||||
|
||||
class MyOutgoingSIFileTransfer : public OutgoingFileTransfer {
|
||||
public:
|
||||
MyOutgoingSIFileTransfer(const std::string& id, const JID& from, const JID& to, const std::string& name, int size, const std::string& description, boost::shared_ptr<ReadBytestream> bytestream, IQRouter* iqRouter, SOCKS5BytestreamServer* socksServer, SOCKS5BytestreamRegistry* registry);
|
||||
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
virtual void cancel();
|
||||
|
||||
boost::signal<void (const boost::optional<FileTransferError>&)> onFinished;
|
||||
|
||||
private:
|
||||
void handleStreamInitiationRequestResponse(StreamInitiation::ref, ErrorPayload::ref);
|
||||
void handleBytestreamsRequestResponse(Bytestreams::ref, ErrorPayload::ref);
|
||||
void finish(boost::optional<FileTransferError> error);
|
||||
void handleIBBSessionFinished(boost::optional<FileTransferError> error);
|
||||
|
||||
private:
|
||||
std::string id;
|
||||
JID from;
|
||||
JID to;
|
||||
std::string name;
|
||||
int size;
|
||||
std::string description;
|
||||
boost::shared_ptr<ReadBytestream> bytestream;
|
||||
IQRouter* iqRouter;
|
||||
SOCKS5BytestreamServer* socksServer;
|
||||
boost::shared_ptr<IBBSendSession> ibbSession;
|
||||
SOCKS5BytestreamRegistry *registry;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void DummyConnectionServer::stop() {
|
|||
|
||||
}
|
||||
|
||||
void DummyConnectionServer::acceptConnection(boost::shared_ptr<Connection> connection) {
|
||||
void DummyConnectionServer::acceptConnection(boost::shared_ptr<Swift::Connection> connection) {
|
||||
eventLoop->postEvent(
|
||||
boost::bind(boost::ref(onNewConnection), connection),
|
||||
shared_from_this());
|
||||
|
|
|
@ -30,7 +30,11 @@ namespace Swift {
|
|||
return ref(new DummyConnectionServer(eventLoop));
|
||||
}
|
||||
|
||||
void acceptConnection(boost::shared_ptr<Connection> connection);
|
||||
void acceptConnection(boost::shared_ptr<Swift::Connection> connection);
|
||||
|
||||
virtual boost::optional<Swift::ConnectionServer::Error> tryStart() {
|
||||
return boost::optional<Swift::ConnectionServer::Error>();
|
||||
}
|
||||
|
||||
virtual void start();
|
||||
virtual void stop();
|
||||
|
|
|
@ -9,6 +9,12 @@
|
|||
#include <Swiften/Network/DummyConnectionFactory.h>
|
||||
#include <Swiften/Network/PlatformDomainNameResolver.h>
|
||||
#include <Swiften/Network/DummyConnectionServerFactory.h>
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/Crypto/CryptoProvider.h>
|
||||
#include <Swiften/Crypto/PlatformCryptoProvider.h>
|
||||
#include <Swiften/Network/NetworkEnvironment.h>
|
||||
#include <Swiften/Network/PlatformNetworkEnvironment.h>
|
||||
#endif
|
||||
|
||||
namespace Swift {
|
||||
|
||||
|
@ -18,6 +24,8 @@ DummyNetworkFactories::DummyNetworkFactories(EventLoop* eventLoop) {
|
|||
#if HAVE_SWIFTEN_3
|
||||
idnConverter = boost::shared_ptr<IDNConverter>(PlatformIDNConverter::create());
|
||||
domainNameResolver = new PlatformDomainNameResolver(idnConverter.get(), eventLoop);
|
||||
cryptoProvider = PlatformCryptoProvider::create();
|
||||
networkEnvironment = new PlatformNetworkEnvironment();
|
||||
#else
|
||||
domainNameResolver = new PlatformDomainNameResolver(eventLoop);
|
||||
#endif
|
||||
|
|
|
@ -1,80 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
#include <Swiften/Network/NetworkFactories.h>
|
||||
#include <Swiften/Parser/PlatformXMLParserFactory.h>
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/IDN/IDNConverter.h>
|
||||
#include <Swiften/IDN/PlatformIDNConverter.h>
|
||||
#endif
|
||||
|
||||
namespace Swift {
|
||||
class EventLoop;
|
||||
|
||||
class DummyNetworkFactories : public NetworkFactories {
|
||||
public:
|
||||
DummyNetworkFactories(EventLoop *eventLoop);
|
||||
~DummyNetworkFactories();
|
||||
|
||||
virtual TimerFactory* getTimerFactory() const {
|
||||
return timerFactory;
|
||||
}
|
||||
|
||||
virtual ConnectionFactory* getConnectionFactory() const {
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
#if HAVE_SWIFTEN_3
|
||||
IDNConverter* getIDNConverter() const {
|
||||
return idnConverter.get();
|
||||
}
|
||||
#endif
|
||||
|
||||
DomainNameResolver* getDomainNameResolver() const {
|
||||
return domainNameResolver;
|
||||
}
|
||||
|
||||
ConnectionServerFactory* getConnectionServerFactory() const {
|
||||
return connectionServerFactory;
|
||||
}
|
||||
|
||||
virtual Swift::NATTraverser* getNATTraverser() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Swift::XMLParserFactory* getXMLParserFactory() const {
|
||||
return m_platformXMLParserFactory;
|
||||
}
|
||||
|
||||
EventLoop *getEventLoop() const {
|
||||
return eventLoop;
|
||||
}
|
||||
|
||||
Swift::TLSContextFactory* getTLSContextFactory() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Swift::ProxyProvider* getProxyProvider() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
PlatformXMLParserFactory *m_platformXMLParserFactory;
|
||||
TimerFactory* timerFactory;
|
||||
ConnectionFactory* connectionFactory;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<IDNConverter> idnConverter;
|
||||
#endif
|
||||
DomainNameResolver* domainNameResolver;
|
||||
ConnectionServerFactory* connectionServerFactory;
|
||||
EventLoop *eventLoop;
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
#include <Swiften/Network/NetworkFactories.h>
|
||||
#include <Swiften/Parser/PlatformXMLParserFactory.h>
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/IDN/IDNConverter.h>
|
||||
#include <Swiften/IDN/PlatformIDNConverter.h>
|
||||
#endif
|
||||
|
||||
namespace Swift {
|
||||
class EventLoop;
|
||||
|
||||
class DummyNetworkFactories : public NetworkFactories {
|
||||
public:
|
||||
DummyNetworkFactories(EventLoop *eventLoop);
|
||||
~DummyNetworkFactories();
|
||||
|
||||
virtual TimerFactory* getTimerFactory() const {
|
||||
return timerFactory;
|
||||
}
|
||||
|
||||
virtual ConnectionFactory* getConnectionFactory() const {
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
#if HAVE_SWIFTEN_3
|
||||
IDNConverter* getIDNConverter() const {
|
||||
return idnConverter.get();
|
||||
}
|
||||
Swift::CryptoProvider* getCryptoProvider() const {
|
||||
return cryptoProvider;
|
||||
}
|
||||
Swift::NetworkEnvironment* getNetworkEnvironment() const {
|
||||
return networkEnvironment;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
DomainNameResolver* getDomainNameResolver() const {
|
||||
return domainNameResolver;
|
||||
}
|
||||
|
||||
ConnectionServerFactory* getConnectionServerFactory() const {
|
||||
return connectionServerFactory;
|
||||
}
|
||||
|
||||
virtual Swift::NATTraverser* getNATTraverser() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Swift::XMLParserFactory* getXMLParserFactory() const {
|
||||
return m_platformXMLParserFactory;
|
||||
}
|
||||
|
||||
EventLoop *getEventLoop() const {
|
||||
return eventLoop;
|
||||
}
|
||||
|
||||
Swift::TLSContextFactory* getTLSContextFactory() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Swift::ProxyProvider* getProxyProvider() const {
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
PlatformXMLParserFactory *m_platformXMLParserFactory;
|
||||
TimerFactory* timerFactory;
|
||||
ConnectionFactory* connectionFactory;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<IDNConverter> idnConverter;
|
||||
CryptoProvider* cryptoProvider;
|
||||
NetworkEnvironment* networkEnvironment;
|
||||
#endif
|
||||
DomainNameResolver* domainNameResolver;
|
||||
ConnectionServerFactory* connectionServerFactory;
|
||||
EventLoop *eventLoop;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,183 +1,183 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Server/ServerFromClientSession.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <Swiften/Elements/ProtocolHeader.h>
|
||||
#include <Swiften/Elements/StreamError.h>
|
||||
#include <Swiften/Elements/Message.h>
|
||||
#include <Swiften/Server/UserRegistry.h>
|
||||
#include <Swiften/Network/Connection.h>
|
||||
#include <Swiften/StreamStack/XMPPLayer.h>
|
||||
#include <Swiften/Elements/StreamFeatures.h>
|
||||
#include <Swiften/Elements/ResourceBind.h>
|
||||
#include <Swiften/Elements/StartSession.h>
|
||||
#include <Swiften/Elements/IQ.h>
|
||||
#include <Swiften/Elements/AuthSuccess.h>
|
||||
#include <Swiften/Elements/AuthFailure.h>
|
||||
#include <Swiften/Elements/AuthRequest.h>
|
||||
#include <Swiften/SASL/PLAINMessage.h>
|
||||
#include <Swiften/StreamStack/StreamStack.h>
|
||||
#include <Swiften/StreamStack/TLSServerLayer.h>
|
||||
#include <Swiften/Elements/StartTLSRequest.h>
|
||||
#include <Swiften/Elements/TLSProceed.h>
|
||||
#include <iostream>
|
||||
#include <Swiften/TLS/CertificateWithKey.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
ServerFromClientSession::ServerFromClientSession(
|
||||
const std::string& id,
|
||||
boost::shared_ptr<Connection> connection,
|
||||
PayloadParserFactoryCollection* payloadParserFactories,
|
||||
PayloadSerializerCollection* payloadSerializers,
|
||||
UserRegistry* userRegistry,
|
||||
XMLParserFactory* factory,
|
||||
Swift::JID remoteJID) :
|
||||
Session(connection, payloadParserFactories, payloadSerializers, factory),
|
||||
id_(id),
|
||||
userRegistry_(userRegistry),
|
||||
authenticated_(false),
|
||||
initialized(false),
|
||||
allowSASLEXTERNAL(false),
|
||||
tlsLayer(0),
|
||||
tlsConnected(false) {
|
||||
setRemoteJID(remoteJID);
|
||||
}
|
||||
|
||||
ServerFromClientSession::~ServerFromClientSession() {
|
||||
if (tlsLayer) {
|
||||
delete tlsLayer;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordValid() {
|
||||
if (!isInitialized()) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
|
||||
authenticated_ = true;
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordInvalid(const std::string &error) {
|
||||
if (!isInitialized()) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
if (!error.empty()) {
|
||||
boost::shared_ptr<StreamError> msg(new StreamError(StreamError::UndefinedCondition, error));
|
||||
getXMPPLayer()->writeElement(msg);
|
||||
}
|
||||
|
||||
finishSession(AuthenticationFailedError);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
|
||||
if (isInitialized()) {
|
||||
onElementReceived(element);
|
||||
}
|
||||
else {
|
||||
if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
|
||||
if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
|
||||
if (authRequest->getMechanism() == "EXTERNAL") {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
|
||||
authenticated_ = true;
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
else {
|
||||
PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
|
||||
user_ = plainMessage.getAuthenticationID();
|
||||
userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
|
||||
}
|
||||
}
|
||||
else {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
finishSession(NoSupportedAuthMechanismsError);
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<StartTLSRequest*>(element.get()) != NULL) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<TLSProceed>(new TLSProceed));
|
||||
getStreamStack()->addLayer(tlsLayer);
|
||||
tlsLayer->connect();
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
|
||||
if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
|
||||
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
|
||||
std::string uuid;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uuid += bucket[rand() % bucket.size()];
|
||||
}
|
||||
setRemoteJID(JID(user_, getLocalJID().getDomain(), uuid));
|
||||
boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
|
||||
resultResourceBind->setJID(getRemoteJID());
|
||||
getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
|
||||
}
|
||||
else if (iq->getPayload<StartSession>()) {
|
||||
getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
|
||||
setInitialized();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
|
||||
setLocalJID(JID("", incomingHeader.getTo()));
|
||||
ProtocolHeader header;
|
||||
header.setFrom(incomingHeader.getTo());
|
||||
header.setID(id_);
|
||||
getXMPPLayer()->writeHeader(header);
|
||||
|
||||
boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
|
||||
|
||||
if (!authenticated_) {
|
||||
if (tlsLayer && !tlsConnected) {
|
||||
features->setHasStartTLS();
|
||||
}
|
||||
features->addAuthenticationMechanism("PLAIN");
|
||||
if (allowSASLEXTERNAL) {
|
||||
features->addAuthenticationMechanism("EXTERNAL");
|
||||
}
|
||||
}
|
||||
else {
|
||||
features->setHasResourceBind();
|
||||
features->setHasSession();
|
||||
}
|
||||
getXMPPLayer()->writeElement(features);
|
||||
}
|
||||
|
||||
void ServerFromClientSession::setInitialized() {
|
||||
initialized = true;
|
||||
onSessionStarted();
|
||||
}
|
||||
|
||||
void ServerFromClientSession::setAllowSASLEXTERNAL() {
|
||||
allowSASLEXTERNAL = true;
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
|
||||
userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
|
||||
}
|
||||
|
||||
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert) {
|
||||
tlsLayer = new TLSServerLayer(tlsContextFactory);
|
||||
if (!tlsLayer->setServerCertificate(cert)) {
|
||||
// std::cout << "error\n";
|
||||
// TODO:
|
||||
// onClosed(boost::shared_ptr<Error>(new Error(Error::InvalidTLSCertificateError)));
|
||||
}
|
||||
else {
|
||||
tlsLayer->onError.connect(boost::bind(&ServerFromClientSession::handleTLSError, this));
|
||||
tlsLayer->onConnected.connect(boost::bind(&ServerFromClientSession::handleTLSConnected, this));
|
||||
// getStreamStack()->addLayer(tlsLayer);
|
||||
// tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this));
|
||||
// tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
|
||||
// tlsLayer->connect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include <Swiften/Server/ServerFromClientSession.h>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <Swiften/Elements/ProtocolHeader.h>
|
||||
#include <Swiften/Elements/StreamError.h>
|
||||
#include <Swiften/Elements/Message.h>
|
||||
#include <Swiften/Server/UserRegistry.h>
|
||||
#include <Swiften/Network/Connection.h>
|
||||
#include <Swiften/StreamStack/XMPPLayer.h>
|
||||
#include <Swiften/Elements/StreamFeatures.h>
|
||||
#include <Swiften/Elements/ResourceBind.h>
|
||||
#include <Swiften/Elements/StartSession.h>
|
||||
#include <Swiften/Elements/IQ.h>
|
||||
#include <Swiften/Elements/AuthSuccess.h>
|
||||
#include <Swiften/Elements/AuthFailure.h>
|
||||
#include <Swiften/Elements/AuthRequest.h>
|
||||
#include <Swiften/SASL/PLAINMessage.h>
|
||||
#include <Swiften/StreamStack/StreamStack.h>
|
||||
#include <Swiften/StreamStack/TLSServerLayer.h>
|
||||
#include <Swiften/Elements/StartTLSRequest.h>
|
||||
#include <Swiften/Elements/TLSProceed.h>
|
||||
#include <iostream>
|
||||
#include <Swiften/TLS/CertificateWithKey.h>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
ServerFromClientSession::ServerFromClientSession(
|
||||
const std::string& id,
|
||||
boost::shared_ptr<Connection> connection,
|
||||
PayloadParserFactoryCollection* payloadParserFactories,
|
||||
PayloadSerializerCollection* payloadSerializers,
|
||||
UserRegistry* userRegistry,
|
||||
XMLParserFactory* factory,
|
||||
Swift::JID remoteJID) :
|
||||
Session(connection, payloadParserFactories, payloadSerializers, factory),
|
||||
id_(id),
|
||||
userRegistry_(userRegistry),
|
||||
authenticated_(false),
|
||||
initialized(false),
|
||||
allowSASLEXTERNAL(false),
|
||||
tlsLayer(0),
|
||||
tlsConnected(false) {
|
||||
setRemoteJID(remoteJID);
|
||||
}
|
||||
|
||||
ServerFromClientSession::~ServerFromClientSession() {
|
||||
if (tlsLayer) {
|
||||
delete tlsLayer;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordValid() {
|
||||
if (!isInitialized()) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
|
||||
authenticated_ = true;
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handlePasswordInvalid(const std::string &error) {
|
||||
if (!isInitialized()) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
if (!error.empty()) {
|
||||
boost::shared_ptr<StreamError> msg(new StreamError(StreamError::UndefinedCondition, error));
|
||||
getXMPPLayer()->writeElement(msg);
|
||||
}
|
||||
|
||||
finishSession(AuthenticationFailedError);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleElement(boost::shared_ptr<ToplevelElement> element) {
|
||||
if (isInitialized()) {
|
||||
onElementReceived(element);
|
||||
}
|
||||
else {
|
||||
if (AuthRequest* authRequest = dynamic_cast<AuthRequest*>(element.get())) {
|
||||
if (authRequest->getMechanism() == "PLAIN" || (allowSASLEXTERNAL && authRequest->getMechanism() == "EXTERNAL")) {
|
||||
if (authRequest->getMechanism() == "EXTERNAL") {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthSuccess>(new AuthSuccess()));
|
||||
authenticated_ = true;
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
else {
|
||||
PLAINMessage plainMessage(authRequest->getMessage() ? *authRequest->getMessage() : createSafeByteArray(""));
|
||||
user_ = plainMessage.getAuthenticationID();
|
||||
userRegistry_->isValidUserPassword(JID(plainMessage.getAuthenticationID(), getLocalJID().getDomain()), this, plainMessage.getPassword());
|
||||
}
|
||||
}
|
||||
else {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<AuthFailure>(new AuthFailure));
|
||||
finishSession(NoSupportedAuthMechanismsError);
|
||||
}
|
||||
}
|
||||
else if (dynamic_cast<StartTLSRequest*>(element.get()) != NULL) {
|
||||
getXMPPLayer()->writeElement(boost::shared_ptr<TLSProceed>(new TLSProceed));
|
||||
getStreamStack()->addLayer(tlsLayer);
|
||||
tlsLayer->connect();
|
||||
getXMPPLayer()->resetParser();
|
||||
}
|
||||
else if (IQ* iq = dynamic_cast<IQ*>(element.get())) {
|
||||
if (boost::shared_ptr<ResourceBind> resourceBind = iq->getPayload<ResourceBind>()) {
|
||||
std::string bucket = "abcdefghijklmnopqrstuvwxyz";
|
||||
std::string uuid;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
uuid += bucket[rand() % bucket.size()];
|
||||
}
|
||||
setRemoteJID(JID(user_, getLocalJID().getDomain(), uuid));
|
||||
boost::shared_ptr<ResourceBind> resultResourceBind(new ResourceBind());
|
||||
resultResourceBind->setJID(getRemoteJID());
|
||||
getXMPPLayer()->writeElement(IQ::createResult(JID(), iq->getID(), resultResourceBind));
|
||||
}
|
||||
else if (iq->getPayload<StartSession>()) {
|
||||
getXMPPLayer()->writeElement(IQ::createResult(getRemoteJID(), iq->getID()));
|
||||
setInitialized();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleStreamStart(const ProtocolHeader& incomingHeader) {
|
||||
setLocalJID(JID("", incomingHeader.getTo()));
|
||||
ProtocolHeader header;
|
||||
header.setFrom(incomingHeader.getTo());
|
||||
header.setID(id_);
|
||||
getXMPPLayer()->writeHeader(header);
|
||||
|
||||
boost::shared_ptr<StreamFeatures> features(new StreamFeatures());
|
||||
|
||||
if (!authenticated_) {
|
||||
if (tlsLayer && !tlsConnected) {
|
||||
features->setHasStartTLS();
|
||||
}
|
||||
features->addAuthenticationMechanism("PLAIN");
|
||||
if (allowSASLEXTERNAL) {
|
||||
features->addAuthenticationMechanism("EXTERNAL");
|
||||
}
|
||||
}
|
||||
else {
|
||||
features->setHasResourceBind();
|
||||
features->setHasSession();
|
||||
}
|
||||
getXMPPLayer()->writeElement(features);
|
||||
}
|
||||
|
||||
void ServerFromClientSession::setInitialized() {
|
||||
initialized = true;
|
||||
onSessionStarted();
|
||||
}
|
||||
|
||||
void ServerFromClientSession::setAllowSASLEXTERNAL() {
|
||||
allowSASLEXTERNAL = true;
|
||||
}
|
||||
|
||||
void ServerFromClientSession::handleSessionFinished(const boost::optional<SessionError>&) {
|
||||
userRegistry_->stopLogin(JID(user_, getLocalJID().getDomain()), this);
|
||||
}
|
||||
|
||||
void ServerFromClientSession::addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert) {
|
||||
tlsLayer = new TLSServerLayer(tlsContextFactory);
|
||||
if (!tlsLayer->setServerCertificate(cert)) {
|
||||
// std::cout << "error\n";
|
||||
// TODO:
|
||||
// onClosed(boost::shared_ptr<Error>(new Error(Error::InvalidTLSCertificateError)));
|
||||
}
|
||||
else {
|
||||
tlsLayer->onError.connect(boost::bind(&ServerFromClientSession::handleTLSError, this));
|
||||
tlsLayer->onConnected.connect(boost::bind(&ServerFromClientSession::handleTLSConnected, this));
|
||||
// getStreamStack()->addLayer(tlsLayer);
|
||||
// tlsLayer->onError.connect(boost::bind(&BasicSessionStream::handleTLSError, this));
|
||||
// tlsLayer->onConnected.connect(boost::bind(&BasicSessionStream::handleTLSConnected, this));
|
||||
// tlsLayer->connect();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,91 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <Swiften/Base/boost_bsignals.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Session/Session.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include <Swiften/Network/Connection.h>
|
||||
#include <Swiften/Base/ByteArray.h>
|
||||
#include <Swiften/TLS/CertificateWithKey.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class ProtocolHeader;
|
||||
class Element;
|
||||
class Stanza;
|
||||
class PayloadParserFactoryCollection;
|
||||
class PayloadSerializerCollection;
|
||||
class StreamStack;
|
||||
class UserRegistry;
|
||||
class XMPPLayer;
|
||||
class ConnectionLayer;
|
||||
class Connection;
|
||||
class TLSServerLayer;
|
||||
class TLSServerContextFactory;
|
||||
class PKCS12Certificate;
|
||||
|
||||
class ServerFromClientSession : public Session {
|
||||
public:
|
||||
ServerFromClientSession(
|
||||
const std::string& id,
|
||||
boost::shared_ptr<Connection> connection,
|
||||
PayloadParserFactoryCollection* payloadParserFactories,
|
||||
PayloadSerializerCollection* payloadSerializers,
|
||||
UserRegistry* userRegistry,
|
||||
XMLParserFactory* factory,
|
||||
Swift::JID remoteJID = Swift::JID());
|
||||
~ServerFromClientSession();
|
||||
|
||||
boost::signal<void ()> onSessionStarted;
|
||||
void setAllowSASLEXTERNAL();
|
||||
const std::string &getUser() {
|
||||
return user_;
|
||||
}
|
||||
|
||||
void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert);
|
||||
|
||||
Swift::JID getBareJID() {
|
||||
return Swift::JID(user_, getLocalJID().getDomain());
|
||||
}
|
||||
|
||||
void handlePasswordValid();
|
||||
void handlePasswordInvalid(const std::string &error = "");
|
||||
|
||||
private:
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<ToplevelElement>);
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Element>);
|
||||
#endif
|
||||
void handleStreamStart(const ProtocolHeader& header);
|
||||
void handleSessionFinished(const boost::optional<SessionError>&);
|
||||
|
||||
void setInitialized();
|
||||
bool isInitialized() const {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void handleTLSError() { }
|
||||
void handleTLSConnected() { tlsConnected = true; }
|
||||
|
||||
private:
|
||||
std::string id_;
|
||||
UserRegistry* userRegistry_;
|
||||
bool authenticated_;
|
||||
bool initialized;
|
||||
bool allowSASLEXTERNAL;
|
||||
std::string user_;
|
||||
TLSServerLayer* tlsLayer;
|
||||
bool tlsConnected;
|
||||
};
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <Swiften/Base/boost_bsignals.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Session/Session.h>
|
||||
#include <Swiften/JID/JID.h>
|
||||
#include <Swiften/Network/Connection.h>
|
||||
#include <Swiften/Base/ByteArray.h>
|
||||
#include <Swiften/TLS/CertificateWithKey.h>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class ProtocolHeader;
|
||||
class Element;
|
||||
class Stanza;
|
||||
class PayloadParserFactoryCollection;
|
||||
class PayloadSerializerCollection;
|
||||
class StreamStack;
|
||||
class UserRegistry;
|
||||
class XMPPLayer;
|
||||
class ConnectionLayer;
|
||||
class Connection;
|
||||
class TLSServerLayer;
|
||||
class TLSServerContextFactory;
|
||||
class PKCS12Certificate;
|
||||
|
||||
class ServerFromClientSession : public Session {
|
||||
public:
|
||||
ServerFromClientSession(
|
||||
const std::string& id,
|
||||
boost::shared_ptr<Connection> connection,
|
||||
PayloadParserFactoryCollection* payloadParserFactories,
|
||||
PayloadSerializerCollection* payloadSerializers,
|
||||
UserRegistry* userRegistry,
|
||||
XMLParserFactory* factory,
|
||||
Swift::JID remoteJID = Swift::JID());
|
||||
~ServerFromClientSession();
|
||||
|
||||
boost::signal<void ()> onSessionStarted;
|
||||
void setAllowSASLEXTERNAL();
|
||||
const std::string &getUser() {
|
||||
return user_;
|
||||
}
|
||||
|
||||
void addTLSEncryption(TLSServerContextFactory* tlsContextFactory, CertificateWithKey::ref cert);
|
||||
|
||||
Swift::JID getBareJID() {
|
||||
return Swift::JID(user_, getLocalJID().getDomain());
|
||||
}
|
||||
|
||||
void handlePasswordValid();
|
||||
void handlePasswordInvalid(const std::string &error = "");
|
||||
|
||||
private:
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<ToplevelElement>);
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Element>);
|
||||
#endif
|
||||
void handleStreamStart(const ProtocolHeader& header);
|
||||
void handleSessionFinished(const boost::optional<SessionError>&);
|
||||
|
||||
void setInitialized();
|
||||
bool isInitialized() const {
|
||||
return initialized;
|
||||
}
|
||||
|
||||
void handleTLSError() { }
|
||||
void handleTLSConnected() { tlsConnected = true; }
|
||||
|
||||
private:
|
||||
std::string id_;
|
||||
UserRegistry* userRegistry_;
|
||||
bool authenticated_;
|
||||
bool initialized;
|
||||
bool allowSASLEXTERNAL;
|
||||
std::string user_;
|
||||
TLSServerLayer* tlsLayer;
|
||||
bool tlsConnected;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,179 +1,179 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include "Swiften/Server/ServerStanzaChannel.h"
|
||||
#include "Swiften/Base/Error.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
namespace {
|
||||
// struct PriorityLessThan {
|
||||
// bool operator()(const ServerSession* s1, const ServerSession* s2) const {
|
||||
// return s1->getPriority() < s2->getPriority();
|
||||
// }
|
||||
// };
|
||||
|
||||
struct HasJID {
|
||||
HasJID(const JID& jid) : jid(jid) {}
|
||||
bool operator()(const boost::shared_ptr<ServerFromClientSession> session) const {
|
||||
return session->getRemoteJID().equals(jid, JID::WithResource);
|
||||
}
|
||||
JID jid;
|
||||
};
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
sessions[session->getRemoteJID().toBare().toString()].push_back(session);
|
||||
session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
|
||||
session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
|
||||
session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::removeSession(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
|
||||
session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
|
||||
session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
|
||||
std::list<boost::shared_ptr<ServerFromClientSession> > &lst = sessions[session->getRemoteJID().toBare().toString()];
|
||||
lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end());
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendIQ(boost::shared_ptr<IQ> iq) {
|
||||
send(iq);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendMessage(boost::shared_ptr<Message> message) {
|
||||
send(message);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
|
||||
send(presence);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session) {
|
||||
if (safeByteArrayToString(data).find("</stream:stream>") != std::string::npos) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
}
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last) {
|
||||
#else
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
|
||||
#endif
|
||||
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
|
||||
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
|
||||
candidateSessions.push_back(*i);
|
||||
}
|
||||
|
||||
for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
|
||||
removeSession(*i);
|
||||
if (element) {
|
||||
(*i)->sendElement(element);
|
||||
}
|
||||
|
||||
if (last && (*i)->getRemoteJID().isValid()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom((*i)->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
}
|
||||
|
||||
(*i)->finishSession();
|
||||
// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ServerStanzaChannel::getNewIQID() {
|
||||
return idGenerator.generateID();
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
|
||||
JID to = stanza->getTo();
|
||||
assert(to.isValid());
|
||||
|
||||
// For a full JID, first try to route to a session with the full JID
|
||||
if (!to.isBare()) {
|
||||
std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to));
|
||||
if (i != sessions[stanza->getTo().toBare().toString()].end()) {
|
||||
(*i)->sendElement(stanza);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for candidate sessions
|
||||
to = to.toBare();
|
||||
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
|
||||
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) {
|
||||
if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) {
|
||||
candidateSessions.push_back(*i);
|
||||
(*i)->sendElement(stanza);
|
||||
}
|
||||
}
|
||||
if (candidateSessions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the session with the highest priority
|
||||
// std::vector<ServerSession*>::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan());
|
||||
// (*i)->sendStanza(stanza);
|
||||
return;
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
removeSession(session);
|
||||
|
||||
// if (!session->initiatedFinish()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
// }
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
|
||||
if (!stanza) {
|
||||
return;
|
||||
}
|
||||
|
||||
stanza->setFrom(session->getRemoteJID());
|
||||
|
||||
if (!stanza->getFrom().isValid())
|
||||
return;
|
||||
|
||||
|
||||
boost::shared_ptr<Message> message = boost::dynamic_pointer_cast<Message>(stanza);
|
||||
if (message) {
|
||||
onMessageReceived(message);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza);
|
||||
if (presence) {
|
||||
onPresenceReceived(presence);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza);
|
||||
if (iq) {
|
||||
onIQReceived(iq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleSessionInitialized() {
|
||||
onAvailableChanged(true);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#include "Swiften/Server/ServerStanzaChannel.h"
|
||||
#include "Swiften/Base/Error.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
namespace Swift {
|
||||
|
||||
namespace {
|
||||
// struct PriorityLessThan {
|
||||
// bool operator()(const ServerSession* s1, const ServerSession* s2) const {
|
||||
// return s1->getPriority() < s2->getPriority();
|
||||
// }
|
||||
// };
|
||||
|
||||
struct HasJID {
|
||||
HasJID(const JID& jid) : jid(jid) {}
|
||||
bool operator()(const boost::shared_ptr<ServerFromClientSession> session) const {
|
||||
return session->getRemoteJID().equals(jid, JID::WithResource);
|
||||
}
|
||||
JID jid;
|
||||
};
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::addSession(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
sessions[session->getRemoteJID().toBare().toString()].push_back(session);
|
||||
session->onSessionFinished.connect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
|
||||
session->onElementReceived.connect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
|
||||
session->onDataRead.connect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::removeSession(boost::shared_ptr<ServerFromClientSession> session) {
|
||||
session->onSessionFinished.disconnect(boost::bind(&ServerStanzaChannel::handleSessionFinished, this, _1, session));
|
||||
session->onElementReceived.disconnect(boost::bind(&ServerStanzaChannel::handleElement, this, _1, session));
|
||||
session->onDataRead.disconnect(boost::bind(&ServerStanzaChannel::handleDataRead, this, _1, session));
|
||||
std::list<boost::shared_ptr<ServerFromClientSession> > &lst = sessions[session->getRemoteJID().toBare().toString()];
|
||||
lst.erase(std::remove(lst.begin(), lst.end(), session), lst.end());
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendIQ(boost::shared_ptr<IQ> iq) {
|
||||
send(iq);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendMessage(boost::shared_ptr<Message> message) {
|
||||
send(message);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::sendPresence(boost::shared_ptr<Presence> presence) {
|
||||
send(presence);
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session) {
|
||||
if (safeByteArrayToString(data).find("</stream:stream>") != std::string::npos) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
}
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last) {
|
||||
#else
|
||||
void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr<Element> element, bool last) {
|
||||
#endif
|
||||
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
|
||||
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) {
|
||||
candidateSessions.push_back(*i);
|
||||
}
|
||||
|
||||
for (std::vector<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) {
|
||||
removeSession(*i);
|
||||
if (element) {
|
||||
(*i)->sendElement(element);
|
||||
}
|
||||
|
||||
if (last && (*i)->getRemoteJID().isValid()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom((*i)->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
}
|
||||
|
||||
(*i)->finishSession();
|
||||
// std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n";
|
||||
if (last) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string ServerStanzaChannel::getNewIQID() {
|
||||
return idGenerator.generateID();
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::send(boost::shared_ptr<Stanza> stanza) {
|
||||
JID to = stanza->getTo();
|
||||
assert(to.isValid());
|
||||
|
||||
// For a full JID, first try to route to a session with the full JID
|
||||
if (!to.isBare()) {
|
||||
std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = std::find_if(sessions[stanza->getTo().toBare().toString()].begin(), sessions[stanza->getTo().toBare().toString()].end(), HasJID(to));
|
||||
if (i != sessions[stanza->getTo().toBare().toString()].end()) {
|
||||
(*i)->sendElement(stanza);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Look for candidate sessions
|
||||
to = to.toBare();
|
||||
std::vector<boost::shared_ptr<ServerFromClientSession> > candidateSessions;
|
||||
for (std::list<boost::shared_ptr<ServerFromClientSession> >::const_iterator i = sessions[stanza->getTo().toBare().toString()].begin(); i != sessions[stanza->getTo().toBare().toString()].end(); ++i) {
|
||||
if ((*i)->getRemoteJID().equals(to, JID::WithoutResource)) {
|
||||
candidateSessions.push_back(*i);
|
||||
(*i)->sendElement(stanza);
|
||||
}
|
||||
}
|
||||
if (candidateSessions.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the session with the highest priority
|
||||
// std::vector<ServerSession*>::const_iterator i = std::max_element(sessions.begin(), sessions.end(), PriorityLessThan());
|
||||
// (*i)->sendStanza(stanza);
|
||||
return;
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
removeSession(session);
|
||||
|
||||
// if (!session->initiatedFinish()) {
|
||||
Swift::Presence::ref presence = Swift::Presence::create();
|
||||
presence->setFrom(session->getRemoteJID());
|
||||
presence->setType(Swift::Presence::Unavailable);
|
||||
onPresenceReceived(presence);
|
||||
// }
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession>& session) {
|
||||
boost::shared_ptr<Stanza> stanza = boost::dynamic_pointer_cast<Stanza>(element);
|
||||
if (!stanza) {
|
||||
return;
|
||||
}
|
||||
|
||||
stanza->setFrom(session->getRemoteJID());
|
||||
|
||||
if (!stanza->getFrom().isValid())
|
||||
return;
|
||||
|
||||
|
||||
boost::shared_ptr<Message> message = boost::dynamic_pointer_cast<Message>(stanza);
|
||||
if (message) {
|
||||
onMessageReceived(message);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza);
|
||||
if (presence) {
|
||||
onPresenceReceived(presence);
|
||||
return;
|
||||
}
|
||||
|
||||
boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza);
|
||||
if (iq) {
|
||||
onIQReceived(iq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void ServerStanzaChannel::handleSessionInitialized() {
|
||||
onAvailableChanged(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,62 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "Swiften/Base/IDGenerator.h"
|
||||
#include "Swiften/Server/ServerFromClientSession.h"
|
||||
#include "Swiften/Client/StanzaChannel.h"
|
||||
#include "Swiften/Elements/Message.h"
|
||||
#include "Swiften/Elements/IQ.h"
|
||||
#include "Swiften/Elements/Presence.h"
|
||||
#include "Swiften/TLS/Certificate.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class Error;
|
||||
class ServerStanzaChannel : public StanzaChannel {
|
||||
public:
|
||||
void addSession(boost::shared_ptr<ServerFromClientSession> session);
|
||||
void removeSession(boost::shared_ptr<ServerFromClientSession> session);
|
||||
|
||||
void sendIQ(boost::shared_ptr<IQ> iq);
|
||||
void sendMessage(boost::shared_ptr<Message> message);
|
||||
void sendPresence(boost::shared_ptr<Presence> presence);
|
||||
#if HAVE_SWIFTEN_3
|
||||
void finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last = false);
|
||||
#else
|
||||
void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
|
||||
#endif
|
||||
bool getStreamManagementEnabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAvailable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Certificate::ref> getPeerCertificateChain() const {
|
||||
return std::vector<Certificate::ref>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string getNewIQID();
|
||||
void send(boost::shared_ptr<Stanza> stanza);
|
||||
void handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleSessionInitialized();
|
||||
|
||||
private:
|
||||
IDGenerator idGenerator;
|
||||
// [JID][resources][ServerFromClientSession]
|
||||
std::map<std::string, std::list<boost::shared_ptr<ServerFromClientSession> > > sessions;
|
||||
};
|
||||
|
||||
}
|
||||
/*
|
||||
* Copyright (c) 2010 Remko Tronçon
|
||||
* Licensed under the GNU General Public License v3.
|
||||
* See Documentation/Licenses/GPLv3.txt for more information.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "Swiften/Base/IDGenerator.h"
|
||||
#include "Swiften/Server/ServerFromClientSession.h"
|
||||
#include "Swiften/Client/StanzaChannel.h"
|
||||
#include "Swiften/Elements/Message.h"
|
||||
#include "Swiften/Elements/IQ.h"
|
||||
#include "Swiften/Elements/Presence.h"
|
||||
#include "Swiften/TLS/Certificate.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Swift {
|
||||
class Error;
|
||||
class ServerStanzaChannel : public StanzaChannel {
|
||||
public:
|
||||
void addSession(boost::shared_ptr<ServerFromClientSession> session);
|
||||
void removeSession(boost::shared_ptr<ServerFromClientSession> session);
|
||||
|
||||
void sendIQ(boost::shared_ptr<IQ> iq);
|
||||
void sendMessage(boost::shared_ptr<Message> message);
|
||||
void sendPresence(boost::shared_ptr<Presence> presence);
|
||||
#if HAVE_SWIFTEN_3
|
||||
void finishSession(const JID& to, boost::shared_ptr<ToplevelElement> element, bool last = false);
|
||||
#else
|
||||
void finishSession(const JID& to, boost::shared_ptr<Element> element, bool last = false);
|
||||
#endif
|
||||
bool getStreamManagementEnabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isAvailable() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<Certificate::ref> getPeerCertificateChain() const {
|
||||
return std::vector<Certificate::ref>();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string getNewIQID();
|
||||
void send(boost::shared_ptr<Stanza> stanza);
|
||||
void handleSessionFinished(const boost::optional<Session::SessionError>&, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleElement(boost::shared_ptr<Element> element, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleDataRead(const SafeByteArray &data, const boost::shared_ptr<ServerFromClientSession> &session);
|
||||
void handleSessionInitialized();
|
||||
|
||||
private:
|
||||
IDGenerator idGenerator;
|
||||
// [JID][resources][ServerFromClientSession]
|
||||
std::map<std::string, std::list<boost::shared_ptr<ServerFromClientSession> > > sessions;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,83 +1,83 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#include <Swiften/Elements/StreamInitiationFileInfo.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/ConnectivityManager.h>
|
||||
#endif
|
||||
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
|
||||
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
|
||||
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
|
||||
#else
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
|
||||
#endif
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
|
||||
#endif
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class UserManager;
|
||||
class User;
|
||||
class Component;
|
||||
class Buddy;
|
||||
|
||||
class FileTransferManager {
|
||||
public:
|
||||
typedef struct Transfer {
|
||||
boost::shared_ptr<Swift::OutgoingFileTransfer> ft;
|
||||
Swift::JID from;
|
||||
Swift::JID to;
|
||||
boost::shared_ptr<Swift::ReadBytestream> readByteStream;
|
||||
} Transfer;
|
||||
|
||||
FileTransferManager(Component *component, UserManager *userManager);
|
||||
virtual ~FileTransferManager();
|
||||
|
||||
FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info);
|
||||
|
||||
private:
|
||||
Component *m_component;
|
||||
UserManager *m_userManager;
|
||||
Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager;
|
||||
Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory;
|
||||
Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory;
|
||||
Swift::JingleSessionManager *m_jingleSessionManager;
|
||||
Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry;
|
||||
#if HAVE_SWIFTEN_3
|
||||
Swift::SOCKS5BytestreamServerManager* m_proxyServerManager;
|
||||
Swift::SOCKS5BytestreamProxiesManager *m_proxyManager;
|
||||
#else
|
||||
Swift::SOCKS5BytestreamServer* m_bytestreamServer;
|
||||
Swift::SOCKS5BytestreamProxy* m_bytestreamProxy;
|
||||
Swift::SOCKS5BytestreamServer *bytestreamServer;
|
||||
Swift::ConnectivityManager* m_connectivityManager;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#include <Swiften/Elements/StreamInitiationFileInfo.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/ConnectivityManager.h>
|
||||
#endif
|
||||
#include <Swiften/FileTransfer/CombinedOutgoingFileTransferManager.h>
|
||||
#include <Swiften/FileTransfer/IncomingFileTransferManager.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/DefaultLocalJingleTransportCandidateGeneratorFactory.h>
|
||||
#include <Swiften/FileTransfer/DefaultRemoteJingleTransportCandidateSelectorFactory.h>
|
||||
#else
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamProxiesManager.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServerManager.h>
|
||||
#endif
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamRegistry.h>
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#if !HAVE_SWIFTEN_3
|
||||
#include <Swiften/FileTransfer/SOCKS5BytestreamProxy.h>
|
||||
#endif
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class UserManager;
|
||||
class User;
|
||||
class Component;
|
||||
class Buddy;
|
||||
|
||||
class FileTransferManager {
|
||||
public:
|
||||
typedef struct Transfer {
|
||||
boost::shared_ptr<Swift::OutgoingFileTransfer> ft;
|
||||
Swift::JID from;
|
||||
Swift::JID to;
|
||||
boost::shared_ptr<Swift::ReadBytestream> readByteStream;
|
||||
} Transfer;
|
||||
|
||||
FileTransferManager(Component *component, UserManager *userManager);
|
||||
virtual ~FileTransferManager();
|
||||
|
||||
FileTransferManager::Transfer sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info);
|
||||
|
||||
private:
|
||||
Component *m_component;
|
||||
UserManager *m_userManager;
|
||||
Swift::CombinedOutgoingFileTransferManager* m_outgoingFTManager;
|
||||
Swift::RemoteJingleTransportCandidateSelectorFactory* m_remoteCandidateSelectorFactory;
|
||||
Swift::LocalJingleTransportCandidateGeneratorFactory* m_localCandidateGeneratorFactory;
|
||||
Swift::JingleSessionManager *m_jingleSessionManager;
|
||||
Swift::SOCKS5BytestreamRegistry* m_bytestreamRegistry;
|
||||
#if HAVE_SWIFTEN_3
|
||||
Swift::SOCKS5BytestreamServerManager* m_proxyServerManager;
|
||||
Swift::SOCKS5BytestreamProxiesManager *m_proxyManager;
|
||||
#else
|
||||
Swift::SOCKS5BytestreamServer* m_bytestreamServer;
|
||||
Swift::SOCKS5BytestreamProxy* m_bytestreamProxy;
|
||||
Swift::SOCKS5BytestreamServer *bytestreamServer;
|
||||
Swift::ConnectivityManager* m_connectivityManager;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#undef TYPE_BOOL
|
||||
#include "transport/protocol.pb.h"
|
||||
// #include "conversation.h"
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,199 +1,199 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include "Swiften/Presence/PresenceOracle.h"
|
||||
#include "Swiften/Disco/EntityCapsManager.h"
|
||||
#include "Swiften/Network/BoostConnectionServer.h"
|
||||
#include "Swiften/Network/Connection.h"
|
||||
#include "Swiften/Elements/ChatState.h"
|
||||
#include "Swiften/Elements/RosterItemPayload.h"
|
||||
#include "Swiften/Elements/VCard.h"
|
||||
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
|
||||
#include "Swiften/Parser/XMPPParser.h"
|
||||
#include "Swiften/Parser/XMPPParserClient.h"
|
||||
#include "Swiften/Serializer/XMPPSerializer.h"
|
||||
#include "storagebackend.h"
|
||||
#include "transport/filetransfermanager.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class UserManager;
|
||||
class User;
|
||||
class Component;
|
||||
class Buddy;
|
||||
class LocalBuddy;
|
||||
class Config;
|
||||
class NetworkConversation;
|
||||
class VCardResponder;
|
||||
class RosterResponder;
|
||||
class BlockResponder;
|
||||
class DummyReadBytestream;
|
||||
class AdminInterface;
|
||||
class DiscoItemsResponder;
|
||||
|
||||
class NetworkPluginServer : Swift::XMPPParserClient {
|
||||
public:
|
||||
struct Backend {
|
||||
int pongReceived;
|
||||
std::list<User *> users;
|
||||
Swift::SafeByteArray data;
|
||||
boost::shared_ptr<Swift::Connection> connection;
|
||||
unsigned long res;
|
||||
unsigned long init_res;
|
||||
unsigned long shared;
|
||||
bool acceptUsers;
|
||||
bool longRun;
|
||||
bool willDie;
|
||||
std::string id;
|
||||
};
|
||||
|
||||
NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder);
|
||||
|
||||
virtual ~NetworkPluginServer();
|
||||
|
||||
void start();
|
||||
|
||||
void setAdminInterface(AdminInterface *adminInterface) {
|
||||
m_adminInterface = adminInterface;
|
||||
}
|
||||
|
||||
int getBackendCount() {
|
||||
return m_clients.size();
|
||||
}
|
||||
|
||||
const std::list<Backend *> &getBackends() {
|
||||
return m_clients;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getCrashedBackends() {
|
||||
return m_crashedBackends;
|
||||
}
|
||||
|
||||
void collectBackend();
|
||||
|
||||
bool moveToLongRunBackend(User *user);
|
||||
|
||||
void handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &message);
|
||||
|
||||
public:
|
||||
void handleNewClientConnection(boost::shared_ptr<Swift::Connection> c);
|
||||
void handleSessionFinished(Backend *c);
|
||||
void handlePongReceived(Backend *c);
|
||||
void handleDataRead(Backend *c, boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
void handleConnectedPayload(const std::string &payload);
|
||||
void handleDisconnectedPayload(const std::string &payload);
|
||||
void handleBuddyChangedPayload(const std::string &payload);
|
||||
void handleBuddyRemovedPayload(const std::string &payload);
|
||||
void handleConvMessagePayload(const std::string &payload, bool subject = false);
|
||||
void handleConvMessageAckPayload(const std::string &payload);
|
||||
void handleParticipantChangedPayload(const std::string &payload);
|
||||
void handleRoomChangedPayload(const std::string &payload);
|
||||
void handleVCardPayload(const std::string &payload);
|
||||
void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
|
||||
void handleAuthorizationPayload(const std::string &payload);
|
||||
void handleAttentionPayload(const std::string &payload);
|
||||
void handleStatsPayload(Backend *c, const std::string &payload);
|
||||
void handleFTStartPayload(const std::string &payload);
|
||||
void handleFTFinishPayload(const std::string &payload);
|
||||
void handleFTDataPayload(Backend *b, const std::string &payload);
|
||||
void handleQueryPayload(Backend *b, const std::string &payload);
|
||||
void handleBackendConfigPayload(const std::string &payload);
|
||||
void handleRoomListPayload(const std::string &payload);
|
||||
void handleRawXML(const std::string &xml);
|
||||
|
||||
void handleUserCreated(User *user);
|
||||
void handleRoomJoined(User *user, const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password);
|
||||
void handleRoomLeft(User *user, const std::string &room);
|
||||
void handleUserReadyToConnect(User *user);
|
||||
void handleUserPresenceChanged(User *user, Swift::Presence::ref presence);
|
||||
void handleUserDestroyed(User *user);
|
||||
|
||||
void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
|
||||
void handleBuddyRemoved(Buddy *buddy);
|
||||
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
|
||||
void handleUserBuddyAdded(User *user, Buddy *buddy);
|
||||
void handleUserBuddyRemoved(User *user, Buddy *buddy);
|
||||
|
||||
void handleBlockToggled(Buddy *buddy);
|
||||
|
||||
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard);
|
||||
void handleVCardRequired(User *user, const std::string &name, unsigned int id);
|
||||
|
||||
void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id);
|
||||
void handleFTAccepted(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID);
|
||||
void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
|
||||
void handleFTDataNeeded(Backend *b, unsigned long ftid);
|
||||
|
||||
void handlePIDTerminated(unsigned long pid);
|
||||
private:
|
||||
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
|
||||
|
||||
void pingTimeout();
|
||||
void sendPing(Backend *c);
|
||||
Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false);
|
||||
void connectWaitingUsers();
|
||||
void loginDelayFinished();
|
||||
void handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq);
|
||||
void handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence);
|
||||
|
||||
void handleStreamStart(const Swift::ProtocolHeader&) {}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Swift::Element> element);
|
||||
#endif
|
||||
void handleStreamEnd() {}
|
||||
|
||||
UserManager *m_userManager;
|
||||
VCardResponder *m_vcardResponder;
|
||||
RosterResponder *m_rosterResponder;
|
||||
BlockResponder *m_blockResponder;
|
||||
Config *m_config;
|
||||
boost::shared_ptr<Swift::ConnectionServer> m_server;
|
||||
std::list<Backend *> m_clients;
|
||||
std::vector<unsigned long> m_pids;
|
||||
Swift::Timer::ref m_pingTimer;
|
||||
Swift::Timer::ref m_collectTimer;
|
||||
Swift::Timer::ref m_loginTimer;
|
||||
Component *m_component;
|
||||
std::list<User *> m_waitingUsers;
|
||||
bool m_isNextLongRun;
|
||||
std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
|
||||
FileTransferManager *m_ftManager;
|
||||
std::vector<std::string> m_crashedBackends;
|
||||
AdminInterface *m_adminInterface;
|
||||
bool m_startingBackend;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
time_t m_lastLogin;
|
||||
Swift::XMPPParser *m_xmppParser;
|
||||
Swift::FullPayloadParserFactoryCollection m_collection;
|
||||
Swift::XMPPSerializer *m_serializer;
|
||||
Swift::FullPayloadSerializerCollection m_collection2;
|
||||
std::map <std::string, std::string> m_id2resource;
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
#include "Swiften/Presence/PresenceOracle.h"
|
||||
#include "Swiften/Disco/EntityCapsManager.h"
|
||||
#include "Swiften/Network/BoostConnectionServer.h"
|
||||
#include "Swiften/Network/Connection.h"
|
||||
#include "Swiften/Elements/ChatState.h"
|
||||
#include "Swiften/Elements/RosterItemPayload.h"
|
||||
#include "Swiften/Elements/VCard.h"
|
||||
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/FullPayloadSerializerCollection.h"
|
||||
#include "Swiften/Parser/XMPPParser.h"
|
||||
#include "Swiften/Parser/XMPPParserClient.h"
|
||||
#include "Swiften/Serializer/XMPPSerializer.h"
|
||||
#include "storagebackend.h"
|
||||
#include "transport/filetransfermanager.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class UserManager;
|
||||
class User;
|
||||
class Component;
|
||||
class Buddy;
|
||||
class LocalBuddy;
|
||||
class Config;
|
||||
class NetworkConversation;
|
||||
class VCardResponder;
|
||||
class RosterResponder;
|
||||
class BlockResponder;
|
||||
class DummyReadBytestream;
|
||||
class AdminInterface;
|
||||
class DiscoItemsResponder;
|
||||
|
||||
class NetworkPluginServer : Swift::XMPPParserClient {
|
||||
public:
|
||||
struct Backend {
|
||||
int pongReceived;
|
||||
std::list<User *> users;
|
||||
Swift::SafeByteArray data;
|
||||
boost::shared_ptr<Swift::Connection> connection;
|
||||
unsigned long res;
|
||||
unsigned long init_res;
|
||||
unsigned long shared;
|
||||
bool acceptUsers;
|
||||
bool longRun;
|
||||
bool willDie;
|
||||
std::string id;
|
||||
};
|
||||
|
||||
NetworkPluginServer(Component *component, Config *config, UserManager *userManager, FileTransferManager *ftManager, DiscoItemsResponder *discoItemsResponder);
|
||||
|
||||
virtual ~NetworkPluginServer();
|
||||
|
||||
void start();
|
||||
|
||||
void setAdminInterface(AdminInterface *adminInterface) {
|
||||
m_adminInterface = adminInterface;
|
||||
}
|
||||
|
||||
int getBackendCount() {
|
||||
return m_clients.size();
|
||||
}
|
||||
|
||||
const std::list<Backend *> &getBackends() {
|
||||
return m_clients;
|
||||
}
|
||||
|
||||
const std::vector<std::string> &getCrashedBackends() {
|
||||
return m_crashedBackends;
|
||||
}
|
||||
|
||||
void collectBackend();
|
||||
|
||||
bool moveToLongRunBackend(User *user);
|
||||
|
||||
void handleMessageReceived(NetworkConversation *conv, boost::shared_ptr<Swift::Message> &message);
|
||||
|
||||
public:
|
||||
void handleNewClientConnection(boost::shared_ptr<Swift::Connection> c);
|
||||
void handleSessionFinished(Backend *c);
|
||||
void handlePongReceived(Backend *c);
|
||||
void handleDataRead(Backend *c, boost::shared_ptr<Swift::SafeByteArray> data);
|
||||
|
||||
void handleConnectedPayload(const std::string &payload);
|
||||
void handleDisconnectedPayload(const std::string &payload);
|
||||
void handleBuddyChangedPayload(const std::string &payload);
|
||||
void handleBuddyRemovedPayload(const std::string &payload);
|
||||
void handleConvMessagePayload(const std::string &payload, bool subject = false);
|
||||
void handleConvMessageAckPayload(const std::string &payload);
|
||||
void handleParticipantChangedPayload(const std::string &payload);
|
||||
void handleRoomChangedPayload(const std::string &payload);
|
||||
void handleVCardPayload(const std::string &payload);
|
||||
void handleChatStatePayload(const std::string &payload, Swift::ChatState::ChatStateType type);
|
||||
void handleAuthorizationPayload(const std::string &payload);
|
||||
void handleAttentionPayload(const std::string &payload);
|
||||
void handleStatsPayload(Backend *c, const std::string &payload);
|
||||
void handleFTStartPayload(const std::string &payload);
|
||||
void handleFTFinishPayload(const std::string &payload);
|
||||
void handleFTDataPayload(Backend *b, const std::string &payload);
|
||||
void handleQueryPayload(Backend *b, const std::string &payload);
|
||||
void handleBackendConfigPayload(const std::string &payload);
|
||||
void handleRoomListPayload(const std::string &payload);
|
||||
void handleRawXML(const std::string &xml);
|
||||
|
||||
void handleUserCreated(User *user);
|
||||
void handleRoomJoined(User *user, const Swift::JID &who, const std::string &room, const std::string &nickname, const std::string &password);
|
||||
void handleRoomLeft(User *user, const std::string &room);
|
||||
void handleUserReadyToConnect(User *user);
|
||||
void handleUserPresenceChanged(User *user, Swift::Presence::ref presence);
|
||||
void handleUserDestroyed(User *user);
|
||||
|
||||
void handleBuddyUpdated(Buddy *buddy, const Swift::RosterItemPayload &item);
|
||||
void handleBuddyRemoved(Buddy *buddy);
|
||||
void handleBuddyAdded(Buddy *buddy, const Swift::RosterItemPayload &item);
|
||||
void handleUserBuddyAdded(User *user, Buddy *buddy);
|
||||
void handleUserBuddyRemoved(User *user, Buddy *buddy);
|
||||
|
||||
void handleBlockToggled(Buddy *buddy);
|
||||
|
||||
void handleVCardUpdated(User *user, boost::shared_ptr<Swift::VCard> vcard);
|
||||
void handleVCardRequired(User *user, const std::string &name, unsigned int id);
|
||||
|
||||
void handleFTStateChanged(Swift::FileTransfer::State state, const std::string &userName, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long id);
|
||||
void handleFTAccepted(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size, unsigned long ftID);
|
||||
void handleFTRejected(User *user, const std::string &buddyName, const std::string &fileName, unsigned long size);
|
||||
void handleFTDataNeeded(Backend *b, unsigned long ftid);
|
||||
|
||||
void handlePIDTerminated(unsigned long pid);
|
||||
private:
|
||||
void send(boost::shared_ptr<Swift::Connection> &, const std::string &data);
|
||||
|
||||
void pingTimeout();
|
||||
void sendPing(Backend *c);
|
||||
Backend *getFreeClient(bool acceptUsers = true, bool longRun = false, bool check = false);
|
||||
void connectWaitingUsers();
|
||||
void loginDelayFinished();
|
||||
void handleRawIQReceived(boost::shared_ptr<Swift::IQ> iq);
|
||||
void handleRawPresenceReceived(boost::shared_ptr<Swift::Presence> presence);
|
||||
|
||||
void handleStreamStart(const Swift::ProtocolHeader&) {}
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Swift::Element> element);
|
||||
#endif
|
||||
void handleStreamEnd() {}
|
||||
|
||||
UserManager *m_userManager;
|
||||
VCardResponder *m_vcardResponder;
|
||||
RosterResponder *m_rosterResponder;
|
||||
BlockResponder *m_blockResponder;
|
||||
Config *m_config;
|
||||
boost::shared_ptr<Swift::ConnectionServer> m_server;
|
||||
std::list<Backend *> m_clients;
|
||||
std::vector<unsigned long> m_pids;
|
||||
Swift::Timer::ref m_pingTimer;
|
||||
Swift::Timer::ref m_collectTimer;
|
||||
Swift::Timer::ref m_loginTimer;
|
||||
Component *m_component;
|
||||
std::list<User *> m_waitingUsers;
|
||||
bool m_isNextLongRun;
|
||||
std::map<unsigned long, FileTransferManager::Transfer> m_filetransfers;
|
||||
FileTransferManager *m_ftManager;
|
||||
std::vector<std::string> m_crashedBackends;
|
||||
AdminInterface *m_adminInterface;
|
||||
bool m_startingBackend;
|
||||
DiscoItemsResponder *m_discoItemsResponder;
|
||||
time_t m_lastLogin;
|
||||
Swift::XMPPParser *m_xmppParser;
|
||||
Swift::FullPayloadParserFactoryCollection m_collection;
|
||||
Swift::XMPPSerializer *m_serializer;
|
||||
Swift::FullPayloadSerializerCollection m_collection2;
|
||||
std::map <std::string, std::string> m_id2resource;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,77 +1,77 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
class UserManager;
|
||||
class StorageBackend;
|
||||
|
||||
class SettingsAdHocCommand : public AdHocCommand {
|
||||
public:
|
||||
typedef enum { Init, WaitingForResponse } State;
|
||||
|
||||
SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~SettingsAdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Swift::Command> getForm();
|
||||
boost::shared_ptr<Swift::Command> handleResponse(boost::shared_ptr<Swift::Command> payload);
|
||||
State m_state;
|
||||
};
|
||||
|
||||
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
|
||||
public:
|
||||
SettingsAdHocCommandFactory() {
|
||||
m_userSettings["send_headlines"] = "0";
|
||||
m_userSettings["stay_connected"] = "0";
|
||||
}
|
||||
|
||||
virtual ~SettingsAdHocCommandFactory() {}
|
||||
|
||||
AdHocCommand *createAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
return new SettingsAdHocCommand(component, userManager, storageBackend, initiator, to);
|
||||
}
|
||||
|
||||
std::string getNode() {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return "Transport settings";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include "transport/adhoccommand.h"
|
||||
#include "transport/adhoccommandfactory.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Component;
|
||||
class UserManager;
|
||||
class StorageBackend;
|
||||
|
||||
class SettingsAdHocCommand : public AdHocCommand {
|
||||
public:
|
||||
typedef enum { Init, WaitingForResponse } State;
|
||||
|
||||
SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to);
|
||||
|
||||
/// Destructor.
|
||||
virtual ~SettingsAdHocCommand();
|
||||
|
||||
virtual boost::shared_ptr<Swift::Command> handleRequest(boost::shared_ptr<Swift::Command> payload);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Swift::Command> getForm();
|
||||
boost::shared_ptr<Swift::Command> handleResponse(boost::shared_ptr<Swift::Command> payload);
|
||||
State m_state;
|
||||
};
|
||||
|
||||
class SettingsAdHocCommandFactory : public AdHocCommandFactory {
|
||||
public:
|
||||
SettingsAdHocCommandFactory() {
|
||||
m_userSettings["send_headlines"] = "0";
|
||||
m_userSettings["stay_connected"] = "0";
|
||||
}
|
||||
|
||||
virtual ~SettingsAdHocCommandFactory() {}
|
||||
|
||||
AdHocCommand *createAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) {
|
||||
return new SettingsAdHocCommand(component, userManager, storageBackend, initiator, to);
|
||||
}
|
||||
|
||||
std::string getNode() {
|
||||
return "settings";
|
||||
}
|
||||
|
||||
std::string getName() {
|
||||
return "Transport settings";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Swiften/Queries/Responder.h"
|
||||
#include "Swiften/Elements/InBandRegistrationPayload.h"
|
||||
#include "Swiften/Elements/RosterPayload.h"
|
||||
#include <boost/signal.hpp>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Transport {
|
||||
|
||||
struct UserInfo;
|
||||
class Component;
|
||||
class StorageBackend;
|
||||
class UserManager;
|
||||
class Config;
|
||||
|
||||
/// Allows users to register the transport using service discovery.
|
||||
class UserRegistration : public Swift::Responder<Swift::InBandRegistrationPayload> {
|
||||
public:
|
||||
/// Creates new UserRegistration handler.
|
||||
/// \param component Component associated with this class
|
||||
/// \param userManager UserManager associated with this class
|
||||
/// \param storageBackend StorageBackend where the registered users will be stored
|
||||
UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend);
|
||||
|
||||
/// Destroys UserRegistration.
|
||||
~UserRegistration();
|
||||
|
||||
/// Registers new user. This function stores user into database and subscribe user to transport.
|
||||
/// \param userInfo UserInfo struct with informations about registered user
|
||||
/// \return false if user is already registered
|
||||
bool registerUser(const UserInfo &userInfo);
|
||||
|
||||
/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
|
||||
/// managed by this transport and disconnects user if he's connected.
|
||||
/// \param barejid bare JID of user to unregister
|
||||
/// \return false if there is no such user registered
|
||||
bool unregisterUser(const std::string &barejid);
|
||||
|
||||
/// Called when new user has been registered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserRegistered;
|
||||
|
||||
/// Called when user has been unregistered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUnregistered;
|
||||
|
||||
/// Called when user's registration has been updated.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUpdated;
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
|
||||
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
|
||||
|
||||
void handleRegisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const UserInfo &row);
|
||||
void handleUnregisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const std::string &barejid);
|
||||
|
||||
Component *m_component;
|
||||
StorageBackend *m_storageBackend;
|
||||
UserManager *m_userManager;
|
||||
Config *m_config;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Swiften/Queries/Responder.h"
|
||||
#include "Swiften/Elements/InBandRegistrationPayload.h"
|
||||
#include "Swiften/Elements/RosterPayload.h"
|
||||
#include <boost/signal.hpp>
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
namespace Transport {
|
||||
|
||||
struct UserInfo;
|
||||
class Component;
|
||||
class StorageBackend;
|
||||
class UserManager;
|
||||
class Config;
|
||||
|
||||
/// Allows users to register the transport using service discovery.
|
||||
class UserRegistration : public Swift::Responder<Swift::InBandRegistrationPayload> {
|
||||
public:
|
||||
/// Creates new UserRegistration handler.
|
||||
/// \param component Component associated with this class
|
||||
/// \param userManager UserManager associated with this class
|
||||
/// \param storageBackend StorageBackend where the registered users will be stored
|
||||
UserRegistration(Component *component, UserManager *userManager, StorageBackend *storageBackend);
|
||||
|
||||
/// Destroys UserRegistration.
|
||||
~UserRegistration();
|
||||
|
||||
/// Registers new user. This function stores user into database and subscribe user to transport.
|
||||
/// \param userInfo UserInfo struct with informations about registered user
|
||||
/// \return false if user is already registered
|
||||
bool registerUser(const UserInfo &userInfo);
|
||||
|
||||
/// Unregisters user. This function removes all data about user from databa, unsubscribe all buddies
|
||||
/// managed by this transport and disconnects user if he's connected.
|
||||
/// \param barejid bare JID of user to unregister
|
||||
/// \return false if there is no such user registered
|
||||
bool unregisterUser(const std::string &barejid);
|
||||
|
||||
/// Called when new user has been registered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserRegistered;
|
||||
|
||||
/// Called when user has been unregistered.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUnregistered;
|
||||
|
||||
/// Called when user's registration has been updated.
|
||||
/// \param userInfo UserInfo struct with informations about user
|
||||
boost::signal<void (const UserInfo &userInfo)> onUserUpdated;
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
|
||||
virtual bool handleSetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::InBandRegistrationPayload> payload);
|
||||
|
||||
void handleRegisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const UserInfo &row);
|
||||
void handleUnregisterRemoteRosterResponse(boost::shared_ptr<Swift::RosterPayload> payload, Swift::ErrorPayload::ref error, const std::string &barejid);
|
||||
|
||||
Component *m_component;
|
||||
StorageBackend *m_storageBackend;
|
||||
UserManager *m_userManager;
|
||||
Config *m_config;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
ADD_SUBDIRECTORY(sqlite3)
|
||||
ADD_SUBDIRECTORY(sqlite3)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SQLITE_SRC *.c *.h)
|
||||
|
||||
ADD_LIBRARY(sqlite3 STATIC ${HEADERS} ${SQLITE_SRC})
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SQLITE_SRC *.c *.h)
|
||||
|
||||
ADD_LIBRARY(sqlite3 STATIC ${HEADERS} ${SQLITE_SRC})
|
||||
|
||||
INSTALL(TARGETS sqlite3 LIBRARY DESTINATION lib ARCHIVE DESTINATION lib COMPONENT libraries)
|
|
@ -1,38 +1,38 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB HEADERS ../include/transport/*.h)
|
||||
|
||||
set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/memoryusage.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/logging.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/config.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/util.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
|
||||
|
||||
if (NOT WIN32)
|
||||
ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
|
||||
else()
|
||||
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${EXTRA_SOURCES} )
|
||||
endif()
|
||||
ADD_DEPENDENCIES(transport-plugin pb)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib)
|
||||
endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
|
||||
|
||||
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc")
|
||||
#INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc" DESTINATION lib/pkgconfig)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.h)
|
||||
FILE(GLOB HEADERS ../include/transport/*.h)
|
||||
|
||||
set(EXTRA_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/../../src/memoryusage.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/logging.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/config.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../src/util.cpp)
|
||||
set(EXTRA_SOURCES ${EXTRA_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
|
||||
|
||||
if (NOT WIN32)
|
||||
ADD_LIBRARY(transport-plugin SHARED ${HEADERS} ${SRC} ${PROTOBUF_SRC} ${PROTOBUF_HDRS} ${EXTRA_SOURCES})
|
||||
else()
|
||||
ADD_LIBRARY(transport-plugin STATIC ${HEADERS} ${SRC} ${EXTRA_SOURCES} )
|
||||
endif()
|
||||
ADD_DEPENDENCIES(transport-plugin pb)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
|
||||
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
if (NOT WIN32)
|
||||
ADD_DEFINITIONS(-fPIC)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT WIN32)
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES})
|
||||
else()
|
||||
TARGET_LINK_LIBRARIES(transport-plugin ${PROTOBUF_LIBRARY} ${LOG4CXX_LIBRARIES} ${Boost_LIBRARIES} ws2_32.lib)
|
||||
endif()
|
||||
|
||||
SET_TARGET_PROPERTIES(transport-plugin PROPERTIES
|
||||
VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION}
|
||||
)
|
||||
|
||||
INSTALL(TARGETS transport-plugin LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries)
|
||||
|
||||
#CONFIGURE_FILE(transport.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc")
|
||||
#INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/transport.pc" DESTINATION lib/pkgconfig)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
if (PROTOBUF_FOUND)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
COMMENT "Running Python protocol buffer compiler on protocol.proto"
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
)
|
||||
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
|
||||
if (PROTOBUF_FOUND)
|
||||
ADD_CUSTOM_COMMAND(
|
||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py
|
||||
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE} --python_out ${CMAKE_CURRENT_SOURCE_DIR} --proto_path ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/ ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
COMMENT "Running Python protocol buffer compiler on protocol.proto"
|
||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.proto
|
||||
)
|
||||
ADD_CUSTOM_TARGET(pb-python ALL DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/protocol_pb2.py)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,48 +1,48 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
if (WIN32)
|
||||
FILE(GLOB WIN_SRC win32/*.cpp)
|
||||
include_directories(win32)
|
||||
include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3")
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
|
||||
else()
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
ADD_DEPENDENCIES(spectrum2 spectrum2_libpurple_backend)
|
||||
ADD_DEPENDENCIES(spectrum2 spectrum2_libircclient-qt_backend)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(spectrum2 transport sqlite3 ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
|
||||
else ()
|
||||
target_link_libraries(spectrum2 transport ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2 RUNTIME DESTINATION bin)
|
||||
|
||||
INSTALL(FILES
|
||||
sample2_gateway.cfg
|
||||
RENAME spectrum.cfg.example
|
||||
DESTINATION /etc/spectrum2/transports
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
sample2.cfg
|
||||
RENAME spectrum_server_mode.cfg.example
|
||||
DESTINATION /etc/spectrum2/transports
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
backend-logging.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
logging.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
|
||||
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp)
|
||||
|
||||
if (WIN32)
|
||||
FILE(GLOB WIN_SRC win32/*.cpp)
|
||||
include_directories(win32)
|
||||
include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3")
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC} ${WIN_SRC})
|
||||
else()
|
||||
ADD_EXECUTABLE(spectrum2 ${SRC})
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
ADD_DEPENDENCIES(spectrum2 spectrum2_libpurple_backend)
|
||||
ADD_DEPENDENCIES(spectrum2 spectrum2_libircclient-qt_backend)
|
||||
|
||||
if (WIN32)
|
||||
target_link_libraries(spectrum2 transport sqlite3 ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
|
||||
else ()
|
||||
target_link_libraries(spectrum2 transport ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY})
|
||||
endif()
|
||||
|
||||
INSTALL(TARGETS spectrum2 RUNTIME DESTINATION bin)
|
||||
|
||||
INSTALL(FILES
|
||||
sample2_gateway.cfg
|
||||
RENAME spectrum.cfg.example
|
||||
DESTINATION /etc/spectrum2/transports
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
sample2.cfg
|
||||
RENAME spectrum_server_mode.cfg.example
|
||||
DESTINATION /etc/spectrum2/transports
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
backend-logging.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
|
||||
INSTALL(FILES
|
||||
logging.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.c)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp ../../src/util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
FILE(GLOB SRC *.cpp *.c)
|
||||
|
||||
ADD_EXECUTABLE(spectrum2_manager ${SRC} ../../src/config.cpp ../../src/util.cpp ${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc)
|
||||
|
||||
ADD_DEPENDENCIES(spectrum2_manager pb)
|
||||
SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1)
|
||||
|
||||
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
|
||||
target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES})
|
||||
|
||||
if(APPLE)
|
||||
target_link_libraries(spectrum2_manager ${APPLE_FRAMEWORKS})
|
||||
endif()
|
||||
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
|
||||
|
||||
INSTALL(FILES
|
||||
spectrum_manager.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin)
|
||||
|
||||
INSTALL(FILES
|
||||
spectrum_manager.cfg
|
||||
DESTINATION /etc/spectrum2
|
||||
)
|
||||
|
|
|
@ -1,200 +1,200 @@
|
|||
#include "managerconfig.h"
|
||||
#include "methods.h"
|
||||
#include "server.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/protocol.pb.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdlib>
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
// static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) {
|
||||
// path p(CONFIG_STRING(config, "service.config_directory"));
|
||||
//
|
||||
// try {
|
||||
// if (!exists(p)) {
|
||||
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
// exit(6);
|
||||
// }
|
||||
//
|
||||
// if (!is_directory(p)) {
|
||||
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
// exit(7);
|
||||
// }
|
||||
//
|
||||
// directory_iterator end_itr;
|
||||
// for (directory_iterator itr(p); itr != end_itr; ++itr) {
|
||||
// if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
|
||||
// Config cfg;
|
||||
// if (cfg.load(itr->path().string()) == false) {
|
||||
// std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
|
||||
// std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// finished++;
|
||||
// Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
|
||||
// client->setAlwaysTrustCertificates();
|
||||
// client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// Swift::ClientOptions opt;
|
||||
// opt.allowPLAINWithoutTLS = true;
|
||||
// client->connect(opt);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (const filesystem_error& ex) {
|
||||
// std::cerr << "boost filesystem error\n";
|
||||
// exit(5);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ManagerConfig config;
|
||||
std::string config_file;
|
||||
std::vector<std::string> command;
|
||||
boost::program_options::variables_map vm;
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\n"
|
||||
" spectrum [OPTIONS] <instance_JID> <other>\nCommands:\n"
|
||||
" start - start all local Spectrum2 instances\n"
|
||||
" stop - stop all local Spectrum2 instances\n"
|
||||
" restart - restart all local Spectrum2 instances\n"
|
||||
" status - status of local Spectrum2 instances\n"
|
||||
" <other> - send command to local Spectrum2 instance and print output\n"
|
||||
"Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "Show help output")
|
||||
("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file")
|
||||
("command", boost::program_options::value<std::vector<std::string> >(&command), "Command")
|
||||
;
|
||||
try
|
||||
{
|
||||
boost::program_options::positional_options_description p;
|
||||
p.add("command", -1);
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
if(vm.count("help"))
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 2;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (!config.load(config_file)) {
|
||||
std::cerr << "Can't load configuration file.\n";
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (command.empty()) {
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (command[0] == "start") {
|
||||
return start_instances(&config);
|
||||
}
|
||||
else if (command[0] == "stop") {
|
||||
stop_instances(&config);
|
||||
}
|
||||
else if (command[0] == "status") {
|
||||
return show_status(&config);
|
||||
}
|
||||
else if (command[0] == "list") {
|
||||
std::vector<std::string> list = show_list(&config);
|
||||
}
|
||||
else if (command[0] == "restart") {
|
||||
return restart_instances(&config);
|
||||
}
|
||||
else if (command[0] == "server") {
|
||||
Server server(&config);
|
||||
if (server.start() == false) {
|
||||
std::cerr << "Can't set up server handler.\n";
|
||||
return 1;
|
||||
}
|
||||
while (1) { sleep(10); }
|
||||
}
|
||||
else {
|
||||
if (command.size() < 2) {
|
||||
std::cout << desc << "\n";
|
||||
return 11;
|
||||
}
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Swift::BoostNetworkFactories networkFactories(&eventLoop);
|
||||
|
||||
std::string jid = command[0];
|
||||
command.erase(command.begin());
|
||||
std::string cmd = boost::algorithm::join(command, " ");
|
||||
|
||||
if (cmd == "start") {
|
||||
return start_instances(&config, jid);
|
||||
}
|
||||
else if (cmd == "stop") {
|
||||
stop_instances(&config, jid);
|
||||
return 0;
|
||||
}
|
||||
else if (cmd == "restart") {
|
||||
return restart_instances(&config, jid);
|
||||
}
|
||||
|
||||
ask_local_server(&config, networkFactories, jid, cmd);
|
||||
// std::string message = command;
|
||||
// m = &message;
|
||||
|
||||
// ask_local_server(&config, networkFactories, message);
|
||||
|
||||
eventLoop.runUntilEvents();
|
||||
|
||||
|
||||
struct timeval td_start,td_end;
|
||||
float elapsed = 0;
|
||||
gettimeofday(&td_start, NULL);
|
||||
|
||||
time_t started = time(NULL);
|
||||
while(get_response().empty()) {
|
||||
eventLoop.runUntilEvents();
|
||||
}
|
||||
if (!get_response().empty()) {
|
||||
gettimeofday(&td_end, NULL);
|
||||
elapsed = 1000000.0 * (td_end.tv_sec -td_start.tv_sec); \
|
||||
elapsed += (td_end.tv_usec - td_start.tv_usec); \
|
||||
elapsed = elapsed / 1000 / 1000; \
|
||||
// std::cout << "Response received after " << (elapsed) << " seconds\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#include "managerconfig.h"
|
||||
#include "methods.h"
|
||||
#include "server.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/protocol.pb.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/EventLoop/SimpleEventLoop.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <cstdlib>
|
||||
#include "signal.h"
|
||||
#include "sys/wait.h"
|
||||
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
using namespace boost::filesystem;
|
||||
|
||||
using namespace boost;
|
||||
|
||||
|
||||
// static void ask_local_servers(ManagerConfig *config, Swift::BoostNetworkFactories &networkFactories, const std::string &message) {
|
||||
// path p(CONFIG_STRING(config, "service.config_directory"));
|
||||
//
|
||||
// try {
|
||||
// if (!exists(p)) {
|
||||
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
// exit(6);
|
||||
// }
|
||||
//
|
||||
// if (!is_directory(p)) {
|
||||
// std::cerr << "Config directory " << CONFIG_STRING(config, "service.config_directory") << " does not exist\n";
|
||||
// exit(7);
|
||||
// }
|
||||
//
|
||||
// directory_iterator end_itr;
|
||||
// for (directory_iterator itr(p); itr != end_itr; ++itr) {
|
||||
// if (is_regular(itr->path()) && extension(itr->path()) == ".cfg") {
|
||||
// Config cfg;
|
||||
// if (cfg.load(itr->path().string()) == false) {
|
||||
// std::cerr << "Can't load config file " << itr->path().string() << ". Skipping...\n";
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// if (CONFIG_VECTOR(&cfg, "service.admin_jid").empty() || CONFIG_STRING(&cfg, "service.admin_password").empty()) {
|
||||
// std::cerr << itr->path().string() << ": service.admin_jid or service.admin_password empty. This server can't be queried over XMPP.\n";
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// finished++;
|
||||
// Swift::Client *client = new Swift::Client(CONFIG_VECTOR(&cfg, "service.admin_jid")[0], CONFIG_STRING(&cfg, "service.admin_password"), &networkFactories);
|
||||
// client->setAlwaysTrustCertificates();
|
||||
// client->onConnected.connect(boost::bind(&handleConnected, client, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// client->onDisconnected.connect(bind(&handleDisconnected, client, _1, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// client->onMessageReceived.connect(bind(&handleMessageReceived, client, _1, CONFIG_STRING(&cfg, "service.jid")));
|
||||
// Swift::ClientOptions opt;
|
||||
// opt.allowPLAINWithoutTLS = true;
|
||||
// client->connect(opt);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// catch (const filesystem_error& ex) {
|
||||
// std::cerr << "boost filesystem error\n";
|
||||
// exit(5);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ManagerConfig config;
|
||||
std::string config_file;
|
||||
std::vector<std::string> command;
|
||||
boost::program_options::variables_map vm;
|
||||
|
||||
boost::program_options::options_description desc("Usage: spectrum [OPTIONS] <COMMAND>\n"
|
||||
" spectrum [OPTIONS] <instance_JID> <other>\nCommands:\n"
|
||||
" start - start all local Spectrum2 instances\n"
|
||||
" stop - stop all local Spectrum2 instances\n"
|
||||
" restart - restart all local Spectrum2 instances\n"
|
||||
" status - status of local Spectrum2 instances\n"
|
||||
" <other> - send command to local Spectrum2 instance and print output\n"
|
||||
"Allowed options");
|
||||
desc.add_options()
|
||||
("help,h", "Show help output")
|
||||
("config,c", boost::program_options::value<std::string>(&config_file)->default_value("/etc/spectrum2/spectrum_manager.cfg"), "Spectrum manager config file")
|
||||
("command", boost::program_options::value<std::vector<std::string> >(&command), "Command")
|
||||
;
|
||||
try
|
||||
{
|
||||
boost::program_options::positional_options_description p;
|
||||
p.add("command", -1);
|
||||
boost::program_options::store(boost::program_options::command_line_parser(argc, argv).
|
||||
options(desc).positional(p).run(), vm);
|
||||
boost::program_options::notify(vm);
|
||||
|
||||
if(vm.count("help"))
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
catch (std::runtime_error& e)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 2;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
std::cout << desc << "\n";
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (!config.load(config_file)) {
|
||||
std::cerr << "Can't load configuration file.\n";
|
||||
return 4;
|
||||
}
|
||||
|
||||
if (command.empty()) {
|
||||
std::cout << desc << "\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (command[0] == "start") {
|
||||
return start_instances(&config);
|
||||
}
|
||||
else if (command[0] == "stop") {
|
||||
stop_instances(&config);
|
||||
}
|
||||
else if (command[0] == "status") {
|
||||
return show_status(&config);
|
||||
}
|
||||
else if (command[0] == "list") {
|
||||
std::vector<std::string> list = show_list(&config);
|
||||
}
|
||||
else if (command[0] == "restart") {
|
||||
return restart_instances(&config);
|
||||
}
|
||||
else if (command[0] == "server") {
|
||||
Server server(&config);
|
||||
if (server.start() == false) {
|
||||
std::cerr << "Can't set up server handler.\n";
|
||||
return 1;
|
||||
}
|
||||
while (1) { sleep(10); }
|
||||
}
|
||||
else {
|
||||
if (command.size() < 2) {
|
||||
std::cout << desc << "\n";
|
||||
return 11;
|
||||
}
|
||||
Swift::SimpleEventLoop eventLoop;
|
||||
Swift::BoostNetworkFactories networkFactories(&eventLoop);
|
||||
|
||||
std::string jid = command[0];
|
||||
command.erase(command.begin());
|
||||
std::string cmd = boost::algorithm::join(command, " ");
|
||||
|
||||
if (cmd == "start") {
|
||||
return start_instances(&config, jid);
|
||||
}
|
||||
else if (cmd == "stop") {
|
||||
stop_instances(&config, jid);
|
||||
return 0;
|
||||
}
|
||||
else if (cmd == "restart") {
|
||||
return restart_instances(&config, jid);
|
||||
}
|
||||
|
||||
ask_local_server(&config, networkFactories, jid, cmd);
|
||||
// std::string message = command;
|
||||
// m = &message;
|
||||
|
||||
// ask_local_server(&config, networkFactories, message);
|
||||
|
||||
eventLoop.runUntilEvents();
|
||||
|
||||
|
||||
struct timeval td_start,td_end;
|
||||
float elapsed = 0;
|
||||
gettimeofday(&td_start, NULL);
|
||||
|
||||
time_t started = time(NULL);
|
||||
while(get_response().empty()) {
|
||||
eventLoop.runUntilEvents();
|
||||
}
|
||||
if (!get_response().empty()) {
|
||||
gettimeofday(&td_end, NULL);
|
||||
elapsed = 1000000.0 * (td_end.tv_sec -td_start.tv_sec); \
|
||||
elapsed += (td_end.tv_usec - td_start.tv_usec); \
|
||||
elapsed = elapsed / 1000 / 1000; \
|
||||
// std::cout << "Response received after " << (elapsed) << " seconds\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,301 +1,301 @@
|
|||
// Copyright (c) 2004-2012 Sergey Lyubka
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef MONGOOSE_HEADER_INCLUDED
|
||||
#define MONGOOSE_HEADER_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct mg_context; // Handle for the HTTP service itself
|
||||
struct mg_connection; // Handle for the individual connection
|
||||
|
||||
|
||||
// This structure contains information about the HTTP request.
|
||||
struct mg_request_info {
|
||||
void *user_data; // User-defined pointer passed to mg_start()
|
||||
char *request_method; // "GET", "POST", etc
|
||||
char *uri; // URL-decoded URI
|
||||
char *http_version; // E.g. "1.0", "1.1"
|
||||
char *query_string; // URL part after '?' (not including '?') or NULL
|
||||
char *remote_user; // Authenticated user, or NULL if no auth used
|
||||
char *log_message; // Mongoose error log message, MG_EVENT_LOG only
|
||||
long remote_ip; // Client's IP address
|
||||
int remote_port; // Client's port
|
||||
int status_code; // HTTP reply status code, e.g. 200
|
||||
int is_ssl; // 1 if SSL-ed, 0 if not
|
||||
int num_headers; // Number of headers
|
||||
struct mg_header {
|
||||
char *name; // HTTP header name
|
||||
char *value; // HTTP header value
|
||||
} http_headers[64]; // Maximum 64 headers
|
||||
};
|
||||
|
||||
// Various events on which user-defined function is called by Mongoose.
|
||||
enum mg_event {
|
||||
MG_NEW_REQUEST, // New HTTP request has arrived from the client
|
||||
MG_REQUEST_COMPLETE, // Mongoose has finished handling the request
|
||||
MG_HTTP_ERROR, // HTTP error must be returned to the client
|
||||
MG_EVENT_LOG, // Mongoose logs an event, request_info.log_message
|
||||
MG_INIT_SSL // Mongoose initializes SSL. Instead of mg_connection *,
|
||||
// SSL context is passed to the callback function.
|
||||
};
|
||||
|
||||
// Prototype for the user-defined function. Mongoose calls this function
|
||||
// on every MG_* event.
|
||||
//
|
||||
// Parameters:
|
||||
// event: which event has been triggered.
|
||||
// conn: opaque connection handler. Could be used to read, write data to the
|
||||
// client, etc. See functions below that have "mg_connection *" arg.
|
||||
//
|
||||
// Return:
|
||||
// If handler returns non-NULL, that means that handler has processed the
|
||||
// request by sending appropriate HTTP reply to the client. Mongoose treats
|
||||
// the request as served.
|
||||
// If handler returns NULL, that means that handler has not processed
|
||||
// the request. Handler must not send any data to the client in this case.
|
||||
// Mongoose proceeds with request handling as if nothing happened.
|
||||
typedef void * (*mg_callback_t)(enum mg_event event,
|
||||
struct mg_connection *conn);
|
||||
|
||||
|
||||
// Start web server.
|
||||
//
|
||||
// Parameters:
|
||||
// callback: user defined event handling function or NULL.
|
||||
// options: NULL terminated list of option_name, option_value pairs that
|
||||
// specify Mongoose configuration parameters.
|
||||
//
|
||||
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
|
||||
// processing is required for these, signal handlers must be set up
|
||||
// after calling mg_start().
|
||||
//
|
||||
//
|
||||
// Example:
|
||||
// const char *options[] = {
|
||||
// "document_root", "/var/www",
|
||||
// "listening_ports", "80,443s",
|
||||
// NULL
|
||||
// };
|
||||
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
|
||||
//
|
||||
// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
|
||||
// for the list of valid option and their possible values.
|
||||
//
|
||||
// Return:
|
||||
// web server context, or NULL on error.
|
||||
struct mg_context *mg_start(mg_callback_t callback, void *user_data,
|
||||
const char **options);
|
||||
|
||||
|
||||
// Stop the web server.
|
||||
//
|
||||
// Must be called last, when an application wants to stop the web server and
|
||||
// release all associated resources. This function blocks until all Mongoose
|
||||
// threads are stopped. Context pointer becomes invalid.
|
||||
void mg_stop(struct mg_context *);
|
||||
|
||||
|
||||
// Get the value of particular configuration parameter.
|
||||
// The value returned is read-only. Mongoose does not allow changing
|
||||
// configuration at run time.
|
||||
// If given parameter name is not valid, NULL is returned. For valid
|
||||
// names, return value is guaranteed to be non-NULL. If parameter is not
|
||||
// set, zero-length string is returned.
|
||||
const char *mg_get_option(const struct mg_context *ctx, const char *name);
|
||||
|
||||
|
||||
// Return array of strings that represent valid configuration options.
|
||||
// For each option, a short name, long name, and default value is returned.
|
||||
// Array is NULL terminated.
|
||||
const char **mg_get_valid_option_names(void);
|
||||
|
||||
|
||||
// Add, edit or delete the entry in the passwords file.
|
||||
//
|
||||
// This function allows an application to manipulate .htpasswd files on the
|
||||
// fly by adding, deleting and changing user records. This is one of the
|
||||
// several ways of implementing authentication on the server side. For another,
|
||||
// cookie-based way please refer to the examples/chat.c in the source tree.
|
||||
//
|
||||
// If password is not NULL, entry is added (or modified if already exists).
|
||||
// If password is NULL, entry is deleted.
|
||||
//
|
||||
// Return:
|
||||
// 1 on success, 0 on error.
|
||||
int mg_modify_passwords_file(const char *passwords_file_name,
|
||||
const char *domain,
|
||||
const char *user,
|
||||
const char *password);
|
||||
|
||||
|
||||
// Return mg_request_info structure associated with the request.
|
||||
// Always succeeds.
|
||||
const struct mg_request_info *mg_get_request_info(const struct mg_connection *);
|
||||
|
||||
|
||||
// Send data to the client.
|
||||
// Return:
|
||||
// 0 when the connection has been closed
|
||||
// -1 on error
|
||||
// number of bytes written on success
|
||||
int mg_write(struct mg_connection *, const void *buf, size_t len);
|
||||
|
||||
|
||||
// Send data to the browser using printf() semantics.
|
||||
//
|
||||
// Works exactly like mg_write(), but allows to do message formatting.
|
||||
// Below are the macros for enabling compiler-specific checks for
|
||||
// printf-like arguments.
|
||||
|
||||
#undef PRINTF_FORMAT_STRING
|
||||
#if _MSC_VER >= 1400
|
||||
#include <sal.h>
|
||||
#if _MSC_VER > 1400
|
||||
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) __format_string s
|
||||
#endif
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) s
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
|
||||
#else
|
||||
#define PRINTF_ARGS(x, y)
|
||||
#endif
|
||||
|
||||
int mg_printf(struct mg_connection *,
|
||||
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||
|
||||
|
||||
// Send contents of the entire file together with HTTP headers.
|
||||
void mg_send_file(struct mg_connection *conn, const char *path);
|
||||
|
||||
|
||||
// Read data from the remote end, return number of bytes read.
|
||||
int mg_read(struct mg_connection *, void *buf, size_t len);
|
||||
|
||||
|
||||
// Get the value of particular HTTP header.
|
||||
//
|
||||
// This is a helper function. It traverses request_info->http_headers array,
|
||||
// and if the header is present in the array, returns its value. If it is
|
||||
// not present, NULL is returned.
|
||||
const char *mg_get_header(const struct mg_connection *, const char *name);
|
||||
|
||||
|
||||
// Get a value of particular form variable.
|
||||
//
|
||||
// Parameters:
|
||||
// data: pointer to form-uri-encoded buffer. This could be either POST data,
|
||||
// or request_info.query_string.
|
||||
// data_len: length of the encoded data.
|
||||
// var_name: variable name to decode from the buffer
|
||||
// buf: destination buffer for the decoded variable
|
||||
// buf_len: length of the destination buffer
|
||||
//
|
||||
// Return:
|
||||
// On success, length of the decoded variable.
|
||||
// On error:
|
||||
// -1 (variable not found, or destination buffer is too small).
|
||||
// -2 (destination buffer is NULL or zero length).
|
||||
//
|
||||
// Destination buffer is guaranteed to be '\0' - terminated if it is not
|
||||
// NULL or zero length. In case of failure, dst[0] == '\0'.
|
||||
int mg_get_var(const char *data, size_t data_len,
|
||||
const char *var_name, char *buf, size_t buf_len);
|
||||
|
||||
// Fetch value of certain cookie variable into the destination buffer.
|
||||
//
|
||||
// Destination buffer is guaranteed to be '\0' - terminated. In case of
|
||||
// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
|
||||
// parameter. This function returns only first occurrence.
|
||||
//
|
||||
// Return:
|
||||
// On success, value length.
|
||||
// On error, -1 (either "Cookie:" header is not present at all, or the
|
||||
// requested parameter is not found, or destination buffer is too small
|
||||
// to hold the value).
|
||||
int mg_get_cookie(const struct mg_connection *,
|
||||
const char *cookie_name, char *buf, size_t buf_len);
|
||||
|
||||
|
||||
// Connect to the remote web server.
|
||||
// Return:
|
||||
// On success, valid pointer to the new connection
|
||||
// On error, NULL
|
||||
struct mg_connection *mg_connect(struct mg_context *ctx,
|
||||
const char *host, int port, int use_ssl);
|
||||
|
||||
|
||||
// Close the connection opened by mg_connect().
|
||||
void mg_close_connection(struct mg_connection *conn);
|
||||
|
||||
|
||||
// Download given URL to a given file.
|
||||
// url: URL to download
|
||||
// path: file name where to save the data
|
||||
// request_info: pointer to a structure that will hold parsed reply headers
|
||||
// buf, bul_len: a buffer for the reply headers
|
||||
// Return:
|
||||
// On error, NULL
|
||||
// On success, opened file stream to the downloaded contents. The stream
|
||||
// is positioned to the end of the file. It is the user's responsibility
|
||||
// to fclose() the opened file stream.
|
||||
FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
|
||||
char *buf, size_t buf_len, struct mg_request_info *request_info);
|
||||
|
||||
|
||||
// Convenience function -- create detached thread.
|
||||
// Return: 0 on success, non-0 on error.
|
||||
typedef void * (*mg_thread_func_t)(void *);
|
||||
int mg_start_thread(mg_thread_func_t f, void *p);
|
||||
|
||||
|
||||
// Return builtin mime type for the given file name.
|
||||
// For unrecognized extensions, "text/plain" is returned.
|
||||
const char *mg_get_builtin_mime_type(const char *file_name);
|
||||
|
||||
|
||||
// Return Mongoose version.
|
||||
const char *mg_version(void);
|
||||
|
||||
|
||||
// MD5 hash given strings.
|
||||
// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
|
||||
// ASCIIz strings. When function returns, buf will contain human-readable
|
||||
// MD5 hash. Example:
|
||||
// char buf[33];
|
||||
// mg_md5(buf, "aa", "bb", NULL);
|
||||
void mg_md5(char buf[33], ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // MONGOOSE_HEADER_INCLUDED
|
||||
// Copyright (c) 2004-2012 Sergey Lyubka
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
#ifndef MONGOOSE_HEADER_INCLUDED
|
||||
#define MONGOOSE_HEADER_INCLUDED
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
struct mg_context; // Handle for the HTTP service itself
|
||||
struct mg_connection; // Handle for the individual connection
|
||||
|
||||
|
||||
// This structure contains information about the HTTP request.
|
||||
struct mg_request_info {
|
||||
void *user_data; // User-defined pointer passed to mg_start()
|
||||
char *request_method; // "GET", "POST", etc
|
||||
char *uri; // URL-decoded URI
|
||||
char *http_version; // E.g. "1.0", "1.1"
|
||||
char *query_string; // URL part after '?' (not including '?') or NULL
|
||||
char *remote_user; // Authenticated user, or NULL if no auth used
|
||||
char *log_message; // Mongoose error log message, MG_EVENT_LOG only
|
||||
long remote_ip; // Client's IP address
|
||||
int remote_port; // Client's port
|
||||
int status_code; // HTTP reply status code, e.g. 200
|
||||
int is_ssl; // 1 if SSL-ed, 0 if not
|
||||
int num_headers; // Number of headers
|
||||
struct mg_header {
|
||||
char *name; // HTTP header name
|
||||
char *value; // HTTP header value
|
||||
} http_headers[64]; // Maximum 64 headers
|
||||
};
|
||||
|
||||
// Various events on which user-defined function is called by Mongoose.
|
||||
enum mg_event {
|
||||
MG_NEW_REQUEST, // New HTTP request has arrived from the client
|
||||
MG_REQUEST_COMPLETE, // Mongoose has finished handling the request
|
||||
MG_HTTP_ERROR, // HTTP error must be returned to the client
|
||||
MG_EVENT_LOG, // Mongoose logs an event, request_info.log_message
|
||||
MG_INIT_SSL // Mongoose initializes SSL. Instead of mg_connection *,
|
||||
// SSL context is passed to the callback function.
|
||||
};
|
||||
|
||||
// Prototype for the user-defined function. Mongoose calls this function
|
||||
// on every MG_* event.
|
||||
//
|
||||
// Parameters:
|
||||
// event: which event has been triggered.
|
||||
// conn: opaque connection handler. Could be used to read, write data to the
|
||||
// client, etc. See functions below that have "mg_connection *" arg.
|
||||
//
|
||||
// Return:
|
||||
// If handler returns non-NULL, that means that handler has processed the
|
||||
// request by sending appropriate HTTP reply to the client. Mongoose treats
|
||||
// the request as served.
|
||||
// If handler returns NULL, that means that handler has not processed
|
||||
// the request. Handler must not send any data to the client in this case.
|
||||
// Mongoose proceeds with request handling as if nothing happened.
|
||||
typedef void * (*mg_callback_t)(enum mg_event event,
|
||||
struct mg_connection *conn);
|
||||
|
||||
|
||||
// Start web server.
|
||||
//
|
||||
// Parameters:
|
||||
// callback: user defined event handling function or NULL.
|
||||
// options: NULL terminated list of option_name, option_value pairs that
|
||||
// specify Mongoose configuration parameters.
|
||||
//
|
||||
// Side-effects: on UNIX, ignores SIGCHLD and SIGPIPE signals. If custom
|
||||
// processing is required for these, signal handlers must be set up
|
||||
// after calling mg_start().
|
||||
//
|
||||
//
|
||||
// Example:
|
||||
// const char *options[] = {
|
||||
// "document_root", "/var/www",
|
||||
// "listening_ports", "80,443s",
|
||||
// NULL
|
||||
// };
|
||||
// struct mg_context *ctx = mg_start(&my_func, NULL, options);
|
||||
//
|
||||
// Please refer to http://code.google.com/p/mongoose/wiki/MongooseManual
|
||||
// for the list of valid option and their possible values.
|
||||
//
|
||||
// Return:
|
||||
// web server context, or NULL on error.
|
||||
struct mg_context *mg_start(mg_callback_t callback, void *user_data,
|
||||
const char **options);
|
||||
|
||||
|
||||
// Stop the web server.
|
||||
//
|
||||
// Must be called last, when an application wants to stop the web server and
|
||||
// release all associated resources. This function blocks until all Mongoose
|
||||
// threads are stopped. Context pointer becomes invalid.
|
||||
void mg_stop(struct mg_context *);
|
||||
|
||||
|
||||
// Get the value of particular configuration parameter.
|
||||
// The value returned is read-only. Mongoose does not allow changing
|
||||
// configuration at run time.
|
||||
// If given parameter name is not valid, NULL is returned. For valid
|
||||
// names, return value is guaranteed to be non-NULL. If parameter is not
|
||||
// set, zero-length string is returned.
|
||||
const char *mg_get_option(const struct mg_context *ctx, const char *name);
|
||||
|
||||
|
||||
// Return array of strings that represent valid configuration options.
|
||||
// For each option, a short name, long name, and default value is returned.
|
||||
// Array is NULL terminated.
|
||||
const char **mg_get_valid_option_names(void);
|
||||
|
||||
|
||||
// Add, edit or delete the entry in the passwords file.
|
||||
//
|
||||
// This function allows an application to manipulate .htpasswd files on the
|
||||
// fly by adding, deleting and changing user records. This is one of the
|
||||
// several ways of implementing authentication on the server side. For another,
|
||||
// cookie-based way please refer to the examples/chat.c in the source tree.
|
||||
//
|
||||
// If password is not NULL, entry is added (or modified if already exists).
|
||||
// If password is NULL, entry is deleted.
|
||||
//
|
||||
// Return:
|
||||
// 1 on success, 0 on error.
|
||||
int mg_modify_passwords_file(const char *passwords_file_name,
|
||||
const char *domain,
|
||||
const char *user,
|
||||
const char *password);
|
||||
|
||||
|
||||
// Return mg_request_info structure associated with the request.
|
||||
// Always succeeds.
|
||||
const struct mg_request_info *mg_get_request_info(const struct mg_connection *);
|
||||
|
||||
|
||||
// Send data to the client.
|
||||
// Return:
|
||||
// 0 when the connection has been closed
|
||||
// -1 on error
|
||||
// number of bytes written on success
|
||||
int mg_write(struct mg_connection *, const void *buf, size_t len);
|
||||
|
||||
|
||||
// Send data to the browser using printf() semantics.
|
||||
//
|
||||
// Works exactly like mg_write(), but allows to do message formatting.
|
||||
// Below are the macros for enabling compiler-specific checks for
|
||||
// printf-like arguments.
|
||||
|
||||
#undef PRINTF_FORMAT_STRING
|
||||
#if _MSC_VER >= 1400
|
||||
#include <sal.h>
|
||||
#if _MSC_VER > 1400
|
||||
#define PRINTF_FORMAT_STRING(s) _Printf_format_string_ s
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) __format_string s
|
||||
#endif
|
||||
#else
|
||||
#define PRINTF_FORMAT_STRING(s) s
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_ARGS(x, y) __attribute__((format(printf, x, y)))
|
||||
#else
|
||||
#define PRINTF_ARGS(x, y)
|
||||
#endif
|
||||
|
||||
int mg_printf(struct mg_connection *,
|
||||
PRINTF_FORMAT_STRING(const char *fmt), ...) PRINTF_ARGS(2, 3);
|
||||
|
||||
|
||||
// Send contents of the entire file together with HTTP headers.
|
||||
void mg_send_file(struct mg_connection *conn, const char *path);
|
||||
|
||||
|
||||
// Read data from the remote end, return number of bytes read.
|
||||
int mg_read(struct mg_connection *, void *buf, size_t len);
|
||||
|
||||
|
||||
// Get the value of particular HTTP header.
|
||||
//
|
||||
// This is a helper function. It traverses request_info->http_headers array,
|
||||
// and if the header is present in the array, returns its value. If it is
|
||||
// not present, NULL is returned.
|
||||
const char *mg_get_header(const struct mg_connection *, const char *name);
|
||||
|
||||
|
||||
// Get a value of particular form variable.
|
||||
//
|
||||
// Parameters:
|
||||
// data: pointer to form-uri-encoded buffer. This could be either POST data,
|
||||
// or request_info.query_string.
|
||||
// data_len: length of the encoded data.
|
||||
// var_name: variable name to decode from the buffer
|
||||
// buf: destination buffer for the decoded variable
|
||||
// buf_len: length of the destination buffer
|
||||
//
|
||||
// Return:
|
||||
// On success, length of the decoded variable.
|
||||
// On error:
|
||||
// -1 (variable not found, or destination buffer is too small).
|
||||
// -2 (destination buffer is NULL or zero length).
|
||||
//
|
||||
// Destination buffer is guaranteed to be '\0' - terminated if it is not
|
||||
// NULL or zero length. In case of failure, dst[0] == '\0'.
|
||||
int mg_get_var(const char *data, size_t data_len,
|
||||
const char *var_name, char *buf, size_t buf_len);
|
||||
|
||||
// Fetch value of certain cookie variable into the destination buffer.
|
||||
//
|
||||
// Destination buffer is guaranteed to be '\0' - terminated. In case of
|
||||
// failure, dst[0] == '\0'. Note that RFC allows many occurrences of the same
|
||||
// parameter. This function returns only first occurrence.
|
||||
//
|
||||
// Return:
|
||||
// On success, value length.
|
||||
// On error, -1 (either "Cookie:" header is not present at all, or the
|
||||
// requested parameter is not found, or destination buffer is too small
|
||||
// to hold the value).
|
||||
int mg_get_cookie(const struct mg_connection *,
|
||||
const char *cookie_name, char *buf, size_t buf_len);
|
||||
|
||||
|
||||
// Connect to the remote web server.
|
||||
// Return:
|
||||
// On success, valid pointer to the new connection
|
||||
// On error, NULL
|
||||
struct mg_connection *mg_connect(struct mg_context *ctx,
|
||||
const char *host, int port, int use_ssl);
|
||||
|
||||
|
||||
// Close the connection opened by mg_connect().
|
||||
void mg_close_connection(struct mg_connection *conn);
|
||||
|
||||
|
||||
// Download given URL to a given file.
|
||||
// url: URL to download
|
||||
// path: file name where to save the data
|
||||
// request_info: pointer to a structure that will hold parsed reply headers
|
||||
// buf, bul_len: a buffer for the reply headers
|
||||
// Return:
|
||||
// On error, NULL
|
||||
// On success, opened file stream to the downloaded contents. The stream
|
||||
// is positioned to the end of the file. It is the user's responsibility
|
||||
// to fclose() the opened file stream.
|
||||
FILE *mg_fetch(struct mg_context *ctx, const char *url, const char *path,
|
||||
char *buf, size_t buf_len, struct mg_request_info *request_info);
|
||||
|
||||
|
||||
// Convenience function -- create detached thread.
|
||||
// Return: 0 on success, non-0 on error.
|
||||
typedef void * (*mg_thread_func_t)(void *);
|
||||
int mg_start_thread(mg_thread_func_t f, void *p);
|
||||
|
||||
|
||||
// Return builtin mime type for the given file name.
|
||||
// For unrecognized extensions, "text/plain" is returned.
|
||||
const char *mg_get_builtin_mime_type(const char *file_name);
|
||||
|
||||
|
||||
// Return Mongoose version.
|
||||
const char *mg_version(void);
|
||||
|
||||
|
||||
// MD5 hash given strings.
|
||||
// Buffer 'buf' must be 33 bytes long. Varargs is a NULL terminated list of
|
||||
// ASCIIz strings. When function returns, buf will contain human-readable
|
||||
// MD5 hash. Example:
|
||||
// char buf[33];
|
||||
// mg_md5(buf, "aa", "bb", NULL);
|
||||
void mg_md5(char buf[33], ...);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // MONGOOSE_HEADER_INCLUDED
|
||||
|
|
|
@ -1,167 +1,167 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "discoinforesponder.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "Swiften/Disco/DiscoInfoResponder.h"
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/DiscoInfo.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/Disco/CapsInfoGenerator.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
DEFINE_LOGGER(logger, "DiscoInfoResponder");
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
|
||||
m_config = config;
|
||||
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateFeatures, this));
|
||||
m_buddyInfo = NULL;
|
||||
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
|
||||
CONFIG_STRING(m_config, "identity.category"),
|
||||
CONFIG_STRING(m_config, "identity.type")));
|
||||
#if HAVE_SWIFTEN_3
|
||||
crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
|
||||
#endif
|
||||
|
||||
updateFeatures();
|
||||
}
|
||||
|
||||
DiscoInfoResponder::~DiscoInfoResponder() {
|
||||
delete m_buddyInfo;
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::updateFeatures() {
|
||||
std::list<std::string> features2;
|
||||
features2.push_back("jabber:iq:register");
|
||||
features2.push_back("jabber:iq:gateway");
|
||||
features2.push_back("jabber:iq:private");
|
||||
features2.push_back("http://jabber.org/protocol/disco#info");
|
||||
features2.push_back("http://jabber.org/protocol/commands");
|
||||
if (CONFIG_BOOL_DEFAULTED(m_config, "features.muc", false)) {
|
||||
features2.push_back("http://jabber.org/protocol/muc");
|
||||
}
|
||||
setTransportFeatures(features2);
|
||||
|
||||
std::list<std::string> features;
|
||||
features.push_back("http://jabber.org/protocol/disco#items");
|
||||
features.push_back("http://jabber.org/protocol/disco#info");
|
||||
features.push_back("http://jabber.org/protocol/chatstates");
|
||||
features.push_back("http://jabber.org/protocol/xhtml-im");
|
||||
if (CONFIG_BOOL_DEFAULTED(m_config, "features.receipts", false)) {
|
||||
features.push_back("urn:xmpp:receipts");
|
||||
}
|
||||
setBuddyFeatures(features);
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::setTransportFeatures(std::list<std::string> &features) {
|
||||
for (std::list<std::string>::iterator it = features.begin(); it != features.end(); it++) {
|
||||
if (!m_transportInfo.hasFeature(*it)) {
|
||||
m_transportInfo.addFeature(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::setBuddyFeatures(std::list<std::string> &f) {
|
||||
delete m_buddyInfo;
|
||||
m_buddyInfo = new Swift::DiscoInfo;
|
||||
m_buddyInfo->addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"), "client", "pc"));
|
||||
|
||||
for (std::list<std::string>::iterator it = f.begin(); it != f.end(); it++) {
|
||||
if (!m_buddyInfo->hasFeature(*it)) {
|
||||
m_buddyInfo->addFeature(*it);
|
||||
}
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
CapsInfoGenerator caps("spectrum", crypto.get());
|
||||
#else
|
||||
CapsInfoGenerator caps("spectrum");
|
||||
#endif
|
||||
m_capsInfo = caps.generateCapsInfo(*m_buddyInfo);
|
||||
onBuddyCapsInfoChanged(m_capsInfo);
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::addRoom(const std::string &jid, const std::string &name) {
|
||||
std::string j = jid;
|
||||
boost::algorithm::to_lower(j);
|
||||
m_rooms[j] = name;
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::clearRooms() {
|
||||
m_rooms.clear();
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::addAdHocCommand(const std::string &node, const std::string &name) {
|
||||
m_commands[node] = node;
|
||||
}
|
||||
|
||||
bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> info) {
|
||||
// disco#info for transport
|
||||
if (to.getNode().empty()) {
|
||||
// Adhoc command
|
||||
if (m_commands.find(info->getNode()) != m_commands.end()) {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addFeature("http://jabber.org/protocol/commands");
|
||||
res->addFeature("jabber:x:data");
|
||||
res->addIdentity(DiscoInfo::Identity(m_commands[info->getNode()], "automation", "command-node"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
else if (info->getNode() == "http://jabber.org/protocol/commands") {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addIdentity(DiscoInfo::Identity("Commands", "automation", "command-list"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
else {
|
||||
if (!info->getNode().empty()) {
|
||||
sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel);
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, id, res);
|
||||
}
|
||||
}
|
||||
// disco#info for room
|
||||
else if (m_rooms.find(to.toBare().toString()) != m_rooms.end()) {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addIdentity(DiscoInfo::Identity(m_rooms[to.toBare().toString()], "conference", "text"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
// disco#info for buddy
|
||||
else {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(*m_buddyInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "discoinforesponder.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include "Swiften/Disco/DiscoInfoResponder.h"
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/DiscoInfo.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/Disco/CapsInfoGenerator.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
DEFINE_LOGGER(logger, "DiscoInfoResponder");
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DiscoInfoResponder::DiscoInfoResponder(Swift::IQRouter *router, Config *config) : Swift::GetResponder<DiscoInfo>(router) {
|
||||
m_config = config;
|
||||
m_config->onBackendConfigUpdated.connect(boost::bind(&DiscoInfoResponder::updateFeatures, this));
|
||||
m_buddyInfo = NULL;
|
||||
m_transportInfo.addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"),
|
||||
CONFIG_STRING(m_config, "identity.category"),
|
||||
CONFIG_STRING(m_config, "identity.type")));
|
||||
#if HAVE_SWIFTEN_3
|
||||
crypto = boost::shared_ptr<CryptoProvider>(PlatformCryptoProvider::create());
|
||||
#endif
|
||||
|
||||
updateFeatures();
|
||||
}
|
||||
|
||||
DiscoInfoResponder::~DiscoInfoResponder() {
|
||||
delete m_buddyInfo;
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::updateFeatures() {
|
||||
std::list<std::string> features2;
|
||||
features2.push_back("jabber:iq:register");
|
||||
features2.push_back("jabber:iq:gateway");
|
||||
features2.push_back("jabber:iq:private");
|
||||
features2.push_back("http://jabber.org/protocol/disco#info");
|
||||
features2.push_back("http://jabber.org/protocol/commands");
|
||||
if (CONFIG_BOOL_DEFAULTED(m_config, "features.muc", false)) {
|
||||
features2.push_back("http://jabber.org/protocol/muc");
|
||||
}
|
||||
setTransportFeatures(features2);
|
||||
|
||||
std::list<std::string> features;
|
||||
features.push_back("http://jabber.org/protocol/disco#items");
|
||||
features.push_back("http://jabber.org/protocol/disco#info");
|
||||
features.push_back("http://jabber.org/protocol/chatstates");
|
||||
features.push_back("http://jabber.org/protocol/xhtml-im");
|
||||
if (CONFIG_BOOL_DEFAULTED(m_config, "features.receipts", false)) {
|
||||
features.push_back("urn:xmpp:receipts");
|
||||
}
|
||||
setBuddyFeatures(features);
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::setTransportFeatures(std::list<std::string> &features) {
|
||||
for (std::list<std::string>::iterator it = features.begin(); it != features.end(); it++) {
|
||||
if (!m_transportInfo.hasFeature(*it)) {
|
||||
m_transportInfo.addFeature(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::setBuddyFeatures(std::list<std::string> &f) {
|
||||
delete m_buddyInfo;
|
||||
m_buddyInfo = new Swift::DiscoInfo;
|
||||
m_buddyInfo->addIdentity(DiscoInfo::Identity(CONFIG_STRING(m_config, "identity.name"), "client", "pc"));
|
||||
|
||||
for (std::list<std::string>::iterator it = f.begin(); it != f.end(); it++) {
|
||||
if (!m_buddyInfo->hasFeature(*it)) {
|
||||
m_buddyInfo->addFeature(*it);
|
||||
}
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
CapsInfoGenerator caps("spectrum", crypto.get());
|
||||
#else
|
||||
CapsInfoGenerator caps("spectrum");
|
||||
#endif
|
||||
m_capsInfo = caps.generateCapsInfo(*m_buddyInfo);
|
||||
onBuddyCapsInfoChanged(m_capsInfo);
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::addRoom(const std::string &jid, const std::string &name) {
|
||||
std::string j = jid;
|
||||
boost::algorithm::to_lower(j);
|
||||
m_rooms[j] = name;
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::clearRooms() {
|
||||
m_rooms.clear();
|
||||
}
|
||||
|
||||
void DiscoInfoResponder::addAdHocCommand(const std::string &node, const std::string &name) {
|
||||
m_commands[node] = node;
|
||||
}
|
||||
|
||||
bool DiscoInfoResponder::handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> info) {
|
||||
// disco#info for transport
|
||||
if (to.getNode().empty()) {
|
||||
// Adhoc command
|
||||
if (m_commands.find(info->getNode()) != m_commands.end()) {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addFeature("http://jabber.org/protocol/commands");
|
||||
res->addFeature("jabber:x:data");
|
||||
res->addIdentity(DiscoInfo::Identity(m_commands[info->getNode()], "automation", "command-node"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
else if (info->getNode() == "http://jabber.org/protocol/commands") {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addIdentity(DiscoInfo::Identity("Commands", "automation", "command-list"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
else {
|
||||
if (!info->getNode().empty()) {
|
||||
sendError(from, id, ErrorPayload::ItemNotFound, ErrorPayload::Cancel);
|
||||
return true;
|
||||
}
|
||||
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(m_transportInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, id, res);
|
||||
}
|
||||
}
|
||||
// disco#info for room
|
||||
else if (m_rooms.find(to.toBare().toString()) != m_rooms.end()) {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo());
|
||||
res->addIdentity(DiscoInfo::Identity(m_rooms[to.toBare().toString()], "conference", "text"));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
// disco#info for buddy
|
||||
else {
|
||||
boost::shared_ptr<DiscoInfo> res(new DiscoInfo(*m_buddyInfo));
|
||||
res->setNode(info->getNode());
|
||||
sendResponse(from, to, id, res);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,75 +1,75 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/signal.hpp>
|
||||
#include "Swiften/Queries/GetResponder.h"
|
||||
#include "Swiften/Elements/DiscoInfo.h"
|
||||
#include "Swiften/Elements/CapsInfo.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/Crypto/CryptoProvider.h>
|
||||
#include <Swiften/Crypto/PlatformCryptoProvider.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Config;
|
||||
|
||||
class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
|
||||
public:
|
||||
DiscoInfoResponder(Swift::IQRouter *router, Config *config);
|
||||
~DiscoInfoResponder();
|
||||
|
||||
void setTransportFeatures(std::list<std::string> &features);
|
||||
void setBuddyFeatures(std::list<std::string> &features);
|
||||
|
||||
void addRoom(const std::string &jid, const std::string &name);
|
||||
void clearRooms();
|
||||
|
||||
void addAdHocCommand(const std::string &node, const std::string &name);
|
||||
|
||||
boost::signal<void (const Swift::CapsInfo &capsInfo)> onBuddyCapsInfoChanged;
|
||||
|
||||
Swift::CapsInfo &getBuddyCapsInfo() {
|
||||
return m_capsInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> payload);
|
||||
void updateFeatures();
|
||||
|
||||
Swift::DiscoInfo m_transportInfo;
|
||||
Swift::DiscoInfo *m_buddyInfo;
|
||||
Config *m_config;
|
||||
Swift::CapsInfo m_capsInfo;
|
||||
std::map<std::string, std::string> m_rooms;
|
||||
std::map<std::string, std::string> m_commands;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<Swift::CryptoProvider> crypto;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <boost/signal.hpp>
|
||||
#include "Swiften/Queries/GetResponder.h"
|
||||
#include "Swiften/Elements/DiscoInfo.h"
|
||||
#include "Swiften/Elements/CapsInfo.h"
|
||||
#include <Swiften/Version.h>
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
#if HAVE_SWIFTEN_3
|
||||
#include <Swiften/Crypto/CryptoProvider.h>
|
||||
#include <Swiften/Crypto/PlatformCryptoProvider.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class Config;
|
||||
|
||||
class DiscoInfoResponder : public Swift::GetResponder<Swift::DiscoInfo> {
|
||||
public:
|
||||
DiscoInfoResponder(Swift::IQRouter *router, Config *config);
|
||||
~DiscoInfoResponder();
|
||||
|
||||
void setTransportFeatures(std::list<std::string> &features);
|
||||
void setBuddyFeatures(std::list<std::string> &features);
|
||||
|
||||
void addRoom(const std::string &jid, const std::string &name);
|
||||
void clearRooms();
|
||||
|
||||
void addAdHocCommand(const std::string &node, const std::string &name);
|
||||
|
||||
boost::signal<void (const Swift::CapsInfo &capsInfo)> onBuddyCapsInfoChanged;
|
||||
|
||||
Swift::CapsInfo &getBuddyCapsInfo() {
|
||||
return m_capsInfo;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool handleGetRequest(const Swift::JID& from, const Swift::JID& to, const std::string& id, boost::shared_ptr<Swift::DiscoInfo> payload);
|
||||
void updateFeatures();
|
||||
|
||||
Swift::DiscoInfo m_transportInfo;
|
||||
Swift::DiscoInfo *m_buddyInfo;
|
||||
Config *m_config;
|
||||
Swift::CapsInfo m_capsInfo;
|
||||
std::map<std::string, std::string> m_rooms;
|
||||
std::map<std::string, std::string> m_commands;
|
||||
#if HAVE_SWIFTEN_3
|
||||
boost::shared_ptr<Swift::CryptoProvider> crypto;
|
||||
#endif
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,102 +1,102 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/filetransfermanager.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/Network/ConnectionServerFactory.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "FileTransferManager");
|
||||
|
||||
FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) {
|
||||
m_component = component;
|
||||
m_userManager = userManager;
|
||||
|
||||
m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter());
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser());
|
||||
#endif
|
||||
m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry();
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
|
||||
m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused");
|
||||
m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
|
||||
#else
|
||||
m_proxyManager = new Swift::SOCKS5BytestreamProxiesManager(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory(), m_component->getNetworkFactories()->getDomainNameResolver(), m_component->getIQRouter(), "bar.com");
|
||||
#endif
|
||||
boost::shared_ptr<Swift::ConnectionServer> server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645);
|
||||
server->start();
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_proxyServerManager = new Swift::SOCKS5BytestreamServerManager(m_bytestreamRegistry, m_component->getNetworkFactories()->getConnectionServerFactory(), m_component->getNetworkFactories()->getNetworkEnvironment(), m_component->getNetworkFactories()->getNATTraverser());
|
||||
#else
|
||||
m_bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry);
|
||||
m_bytestreamServer->start();
|
||||
m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(),
|
||||
m_userManager, m_remoteCandidateSelectorFactory,
|
||||
m_localCandidateGeneratorFactory, m_bytestreamRegistry,
|
||||
m_bytestreamProxy, m_component->getPresenceOracle(),
|
||||
m_bytestreamServer);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// WARNING: Swiften crashes when this is uncommented... But we probably need it for working Jingle FT
|
||||
// m_connectivityManager->addListeningPort(19645);
|
||||
}
|
||||
|
||||
FileTransferManager::~FileTransferManager() {
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_bytestreamServer->stop();
|
||||
delete m_remoteCandidateSelectorFactory;
|
||||
delete m_localCandidateGeneratorFactory;
|
||||
#endif
|
||||
delete m_outgoingFTManager;
|
||||
delete m_jingleSessionManager;
|
||||
delete m_bytestreamRegistry;
|
||||
#if !HAVE_SWIFTEN_3
|
||||
delete m_bytestreamServer;
|
||||
delete m_bytestreamProxy;
|
||||
delete m_connectivityManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
FileTransferManager::Transfer FileTransferManager::sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info) {
|
||||
FileTransferManager::Transfer transfer;
|
||||
transfer.from = buddy->getJID();
|
||||
transfer.to = user->getJID();
|
||||
transfer.readByteStream = byteStream;
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting FT from '" << transfer.from << "' to '" << transfer.to << "'")
|
||||
|
||||
transfer.ft = m_outgoingFTManager->createOutgoingFileTransfer(transfer.from, transfer.to, transfer.readByteStream, info);
|
||||
// if (transfer.ft) {
|
||||
// m_filetransfers.push_back(ft);
|
||||
// ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id));
|
||||
// transfer.ft->start();
|
||||
// }
|
||||
return transfer;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/filetransfermanager.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/logging.h"
|
||||
#include "Swiften/Network/ConnectionServerFactory.h"
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "FileTransferManager");
|
||||
|
||||
FileTransferManager::FileTransferManager(Component *component, UserManager *userManager) {
|
||||
m_component = component;
|
||||
m_userManager = userManager;
|
||||
|
||||
m_jingleSessionManager = new Swift::JingleSessionManager(m_component->getIQRouter());
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_connectivityManager = new Swift::ConnectivityManager(m_component->getNetworkFactories()->getNATTraverser());
|
||||
#endif
|
||||
m_bytestreamRegistry = new Swift::SOCKS5BytestreamRegistry();
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_bytestreamProxy = new Swift::SOCKS5BytestreamProxy(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
|
||||
m_localCandidateGeneratorFactory = new Swift::DefaultLocalJingleTransportCandidateGeneratorFactory(m_connectivityManager, m_bytestreamRegistry, m_bytestreamProxy, "thishouldnotbeused");
|
||||
m_remoteCandidateSelectorFactory = new Swift::DefaultRemoteJingleTransportCandidateSelectorFactory(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory());
|
||||
#else
|
||||
m_proxyManager = new Swift::SOCKS5BytestreamProxiesManager(m_component->getNetworkFactories()->getConnectionFactory(), m_component->getNetworkFactories()->getTimerFactory(), m_component->getNetworkFactories()->getDomainNameResolver(), m_component->getIQRouter(), "bar.com");
|
||||
#endif
|
||||
boost::shared_ptr<Swift::ConnectionServer> server = m_component->getNetworkFactories()->getConnectionServerFactory()->createConnectionServer(19645);
|
||||
server->start();
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_proxyServerManager = new Swift::SOCKS5BytestreamServerManager(m_bytestreamRegistry, m_component->getNetworkFactories()->getConnectionServerFactory(), m_component->getNetworkFactories()->getNetworkEnvironment(), m_component->getNetworkFactories()->getNATTraverser());
|
||||
#else
|
||||
m_bytestreamServer = new Swift::SOCKS5BytestreamServer(server, m_bytestreamRegistry);
|
||||
m_bytestreamServer->start();
|
||||
m_outgoingFTManager = new Swift::CombinedOutgoingFileTransferManager(m_jingleSessionManager, m_component->getIQRouter(),
|
||||
m_userManager, m_remoteCandidateSelectorFactory,
|
||||
m_localCandidateGeneratorFactory, m_bytestreamRegistry,
|
||||
m_bytestreamProxy, m_component->getPresenceOracle(),
|
||||
m_bytestreamServer);
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// WARNING: Swiften crashes when this is uncommented... But we probably need it for working Jingle FT
|
||||
// m_connectivityManager->addListeningPort(19645);
|
||||
}
|
||||
|
||||
FileTransferManager::~FileTransferManager() {
|
||||
#if !HAVE_SWIFTEN_3
|
||||
m_bytestreamServer->stop();
|
||||
delete m_remoteCandidateSelectorFactory;
|
||||
delete m_localCandidateGeneratorFactory;
|
||||
#endif
|
||||
delete m_outgoingFTManager;
|
||||
delete m_jingleSessionManager;
|
||||
delete m_bytestreamRegistry;
|
||||
#if !HAVE_SWIFTEN_3
|
||||
delete m_bytestreamServer;
|
||||
delete m_bytestreamProxy;
|
||||
delete m_connectivityManager;
|
||||
#endif
|
||||
}
|
||||
|
||||
FileTransferManager::Transfer FileTransferManager::sendFile(User *user, Buddy *buddy, boost::shared_ptr<Swift::ReadBytestream> byteStream, const Swift::StreamInitiationFileInfo &info) {
|
||||
FileTransferManager::Transfer transfer;
|
||||
transfer.from = buddy->getJID();
|
||||
transfer.to = user->getJID();
|
||||
transfer.readByteStream = byteStream;
|
||||
|
||||
LOG4CXX_INFO(logger, "Starting FT from '" << transfer.from << "' to '" << transfer.to << "'")
|
||||
|
||||
transfer.ft = m_outgoingFTManager->createOutgoingFileTransfer(transfer.from, transfer.to, transfer.readByteStream, info);
|
||||
// if (transfer.ft) {
|
||||
// m_filetransfers.push_back(ft);
|
||||
// ft->onStateChange.connect(boost::bind(&User::handleFTStateChanged, this, _1, Buddy::JIDToLegacyName(from), info.getName(), info.getSize(), id));
|
||||
// transfer.ft->start();
|
||||
// }
|
||||
return transfer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,181 +1,181 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/storagebackend.h"
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
|
||||
|
||||
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, userManager, storageBackend, initiator, to) {
|
||||
m_state = Init;
|
||||
#if HAVE_SWIFTEN_3
|
||||
Swift::FormField::ref field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, "1");
|
||||
#else
|
||||
Swift::BooleanFormField::ref field;
|
||||
|
||||
field = Swift::BooleanFormField::create(true);
|
||||
#endif
|
||||
field->setName("enable_transport");
|
||||
field->setLabel("Enable transport");
|
||||
addFormField(field);
|
||||
#if HAVE_SWIFTEN_3
|
||||
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0"));
|
||||
#else
|
||||
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0") == "1");
|
||||
#endif
|
||||
field->setName("send_headlines");
|
||||
field->setLabel("Allow sending messages as headlines");
|
||||
addFormField(field);
|
||||
#if HAVE_SWIFTEN_3
|
||||
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0"));
|
||||
#else
|
||||
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0") == "1");
|
||||
#endif
|
||||
field->setName("stay_connected");
|
||||
field->setLabel("Stay connected to legacy network when offline on XMPP");
|
||||
addFormField(field);
|
||||
}
|
||||
|
||||
SettingsAdHocCommand::~SettingsAdHocCommand() {
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::getForm() {
|
||||
if (!m_storageBackend) {
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
#if HAVE_SWIFTEN_3
|
||||
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "This server does not support transport settings. There is no storage backend configured"));
|
||||
#else
|
||||
form->addField(Swift::FixedFormField::create("This server does not support transport settings. There is no storage backend configured"));
|
||||
#endif
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
UserInfo user;
|
||||
if (m_storageBackend->getUser(m_initiator.toBare().toString(), user) == false) {
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
#if HAVE_SWIFTEN_3
|
||||
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "You are not registered."));
|
||||
#else
|
||||
form->addField(Swift::FixedFormField::create("You are not registered."));
|
||||
#endif
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
|
||||
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
|
||||
// FIXME: Support for more types than boolean
|
||||
#if HAVE_SWIFTEN_3
|
||||
if (field->getType() == Swift::FormField::BooleanType) {
|
||||
std::string value = field->getBoolValue() ? "1" : "0";
|
||||
int type = (int) TYPE_BOOLEAN;
|
||||
m_storageBackend->getUserSetting(user.id, field->getName(), type, value);
|
||||
field->setBoolValue(value == "1");
|
||||
}
|
||||
#else
|
||||
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(field)) {
|
||||
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(field));
|
||||
std::string value = f->getValue() ? "1" : "0";
|
||||
int type = (int)TYPE_BOOLEAN;
|
||||
m_storageBackend->getUserSetting(user.id, f->getName(), type, value);
|
||||
f->setValue(value == "1");
|
||||
}
|
||||
#endif
|
||||
|
||||
form->addField(field);
|
||||
}
|
||||
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> payload) {
|
||||
UserInfo user;
|
||||
bool registered = m_storageBackend->getUser(m_initiator.toBare().toString(), user);
|
||||
|
||||
if (registered && payload->getForm()) {
|
||||
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
|
||||
Swift::FormField::ref received = payload->getForm()->getField(field->getName());
|
||||
if (!received) {
|
||||
continue;
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
if (received->getType() == Swift::FormField::BooleanType) {
|
||||
std::string value = received->getBoolValue() ? "1" : "0";
|
||||
m_storageBackend->updateUserSetting(user.id, received->getName(), value);
|
||||
} else if (received->getType() == Swift::FormField::TextSingleType) {
|
||||
m_storageBackend->updateUserSetting(user.id, received->getName(), received->getTextSingleValue());
|
||||
}
|
||||
#else
|
||||
// FIXME: Support for more types than boolean
|
||||
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(received)) {
|
||||
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(received));
|
||||
std::string value = f->getValue() ? "1" : "0";
|
||||
m_storageBackend->updateUserSetting(user.id, f->getName(), value);
|
||||
}
|
||||
else if (boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received)) {
|
||||
Swift::TextSingleFormField::ref f(boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received));
|
||||
m_storageBackend->updateUserSetting(user.id, f->getName(), f->getValue());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
|
||||
boost::shared_ptr<Swift::Command> response;
|
||||
if (payload->getAction() == Swift::Command::Cancel) {
|
||||
response = boost::shared_ptr<Swift::Command>(new Swift::Command("settings", m_id, Swift::Command::Canceled));
|
||||
return response;
|
||||
}
|
||||
|
||||
switch (m_state) {
|
||||
case Init:
|
||||
response = getForm();
|
||||
m_state = WaitingForResponse;
|
||||
break;
|
||||
case WaitingForResponse:
|
||||
response = handleResponse(payload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2012, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/buddy.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/logging.h"
|
||||
#include "transport/storagebackend.h"
|
||||
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "SettingsAdHocCommand");
|
||||
|
||||
SettingsAdHocCommand::SettingsAdHocCommand(Component *component, UserManager *userManager, StorageBackend *storageBackend, const Swift::JID &initiator, const Swift::JID &to) : AdHocCommand(component, userManager, storageBackend, initiator, to) {
|
||||
m_state = Init;
|
||||
#if HAVE_SWIFTEN_3
|
||||
Swift::FormField::ref field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, "1");
|
||||
#else
|
||||
Swift::BooleanFormField::ref field;
|
||||
|
||||
field = Swift::BooleanFormField::create(true);
|
||||
#endif
|
||||
field->setName("enable_transport");
|
||||
field->setLabel("Enable transport");
|
||||
addFormField(field);
|
||||
#if HAVE_SWIFTEN_3
|
||||
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0"));
|
||||
#else
|
||||
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.send_headlines", "0") == "1");
|
||||
#endif
|
||||
field->setName("send_headlines");
|
||||
field->setLabel("Allow sending messages as headlines");
|
||||
addFormField(field);
|
||||
#if HAVE_SWIFTEN_3
|
||||
field = boost::make_shared<Swift::FormField>(Swift::FormField::BooleanType, CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0"));
|
||||
#else
|
||||
field = Swift::BooleanFormField::create(CONFIG_STRING_DEFAULTED(component->getConfig(), "settings.stay_connected", "0") == "1");
|
||||
#endif
|
||||
field->setName("stay_connected");
|
||||
field->setLabel("Stay connected to legacy network when offline on XMPP");
|
||||
addFormField(field);
|
||||
}
|
||||
|
||||
SettingsAdHocCommand::~SettingsAdHocCommand() {
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::getForm() {
|
||||
if (!m_storageBackend) {
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
#if HAVE_SWIFTEN_3
|
||||
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "This server does not support transport settings. There is no storage backend configured"));
|
||||
#else
|
||||
form->addField(Swift::FixedFormField::create("This server does not support transport settings. There is no storage backend configured"));
|
||||
#endif
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
UserInfo user;
|
||||
if (m_storageBackend->getUser(m_initiator.toBare().toString(), user) == false) {
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
#if HAVE_SWIFTEN_3
|
||||
form->addField(boost::make_shared<Swift::FormField>(Swift::FormField::FixedType, "You are not registered."));
|
||||
#else
|
||||
form->addField(Swift::FixedFormField::create("You are not registered."));
|
||||
#endif
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Executing));
|
||||
boost::shared_ptr<Swift::Form> form(new Swift::Form());
|
||||
|
||||
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
|
||||
// FIXME: Support for more types than boolean
|
||||
#if HAVE_SWIFTEN_3
|
||||
if (field->getType() == Swift::FormField::BooleanType) {
|
||||
std::string value = field->getBoolValue() ? "1" : "0";
|
||||
int type = (int) TYPE_BOOLEAN;
|
||||
m_storageBackend->getUserSetting(user.id, field->getName(), type, value);
|
||||
field->setBoolValue(value == "1");
|
||||
}
|
||||
#else
|
||||
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(field)) {
|
||||
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(field));
|
||||
std::string value = f->getValue() ? "1" : "0";
|
||||
int type = (int)TYPE_BOOLEAN;
|
||||
m_storageBackend->getUserSetting(user.id, f->getName(), type, value);
|
||||
f->setValue(value == "1");
|
||||
}
|
||||
#endif
|
||||
|
||||
form->addField(field);
|
||||
}
|
||||
|
||||
response->setForm(form);
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleResponse(boost::shared_ptr<Swift::Command> payload) {
|
||||
UserInfo user;
|
||||
bool registered = m_storageBackend->getUser(m_initiator.toBare().toString(), user);
|
||||
|
||||
if (registered && payload->getForm()) {
|
||||
BOOST_FOREACH(Swift::FormField::ref field, m_fields) {
|
||||
Swift::FormField::ref received = payload->getForm()->getField(field->getName());
|
||||
if (!received) {
|
||||
continue;
|
||||
}
|
||||
#if HAVE_SWIFTEN_3
|
||||
if (received->getType() == Swift::FormField::BooleanType) {
|
||||
std::string value = received->getBoolValue() ? "1" : "0";
|
||||
m_storageBackend->updateUserSetting(user.id, received->getName(), value);
|
||||
} else if (received->getType() == Swift::FormField::TextSingleType) {
|
||||
m_storageBackend->updateUserSetting(user.id, received->getName(), received->getTextSingleValue());
|
||||
}
|
||||
#else
|
||||
// FIXME: Support for more types than boolean
|
||||
if (boost::dynamic_pointer_cast<Swift::BooleanFormField>(received)) {
|
||||
Swift::BooleanFormField::ref f(boost::dynamic_pointer_cast<Swift::BooleanFormField>(received));
|
||||
std::string value = f->getValue() ? "1" : "0";
|
||||
m_storageBackend->updateUserSetting(user.id, f->getName(), value);
|
||||
}
|
||||
else if (boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received)) {
|
||||
Swift::TextSingleFormField::ref f(boost::dynamic_pointer_cast<Swift::TextSingleFormField>(received));
|
||||
m_storageBackend->updateUserSetting(user.id, f->getName(), f->getValue());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> response(new Swift::Command("settings", m_id, Swift::Command::Completed));
|
||||
return response;
|
||||
}
|
||||
|
||||
boost::shared_ptr<Swift::Command> SettingsAdHocCommand::handleRequest(boost::shared_ptr<Swift::Command> payload) {
|
||||
boost::shared_ptr<Swift::Command> response;
|
||||
if (payload->getAction() == Swift::Command::Cancel) {
|
||||
response = boost::shared_ptr<Swift::Command>(new Swift::Command("settings", m_id, Swift::Command::Canceled));
|
||||
return response;
|
||||
}
|
||||
|
||||
switch (m_state) {
|
||||
case Init:
|
||||
response = getForm();
|
||||
m_state = WaitingForResponse;
|
||||
break;
|
||||
case WaitingForResponse:
|
||||
response = handleResponse(payload);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -150,8 +150,11 @@ void BasicTest::dumpReceived() {
|
|||
std::cout << "Stream2:\n";
|
||||
std::cout << receivedData2 << "\n";
|
||||
}
|
||||
|
||||
#if HAVE_SWIFTEN_3
|
||||
void BasicTest::handleElement(boost::shared_ptr<Swift::ToplevelElement> element) {
|
||||
#else
|
||||
void BasicTest::handleElement(boost::shared_ptr<Swift::Element> element) {
|
||||
#endif
|
||||
if (stream1_active) {
|
||||
received.push_back(element);
|
||||
}
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "Swiften/Server/ServerStanzaChannel.h"
|
||||
#include "Swiften/Server/ServerFromClientSession.h"
|
||||
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
|
||||
#define HAVE_SWIFTEN_3 SWIFTEN_VERSION >= 0x030000
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
|
@ -217,9 +218,11 @@ class BasicTest : public Swift::XMPPParserClient {
|
|||
void handleDataReceived2(const Swift::SafeByteArray &data);
|
||||
|
||||
void handleStreamStart(const Swift::ProtocolHeader&);
|
||||
|
||||
#if HAVE_SWIFTEN_3
|
||||
void handleElement(boost::shared_ptr<Swift::ToplevelElement> element);
|
||||
#else
|
||||
void handleElement(boost::shared_ptr<Swift::Element> element);
|
||||
|
||||
#endif
|
||||
void handleStreamEnd();
|
||||
|
||||
void injectPresence(boost::shared_ptr<Swift::Presence> &response);
|
||||
|
|
|
@ -1,151 +0,0 @@
|
|||
#include "transport/userregistry.h"
|
||||
#include "transport/userregistration.h"
|
||||
#include "transport/config.h"
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/user.h"
|
||||
#include "transport/transport.h"
|
||||
#include "transport/conversation.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/localbuddy.h"
|
||||
#include "transport/settingsadhoccommand.h"
|
||||
#include "transport/filetransfermanager.h"
|
||||
#include "transport/adhocmanager.h"
|
||||
#include "transport/memoryreadbytestream.h"
|
||||
#include <cppunit/TestFixture.h>
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
#include <Swiften/Swiften.h>
|
||||
#include <Swiften/EventLoop/DummyEventLoop.h>
|
||||
#include <Swiften/Server/Server.h>
|
||||
#include <Swiften/Network/DummyNetworkFactories.h>
|
||||
#include <Swiften/Network/DummyConnectionServer.h>
|
||||
#include "Swiften/Server/ServerStanzaChannel.h"
|
||||
#include "Swiften/Server/ServerFromClientSession.h"
|
||||
#include "Swiften/Parser/PayloadParsers/FullPayloadParserFactoryCollection.h"
|
||||
#include "basictest.h"
|
||||
|
||||
using namespace Transport;
|
||||
|
||||
class FileTransferManagerTest : public CPPUNIT_NS :: TestFixture, public BasicTest {
|
||||
CPPUNIT_TEST_SUITE(FileTransferManagerTest);
|
||||
CPPUNIT_TEST(sendFileNoMethod);
|
||||
CPPUNIT_TEST(sendFileSIIBB);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
|
||||
public:
|
||||
FileTransferManager *manager;
|
||||
std::string data;
|
||||
FileTransferManager::Transfer transfer;
|
||||
bool dataNeeded;
|
||||
Swift::FileTransfer::State::FTState ftState;
|
||||
boost::shared_ptr<MemoryReadBytestream> bytestream;
|
||||
|
||||
void setUp (void) {
|
||||
setMeUp();
|
||||
|
||||
dataNeeded = false;
|
||||
data = "This is our testing file\n";
|
||||
manager = new FileTransferManager(component, userManager);
|
||||
|
||||
connectUser();
|
||||
add2Buddies();
|
||||
received.clear();
|
||||
}
|
||||
|
||||
void tearDown (void) {
|
||||
received.clear();
|
||||
delete manager;
|
||||
disconnectUser();
|
||||
tearMeDown();
|
||||
}
|
||||
|
||||
|
||||
void handleFTDataNeeded() {
|
||||
dataNeeded = true;
|
||||
// std::cout << "data needed\n";
|
||||
}
|
||||
|
||||
void handleFTStateChanged(Swift::FileTransfer::State state) {
|
||||
// std::cout << "state changed " << state.state << "\n";
|
||||
ftState = state.state;
|
||||
}
|
||||
|
||||
void _sendFile() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
|
||||
Swift::StreamInitiationFileInfo fileInfo;
|
||||
fileInfo.setSize(data.size());
|
||||
fileInfo.setName("test.pdf");
|
||||
|
||||
bytestream = boost::shared_ptr<MemoryReadBytestream>(new MemoryReadBytestream(data.size()));
|
||||
bytestream->onDataNeeded.connect(boost::bind(&FileTransferManagerTest::handleFTDataNeeded, this));
|
||||
|
||||
transfer = manager->sendFile(user, user->getRosterManager()->getBuddy("buddy1"), bytestream, fileInfo);
|
||||
}
|
||||
|
||||
void sendFileNoMethod() {
|
||||
_sendFile();
|
||||
CPPUNIT_ASSERT(!transfer.ft);
|
||||
}
|
||||
|
||||
void sendFileSIIBB() {
|
||||
User *user = userManager->getUser("user@localhost");
|
||||
boost::shared_ptr<Swift::DiscoInfo> info(new Swift::DiscoInfo());
|
||||
info->addFeature("http://jabber.org/protocol/si/profile/file-transfer");
|
||||
user->handleDiscoInfo("user@localhost/resource", info);
|
||||
|
||||
// Send file request
|
||||
_sendFile();
|
||||
CPPUNIT_ASSERT(transfer.ft);
|
||||
|
||||
transfer.ft->onStateChange.connect(boost::bind(&FileTransferManagerTest::handleFTStateChanged, this, _1));
|
||||
transfer.ft->start();
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
|
||||
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::StreamInitiation>());
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(std::string("test.pdf"), dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getPayload<Swift::StreamInitiation>()->getFileInfo()->getName());
|
||||
CPPUNIT_ASSERT_EQUAL((int) data.size(), (int) dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getPayload<Swift::StreamInitiation>()->getFileInfo()->getSize());
|
||||
|
||||
// request acceptation
|
||||
Swift::IQ::ref accept = Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID());
|
||||
Swift::StreamInitiation::ref payload(new Swift::StreamInitiation());
|
||||
payload->setRequestedMethod("http://jabber.org/protocol/ibb");
|
||||
accept->addPayload(payload);
|
||||
injectIQ(accept);
|
||||
loop->processEvents();
|
||||
received.erase(received.begin());
|
||||
|
||||
// handle open packet and accept the FT
|
||||
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
|
||||
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::IBB>());
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::IBB::Open, getStanza(received[0])->getPayload<Swift::IBB>()->getAction());
|
||||
injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID()));
|
||||
loop->processEvents();
|
||||
|
||||
CPPUNIT_ASSERT_EQUAL(true, dataNeeded);
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::FileTransfer::State::Transferring, ftState);
|
||||
|
||||
bytestream->appendData(data); // this will be send in one packet...
|
||||
loop->processEvents();
|
||||
received.erase(received.begin());
|
||||
|
||||
// we received data now
|
||||
CPPUNIT_ASSERT_EQUAL(1, (int) received.size());
|
||||
CPPUNIT_ASSERT(dynamic_cast<Swift::IQ *>(getStanza(received[0])));
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::IQ::Set, dynamic_cast<Swift::IQ *>(getStanza(received[0]))->getType());
|
||||
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::IBB>());
|
||||
CPPUNIT_ASSERT_EQUAL(Swift::IBB::Data, getStanza(received[0])->getPayload<Swift::IBB>()->getAction());
|
||||
injectIQ(Swift::IQ::createResult(getStanza(received[0])->getFrom(), getStanza(received[0])->getTo(), getStanza(received[0])->getID()));
|
||||
loop->processEvents();
|
||||
received.erase(received.begin());
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
CPPUNIT_TEST_SUITE_REGISTRATION (FileTransferManagerTest);
|
|
@ -147,7 +147,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
|
|||
|
||||
// set enabled_transport = 0
|
||||
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("enable_transport");
|
||||
boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->setValue(false);
|
||||
f->setBoolValue(false);
|
||||
|
||||
std::string sessionId = getStanza(received[0])->getPayload<Swift::Command>()->getSessionID();
|
||||
|
||||
|
@ -207,7 +207,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
|
|||
|
||||
// set enabled_transport = 0
|
||||
f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("enable_transport");
|
||||
CPPUNIT_ASSERT_EQUAL(false, boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->getValue());
|
||||
CPPUNIT_ASSERT_EQUAL(false, f->getBoolValue());
|
||||
}
|
||||
|
||||
void executeTwoCommands() {
|
||||
|
@ -355,7 +355,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
|
|||
|
||||
// set enabled_transport = 0
|
||||
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("send_headlines");
|
||||
boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->setValue(true);
|
||||
f->setBoolValue(true);
|
||||
|
||||
std::string sessionId = getStanza(received[0])->getPayload<Swift::Command>()->getSessionID();
|
||||
|
||||
|
@ -397,7 +397,7 @@ class SettingsAdHocCommandTest : public CPPUNIT_NS :: TestFixture, public BasicT
|
|||
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm());
|
||||
CPPUNIT_ASSERT(getStanza(received[0])->getPayload<Swift::Command>()->getForm()->getField("send_headlines"));
|
||||
Swift::FormField::ref f = getStanza(received[0])->getPayload<Swift:: Command>()->getForm()->getField("send_headlines");
|
||||
CPPUNIT_ASSERT_EQUAL(true, boost::dynamic_pointer_cast<Swift::BooleanFormField>(f)->getValue());
|
||||
CPPUNIT_ASSERT_EQUAL(true, f->getBoolValue());
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -1,363 +1,363 @@
|
|||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/transport.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/userregistry.h"
|
||||
#include "transport/logging.h"
|
||||
#include "storageparser.h"
|
||||
#ifdef _WIN32
|
||||
#include <Swiften/TLS/CAPICertificate.h>
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
|
||||
#else
|
||||
#include "Swiften/TLS/PKCS12Certificate.h"
|
||||
#include "Swiften/TLS/CertificateWithKey.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
|
||||
#endif
|
||||
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
|
||||
#include "transport/BlockParser.h"
|
||||
#include "transport/BlockSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
|
||||
#include "Swiften/Parser/GenericPayloadParserFactory.h"
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/RosterPayload.h"
|
||||
#include "Swiften/Elements/InBandRegistrationPayload.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "Component");
|
||||
DEFINE_LOGGER(logger_xml, "Component.XML");
|
||||
|
||||
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
|
||||
m_component = NULL;
|
||||
m_userRegistry = NULL;
|
||||
m_server = NULL;
|
||||
m_reconnectCount = 0;
|
||||
m_config = config;
|
||||
m_config->onBackendConfigUpdated.connect(boost::bind(&Component::handleBackendConfigChanged, this));
|
||||
m_factory = factory;
|
||||
m_loop = loop;
|
||||
m_userRegistry = userRegistry;
|
||||
m_rawXML = false;
|
||||
|
||||
m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
|
||||
|
||||
m_factories = factories;
|
||||
|
||||
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
|
||||
m_reconnectTimer->onTick.connect(bind(&Component::start, this));
|
||||
|
||||
if (CONFIG_BOOL(m_config, "service.server_mode")) {
|
||||
LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
if (!CONFIG_STRING(m_config, "service.cert").empty()) {
|
||||
#ifndef _WIN32
|
||||
//TODO: fix
|
||||
LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
|
||||
LOG4CXX_INFO(logger, "SSLv23_server_method used.");
|
||||
TLSServerContextFactory *f = new OpenSSLServerContextFactory();
|
||||
CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
|
||||
m_server->addTLSEncryption(f, certificate);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
|
||||
}
|
||||
// m_server->start();
|
||||
m_stanzaChannel = m_server->getStanzaChannel();
|
||||
m_iqRouter = m_server->getIQRouter();
|
||||
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
|
||||
|
||||
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
|
||||
m_server->addPayloadSerializer(new Transport::BlockSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::StatsSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
|
||||
|
||||
m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
|
||||
m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "Creating component in gateway mode");
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_component = new Swift::Component(m_jid, CONFIG_STRING(m_config, "service.password"), m_factories);
|
||||
#else
|
||||
m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
|
||||
#endif
|
||||
m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
|
||||
m_component->onConnected.connect(bind(&Component::handleConnected, this));
|
||||
m_component->onError.connect(boost::bind(&Component::handleConnectionError, this, _1));
|
||||
m_component->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
|
||||
m_component->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
|
||||
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
|
||||
|
||||
m_component->addPayloadSerializer(new Swift::AttentionSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
|
||||
m_component->addPayloadSerializer(new Transport::BlockSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::StatsSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
|
||||
|
||||
m_stanzaChannel = m_component->getStanzaChannel();
|
||||
m_iqRouter = m_component->getIQRouter();
|
||||
}
|
||||
|
||||
m_capsMemoryStorage = new CapsMemoryStorage();
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter, m_factories->getCryptoProvider());
|
||||
#else
|
||||
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
|
||||
#endif
|
||||
m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
|
||||
m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
|
||||
|
||||
m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
|
||||
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
|
||||
|
||||
|
||||
|
||||
//
|
||||
// m_registerHandler = new SpectrumRegisterHandler(m_component);
|
||||
// m_registerHandler->start();
|
||||
}
|
||||
|
||||
Component::~Component() {
|
||||
delete m_presenceOracle;
|
||||
delete m_entityCapsManager;
|
||||
delete m_capsManager;
|
||||
delete m_capsMemoryStorage;
|
||||
if (m_component)
|
||||
delete m_component;
|
||||
if (m_server) {
|
||||
m_server->stop();
|
||||
delete m_server;
|
||||
}
|
||||
}
|
||||
|
||||
bool Component::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
|
||||
if (!m_rawXML) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
|
||||
if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
|
||||
if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
|
||||
|
||||
if (iq->getTo().getNode().empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
onRawIQReceived(iq);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Component::handleBackendConfigChanged() {
|
||||
if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
|
||||
m_rawXML = true;
|
||||
m_iqRouter->addHandler(this);
|
||||
}
|
||||
}
|
||||
|
||||
Swift::StanzaChannel *Component::getStanzaChannel() {
|
||||
return m_stanzaChannel;
|
||||
}
|
||||
|
||||
Transport::PresenceOracle *Component::getPresenceOracle() {
|
||||
return m_presenceOracle;
|
||||
}
|
||||
|
||||
void Component::start() {
|
||||
if (m_component && !m_component->isAvailable()) {
|
||||
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
|
||||
if (CONFIG_INT(m_config, "service.port") == 5222) {
|
||||
LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
|
||||
}
|
||||
m_reconnectCount++;
|
||||
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
else if (m_server) {
|
||||
LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server->start();
|
||||
|
||||
//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
|
||||
//Ideally, onStopped must be defined in ConnectionServer
|
||||
if (boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())) {
|
||||
boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&Component::handleServerStopped, this, _1));
|
||||
}
|
||||
|
||||
// We're connected right here, because we're in server mode...
|
||||
handleConnected();
|
||||
}
|
||||
}
|
||||
|
||||
void Component::stop() {
|
||||
if (m_component) {
|
||||
m_reconnectCount = 0;
|
||||
// TODO: Call this once swiften will fix assert(!session_);
|
||||
// m_component->disconnect();
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
else if (m_server) {
|
||||
LOG4CXX_INFO(logger, "Stopping component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Component::handleConnected() {
|
||||
onConnected();
|
||||
m_reconnectCount = 0;
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
|
||||
void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
|
||||
if(e != NULL ) {
|
||||
if(*e == Swift::BoostConnectionServer::Conflict) {
|
||||
LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
|
||||
if (CONFIG_INT(m_config, "service.port") == 5347) {
|
||||
LOG4CXX_INFO(logger, "Port 5347 is usually used for components. You are using server_mode=1. Are you sure you don't want to use server_mode=0 and run spectrum as component?");
|
||||
}
|
||||
}
|
||||
if(*e == Swift::BoostConnectionServer::UnknownError)
|
||||
LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Component::handleConnectionError(const ComponentError &error) {
|
||||
onConnectionError(error);
|
||||
// if (m_reconnectCount == 2)
|
||||
// Component::instance()->userManager()->removeAllUsers();
|
||||
std::string str = "Unknown error";
|
||||
switch (error.getType()) {
|
||||
case ComponentError::UnknownError: str = "Unknown error"; break;
|
||||
case ComponentError::ConnectionError: str = "Connection error"; break;
|
||||
case ComponentError::ConnectionReadError: str = "Connection read error"; break;
|
||||
case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
|
||||
case ComponentError::XMLError: str = "XML Error"; break;
|
||||
case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
|
||||
case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
|
||||
|
||||
m_reconnectTimer->start();
|
||||
}
|
||||
|
||||
void Component::handleDataRead(const Swift::SafeByteArray &data) {
|
||||
std::string d = safeByteArrayToString(data);
|
||||
if (!boost::starts_with(d, "<auth")) {
|
||||
LOG4CXX_INFO(logger_xml, "XML IN " << d);
|
||||
}
|
||||
}
|
||||
|
||||
void Component::handleDataWritten(const Swift::SafeByteArray &data) {
|
||||
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
|
||||
}
|
||||
|
||||
void Component::handlePresence(Swift::Presence::ref presence) {
|
||||
// filter out login/logout presence spam
|
||||
if (!presence->getTo().getNode().empty())
|
||||
return;
|
||||
|
||||
// filter out bad presences
|
||||
if (!presence->getFrom().isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (presence->getType()) {
|
||||
case Presence::Error:
|
||||
case Presence::Subscribe:
|
||||
case Presence::Subscribed:
|
||||
case Presence::Unsubscribe:
|
||||
case Presence::Unsubscribed:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
// check if we have this client's capabilities and ask for them
|
||||
if (presence->getType() != Swift::Presence::Unavailable) {
|
||||
boost::shared_ptr<CapsInfo> capsInfo = presence->getPayload<CapsInfo>();
|
||||
if (capsInfo && capsInfo->getHash() == "sha-1") {
|
||||
/*haveFeatures = */m_entityCapsManager->getCaps(presence->getFrom()) != DiscoInfo::ref();
|
||||
}
|
||||
#ifdef SUPPORT_LEGACY_CAPS
|
||||
else {
|
||||
GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
|
||||
discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
|
||||
discoInfoRequest->send();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
onUserPresenceReceived(presence);
|
||||
}
|
||||
|
||||
void Component::handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid) {
|
||||
#ifdef SUPPORT_LEGACY_CAPS
|
||||
onUserDiscoInfoReceived(jid, info);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Component::handleCapsChanged(const Swift::JID& jid) {
|
||||
onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* libtransport -- C++ library for easy XMPP Transports development
|
||||
*
|
||||
* Copyright (C) 2011, Jan Kaluza <hanzz.k@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/transport.h"
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/smart_ptr/make_shared.hpp>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include "transport/storagebackend.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/userregistry.h"
|
||||
#include "transport/logging.h"
|
||||
#include "storageparser.h"
|
||||
#ifdef _WIN32
|
||||
#include <Swiften/TLS/CAPICertificate.h>
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContext.h"
|
||||
#include "Swiften/TLS/Schannel/SchannelServerContextFactory.h"
|
||||
#else
|
||||
#include "Swiften/TLS/PKCS12Certificate.h"
|
||||
#include "Swiften/TLS/CertificateWithKey.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContext.h"
|
||||
#include "Swiften/TLS/OpenSSL/OpenSSLServerContextFactory.h"
|
||||
#endif
|
||||
#include "Swiften/Parser/PayloadParsers/AttentionParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/AttentionSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/XHTMLIMParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/XHTMLIMSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/StatsParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/StatsSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/GatewayPayloadParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/GatewayPayloadSerializer.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/SpectrumErrorSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/MUCPayloadParser.h"
|
||||
#include "transport/BlockParser.h"
|
||||
#include "transport/BlockSerializer.h"
|
||||
#include "Swiften/Parser/PayloadParsers/InvisibleParser.h"
|
||||
#include "Swiften/Serializer/PayloadSerializers/InvisibleSerializer.h"
|
||||
#include "Swiften/Parser/GenericPayloadParserFactory.h"
|
||||
#include "Swiften/Queries/IQRouter.h"
|
||||
#include "Swiften/Elements/RosterPayload.h"
|
||||
#include "Swiften/Elements/InBandRegistrationPayload.h"
|
||||
|
||||
using namespace Swift;
|
||||
using namespace boost;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
DEFINE_LOGGER(logger, "Component");
|
||||
DEFINE_LOGGER(logger_xml, "Component.XML");
|
||||
|
||||
Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories, Config *config, Factory *factory, Transport::UserRegistry *userRegistry) {
|
||||
m_component = NULL;
|
||||
m_userRegistry = NULL;
|
||||
m_server = NULL;
|
||||
m_reconnectCount = 0;
|
||||
m_config = config;
|
||||
m_config->onBackendConfigUpdated.connect(boost::bind(&Component::handleBackendConfigChanged, this));
|
||||
m_factory = factory;
|
||||
m_loop = loop;
|
||||
m_userRegistry = userRegistry;
|
||||
m_rawXML = false;
|
||||
|
||||
m_jid = Swift::JID(CONFIG_STRING(m_config, "service.jid"));
|
||||
|
||||
m_factories = factories;
|
||||
|
||||
m_reconnectTimer = m_factories->getTimerFactory()->createTimer(3000);
|
||||
m_reconnectTimer->onTick.connect(bind(&Component::start, this));
|
||||
|
||||
if (CONFIG_BOOL(m_config, "service.server_mode")) {
|
||||
LOG4CXX_INFO(logger, "Creating component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server = new Swift::Server(loop, m_factories, m_userRegistry, m_jid, CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
if (!CONFIG_STRING(m_config, "service.cert").empty()) {
|
||||
#ifndef _WIN32
|
||||
//TODO: fix
|
||||
LOG4CXX_INFO(logger, "Using PKCS#12 certificate " << CONFIG_STRING(m_config, "service.cert"));
|
||||
LOG4CXX_INFO(logger, "SSLv23_server_method used.");
|
||||
TLSServerContextFactory *f = new OpenSSLServerContextFactory();
|
||||
CertificateWithKey::ref certificate = boost::make_shared<PKCS12Certificate>(CONFIG_STRING(m_config, "service.cert"), createSafeByteArray(CONFIG_STRING(m_config, "service.cert_password")));
|
||||
m_server->addTLSEncryption(f, certificate);
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
LOG4CXX_WARN(logger, "No PKCS#12 certificate used. TLS is disabled.");
|
||||
}
|
||||
// m_server->start();
|
||||
m_stanzaChannel = m_server->getStanzaChannel();
|
||||
m_iqRouter = m_server->getIQRouter();
|
||||
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
|
||||
m_server->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
|
||||
|
||||
m_server->addPayloadSerializer(new Swift::AttentionSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::XHTMLIMSerializer());
|
||||
m_server->addPayloadSerializer(new Transport::BlockSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::InvisibleSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::StatsSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
|
||||
m_server->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
|
||||
|
||||
m_server->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
|
||||
m_server->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
|
||||
}
|
||||
else {
|
||||
LOG4CXX_INFO(logger, "Creating component in gateway mode");
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_component = new Swift::Component(m_jid, CONFIG_STRING(m_config, "service.password"), m_factories);
|
||||
#else
|
||||
m_component = new Swift::Component(loop, m_factories, m_jid, CONFIG_STRING(m_config, "service.password"));
|
||||
#endif
|
||||
m_component->setSoftwareVersion("Spectrum", SPECTRUM_VERSION);
|
||||
m_component->onConnected.connect(bind(&Component::handleConnected, this));
|
||||
m_component->onError.connect(boost::bind(&Component::handleConnectionError, this, _1));
|
||||
m_component->onDataRead.connect(boost::bind(&Component::handleDataRead, this, _1));
|
||||
m_component->onDataWritten.connect(boost::bind(&Component::handleDataWritten, this, _1));
|
||||
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<StorageParser>("private", "jabber:iq:private"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::AttentionParser>("attention", "urn:xmpp:attention:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::XHTMLIMParser>("html", "http://jabber.org/protocol/xhtml-im"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Transport::BlockParser>("block", "urn:xmpp:block:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::InvisibleParser>("invisible", "urn:xmpp:invisible:0"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::StatsParser>("query", "http://jabber.org/protocol/stats"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::GatewayPayloadParser>("query", "jabber:iq:gateway"));
|
||||
m_component->addPayloadParserFactory(new GenericPayloadParserFactory<Swift::MUCPayloadParser>("x", "http://jabber.org/protocol/muc"));
|
||||
|
||||
m_component->addPayloadSerializer(new Swift::AttentionSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::XHTMLIMSerializer());
|
||||
m_component->addPayloadSerializer(new Transport::BlockSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::InvisibleSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::StatsSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::SpectrumErrorSerializer());
|
||||
m_component->addPayloadSerializer(new Swift::GatewayPayloadSerializer());
|
||||
|
||||
m_stanzaChannel = m_component->getStanzaChannel();
|
||||
m_iqRouter = m_component->getIQRouter();
|
||||
}
|
||||
|
||||
m_capsMemoryStorage = new CapsMemoryStorage();
|
||||
#if HAVE_SWIFTEN_3
|
||||
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter, m_factories->getCryptoProvider());
|
||||
#else
|
||||
m_capsManager = new CapsManager(m_capsMemoryStorage, m_stanzaChannel, m_iqRouter);
|
||||
#endif
|
||||
m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
|
||||
m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
|
||||
|
||||
m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
|
||||
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
|
||||
|
||||
|
||||
|
||||
//
|
||||
// m_registerHandler = new SpectrumRegisterHandler(m_component);
|
||||
// m_registerHandler->start();
|
||||
}
|
||||
|
||||
Component::~Component() {
|
||||
delete m_presenceOracle;
|
||||
delete m_entityCapsManager;
|
||||
delete m_capsManager;
|
||||
delete m_capsMemoryStorage;
|
||||
if (m_component)
|
||||
delete m_component;
|
||||
if (m_server) {
|
||||
m_server->stop();
|
||||
delete m_server;
|
||||
}
|
||||
}
|
||||
|
||||
bool Component::handleIQ(boost::shared_ptr<Swift::IQ> iq) {
|
||||
if (!m_rawXML) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (iq->getPayload<Swift::RosterPayload>() != NULL) { return false; }
|
||||
if (iq->getPayload<Swift::InBandRegistrationPayload>() != NULL) { return false; }
|
||||
if (iq->getPayload<Swift::StatsPayload>() != NULL) { return false; }
|
||||
|
||||
if (iq->getTo().getNode().empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
onRawIQReceived(iq);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Component::handleBackendConfigChanged() {
|
||||
if (!m_rawXML && CONFIG_BOOL_DEFAULTED(m_config, "features.rawxml", false)) {
|
||||
m_rawXML = true;
|
||||
m_iqRouter->addHandler(this);
|
||||
}
|
||||
}
|
||||
|
||||
Swift::StanzaChannel *Component::getStanzaChannel() {
|
||||
return m_stanzaChannel;
|
||||
}
|
||||
|
||||
Transport::PresenceOracle *Component::getPresenceOracle() {
|
||||
return m_presenceOracle;
|
||||
}
|
||||
|
||||
void Component::start() {
|
||||
if (m_component && !m_component->isAvailable()) {
|
||||
LOG4CXX_INFO(logger, "Connecting XMPP server " << CONFIG_STRING(m_config, "service.server") << " port " << CONFIG_INT(m_config, "service.port"));
|
||||
if (CONFIG_INT(m_config, "service.port") == 5222) {
|
||||
LOG4CXX_WARN(logger, "Port 5222 is usually used for client connections, not for component connections! Are you sure you are using right port?");
|
||||
}
|
||||
m_reconnectCount++;
|
||||
m_component->connect(CONFIG_STRING(m_config, "service.server"), CONFIG_INT(m_config, "service.port"));
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
else if (m_server) {
|
||||
LOG4CXX_INFO(logger, "Starting component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server->start();
|
||||
|
||||
//Type casting to BoostConnectionServer since onStopped signal is not defined in ConnectionServer
|
||||
//Ideally, onStopped must be defined in ConnectionServer
|
||||
if (boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())) {
|
||||
boost::dynamic_pointer_cast<Swift::BoostConnectionServer>(m_server->getConnectionServer())->onStopped.connect(boost::bind(&Component::handleServerStopped, this, _1));
|
||||
}
|
||||
|
||||
// We're connected right here, because we're in server mode...
|
||||
handleConnected();
|
||||
}
|
||||
}
|
||||
|
||||
void Component::stop() {
|
||||
if (m_component) {
|
||||
m_reconnectCount = 0;
|
||||
// TODO: Call this once swiften will fix assert(!session_);
|
||||
// m_component->disconnect();
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
else if (m_server) {
|
||||
LOG4CXX_INFO(logger, "Stopping component in server mode on port " << CONFIG_INT(m_config, "service.port"));
|
||||
m_server->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Component::handleConnected() {
|
||||
onConnected();
|
||||
m_reconnectCount = 0;
|
||||
m_reconnectTimer->stop();
|
||||
}
|
||||
|
||||
void Component::handleServerStopped(boost::optional<Swift::BoostConnectionServer::Error> e) {
|
||||
if(e != NULL ) {
|
||||
if(*e == Swift::BoostConnectionServer::Conflict) {
|
||||
LOG4CXX_INFO(logger, "Port "<< CONFIG_INT(m_config, "service.port") << " already in use! Stopping server..");
|
||||
if (CONFIG_INT(m_config, "service.port") == 5347) {
|
||||
LOG4CXX_INFO(logger, "Port 5347 is usually used for components. You are using server_mode=1. Are you sure you don't want to use server_mode=0 and run spectrum as component?");
|
||||
}
|
||||
}
|
||||
if(*e == Swift::BoostConnectionServer::UnknownError)
|
||||
LOG4CXX_INFO(logger, "Unknown error occured! Stopping server..");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Component::handleConnectionError(const ComponentError &error) {
|
||||
onConnectionError(error);
|
||||
// if (m_reconnectCount == 2)
|
||||
// Component::instance()->userManager()->removeAllUsers();
|
||||
std::string str = "Unknown error";
|
||||
switch (error.getType()) {
|
||||
case ComponentError::UnknownError: str = "Unknown error"; break;
|
||||
case ComponentError::ConnectionError: str = "Connection error"; break;
|
||||
case ComponentError::ConnectionReadError: str = "Connection read error"; break;
|
||||
case ComponentError::ConnectionWriteError: str = "Connection write error"; break;
|
||||
case ComponentError::XMLError: str = "XML Error"; break;
|
||||
case ComponentError::AuthenticationFailedError: str = "Authentication failed error"; break;
|
||||
case ComponentError::UnexpectedElementError: str = "Unexpected element error"; break;
|
||||
}
|
||||
LOG4CXX_INFO(logger, "Disconnected from XMPP server. Error: " << str);
|
||||
|
||||
m_reconnectTimer->start();
|
||||
}
|
||||
|
||||
void Component::handleDataRead(const Swift::SafeByteArray &data) {
|
||||
std::string d = safeByteArrayToString(data);
|
||||
if (!boost::starts_with(d, "<auth")) {
|
||||
LOG4CXX_INFO(logger_xml, "XML IN " << d);
|
||||
}
|
||||
}
|
||||
|
||||
void Component::handleDataWritten(const Swift::SafeByteArray &data) {
|
||||
LOG4CXX_INFO(logger_xml, "XML OUT " << safeByteArrayToString(data));
|
||||
}
|
||||
|
||||
void Component::handlePresence(Swift::Presence::ref presence) {
|
||||
// filter out login/logout presence spam
|
||||
if (!presence->getTo().getNode().empty())
|
||||
return;
|
||||
|
||||
// filter out bad presences
|
||||
if (!presence->getFrom().isValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (presence->getType()) {
|
||||
case Presence::Error:
|
||||
case Presence::Subscribe:
|
||||
case Presence::Subscribed:
|
||||
case Presence::Unsubscribe:
|
||||
case Presence::Unsubscribed:
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
// check if we have this client's capabilities and ask for them
|
||||
if (presence->getType() != Swift::Presence::Unavailable) {
|
||||
boost::shared_ptr<CapsInfo> capsInfo = presence->getPayload<CapsInfo>();
|
||||
if (capsInfo && capsInfo->getHash() == "sha-1") {
|
||||
/*haveFeatures = */m_entityCapsManager->getCaps(presence->getFrom()) != DiscoInfo::ref();
|
||||
}
|
||||
#ifdef SUPPORT_LEGACY_CAPS
|
||||
else {
|
||||
GetDiscoInfoRequest::ref discoInfoRequest = GetDiscoInfoRequest::create(presence->getFrom(), m_iqRouter);
|
||||
discoInfoRequest->onResponse.connect(boost::bind(&Component::handleDiscoInfoResponse, this, _1, _2, presence->getFrom()));
|
||||
discoInfoRequest->send();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
onUserPresenceReceived(presence);
|
||||
}
|
||||
|
||||
void Component::handleDiscoInfoResponse(boost::shared_ptr<Swift::DiscoInfo> info, Swift::ErrorPayload::ref error, const Swift::JID& jid) {
|
||||
#ifdef SUPPORT_LEGACY_CAPS
|
||||
onUserDiscoInfoReceived(jid, info);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Component::handleCapsChanged(const Swift::JID& jid) {
|
||||
onUserDiscoInfoReceived(jid, m_entityCapsManager->getCaps(jid));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
1016
src/user.cpp
1016
src/user.cpp
File diff suppressed because it is too large
Load Diff
1212
src/usermanager.cpp
1212
src/usermanager.cpp
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue