diff options
Diffstat (limited to 'Swiften/Network/HTTPConnectProxiedConnection.cpp')
-rw-r--r-- | Swiften/Network/HTTPConnectProxiedConnection.cpp | 63 |
1 files changed, 60 insertions, 3 deletions
diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp index ead48e9..fc5a6c6 100644 --- a/Swiften/Network/HTTPConnectProxiedConnection.cpp +++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp @@ -5,7 +5,7 @@ */ /* - * Copyright (c) 2011-2012 Isode Limited. + * Copyright (c) 2011-2015 Isode Limited. * All rights reserved. * See the COPYING file for more information. */ @@ -14,15 +14,20 @@ #include <Swiften/Network/HTTPConnectProxiedConnection.h> #include <iostream> +#include <utility> + #include <boost/bind.hpp> #include <boost/lexical_cast.hpp> +#include <boost/algorithm/string.hpp> +#include <Swiften/Base/foreach.h> #include <Swiften/Base/Algorithm.h> #include <Swiften/Base/Log.h> #include <Swiften/Base/String.h> #include <Swiften/Base/ByteArray.h> #include <Swiften/Network/HostAddressPort.h> #include <Swiften/Network/ConnectionFactory.h> +#include <Swiften/Network/HTTPTrafficFilter.h> #include <Swiften/StringCodecs/Base64.h> using namespace Swift; @@ -40,6 +45,9 @@ HTTPConnectProxiedConnection::HTTPConnectProxiedConnection( authPassword_(authPassword) { } +void HTTPConnectProxiedConnection::setHTTPTrafficFilter(boost::shared_ptr<HTTPTrafficFilter> trafficFilter) { + trafficFilter_ = trafficFilter; +} void HTTPConnectProxiedConnection::initializeProxy() { std::stringstream connect; @@ -58,9 +66,58 @@ void HTTPConnectProxiedConnection::initializeProxy() { write(data); } +void HTTPConnectProxiedConnection::parseHTTPHeader(const std::string& data, std::string& statusLine, std::vector<std::pair<std::string, std::string> >& headerFields) { + std::istringstream dataStream(data); + + // parse status line + std::getline(dataStream, statusLine); + + // parse fields + std::string headerLine; + std::string::size_type splitIndex; + while (std::getline(dataStream, headerLine) && headerLine != "\r") { + splitIndex = headerLine.find(':', 0); + if (splitIndex != std::string::npos) { + headerFields.push_back(std::pair<std::string, std::string>(headerLine.substr(0, splitIndex), headerLine.substr(splitIndex + 1))); + } + } +} + +void HTTPConnectProxiedConnection::sendHTTPRequest(const std::string& statusLine, std::vector<std::pair<std::string, std::string> >& headerFields) { + typedef std::pair<std::string, std::string> HTTPHeaderField; + std::stringstream request; + + request << statusLine << "\r\n"; + foreach (const HTTPHeaderField& field, headerFields) { + request << field.first << ":" << field.second << "\r\n"; + } + request << "\r\n"; + write(createSafeByteArray(request.str())); +} + void HTTPConnectProxiedConnection::handleProxyInitializeData(boost::shared_ptr<SafeByteArray> data) { - SWIFT_LOG(debug) << byteArrayToString(ByteArray(data->begin(), data->end())) << std::endl; - std::vector<std::string> tmp = String::split(byteArrayToString(ByteArray(data->begin(), data->end())), ' '); + std::string dataString = byteArrayToString(ByteArray(data->begin(), data->end())); + SWIFT_LOG(debug) << data << std::endl; + + std::string statusLine; + std::vector<std::pair<std::string, std::string> > headerFields; + + std::string::size_type headerEnd = dataString.find("\r\n\r\n", 0); + + parseHTTPHeader(dataString.substr(0, headerEnd), statusLine, headerFields); + + if (trafficFilter_) { + std::vector<std::pair<std::string, std::string> > newHeaderFields = trafficFilter_->filterHTTPResponseHeader(headerFields); + if (!newHeaderFields.empty()) { + std::stringstream statusLine; + statusLine << "CONNECT " << getServer().getAddress().toString() << ":" << getServer().getPort(); + sendHTTPRequest(statusLine.str(), newHeaderFields); + SWIFT_LOG(debug) << "send HTTP request from traffic filter" << std::endl; + return; + } + } + + std::vector<std::string> tmp = String::split(statusLine, ' '); if (tmp.size() > 1) { try { int status = boost::lexical_cast<int>(tmp[1]); |