- Added preparation for fixed forwading tables - Updated TODO list (forwading+)master
@@ -303,7 +303,7 @@ set(CPPCMS_SOURCES | |||
src/tcp_messenger.cpp | |||
src/tcp_connector.cpp | |||
src/tcp_cache_server.cpp | |||
src/connection_forwarder.cpp | |||
src/forwarder.cpp | |||
src/session_pool.cpp | |||
src/base_encryptor.cpp | |||
src/hmac_encryptor.cpp | |||
@@ -5,7 +5,11 @@ | |||
- Sessions **Interface** | |||
- Encoding Validators | |||
- Url Dispatcher | |||
- File upload: | |||
- create better pre-upload validation | |||
- create saving file to file | |||
- Reintergrate Sessions over TCP/IP | |||
- Forwarding management | |||
- Prefork-support | |||
- form.* | |||
Date-Time |
@@ -0,0 +1,46 @@ | |||
#ifndef CPPCMS_FORWARDER_H | |||
#define CPPCMS_FORWARDER_H | |||
#include <cppcms/defs.h> | |||
#include <booster/hold_ptr.h> | |||
#include <booster/shared_ptr.h> | |||
#include <booster/noncopyable.h> | |||
#include <booster/thread.h> | |||
#include <string> | |||
#include <map> | |||
namespace cppcms { | |||
class mount_point; | |||
namespace http { | |||
class context; | |||
} | |||
class CPPCMS_API forwarder { | |||
public: | |||
forwarder(); | |||
~forwarder(); | |||
void add_forwarding_rule(booster::shared_ptr<mount_point> p,std::string const &ip,int port); | |||
void remove_forwarding_rule(booster::shared_ptr<mount_point> p); | |||
typedef std::pair<std::string,int> address_type; | |||
address_type check_forwading_rules(std::string const &h,std::string const &s,std::string const &p); | |||
private: | |||
typedef std::map<booster::shared_ptr<mount_point> ,address_type> rules_type; | |||
rules_type rules_; | |||
booster::shared_mutex mutex_; | |||
struct _data; | |||
booster::hold_ptr<_data> d; | |||
}; | |||
/// | |||
/// Forward the connection handled by \a cont to other node at IP \a ip listenning to on port \a port over | |||
/// SCGI protocol. | |||
/// | |||
/// The context must be released first by calling cppcms::application::release_context() and it should not | |||
/// be used after this function call | |||
/// | |||
void CPPCMS_API forward_connection(booster::shared_ptr<http::context> cont,std::string const &ip,int port); | |||
} | |||
#endif |
@@ -1,40 +0,0 @@ | |||
/////////////////////////////////////////////////////////////////////////////// | |||
// | |||
// Copyright (C) 2008-2010 Artyom Beilis (Tonkikh) <artyomtnk@yahoo.com> | |||
// | |||
// This program is free software: you can redistribute it and/or modify | |||
// it under the terms of the GNU Lesser General Public License as published by | |||
// the Free Software Foundation, either version 3 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 Lesser General Public License for more details. | |||
// | |||
// You should have received a copy of the GNU Lesser General Public License | |||
// along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
// | |||
/////////////////////////////////////////////////////////////////////////////// | |||
#ifndef CPPCMS_CONNECTION_FORWARDER_H | |||
#define CPPCMS_CONNECTION_FORWARDER_H | |||
#include <cppcms/application.h> | |||
namespace cppcms { | |||
class CPPCMS_API connection_forwarder : public application { | |||
public: | |||
connection_forwarder(cppcms::service &srv,std::string const &ip,int port); | |||
~connection_forwarder(); | |||
virtual void main(std::string); | |||
private: | |||
struct _data; | |||
booster::hold_ptr<_data> d; | |||
std::string ip_; | |||
int port_; | |||
}; | |||
} | |||
#endif |
@@ -107,8 +107,6 @@ void connection::load_content(booster::system::error_code const &e,http::context | |||
std::string content_type = getenv("CONTENT_TYPE"); | |||
std::string s_content_length=getenv("CONTENT_LENGTH"); | |||
BOOSTER_DEBUG("cgi") << getenv("REQUEST_METHOD") << " " << getenv("REQUEST_URI"); | |||
long long content_length = s_content_length.empty() ? 0 : atoll(s_content_length.c_str()); | |||
if(content_length < 0) { | |||
@@ -17,10 +17,11 @@ | |||
// | |||
/////////////////////////////////////////////////////////////////////////////// | |||
#define CPPCMS_SOURCE | |||
#include "connection_forwarder.h" | |||
#include <cppcms/forwarder.h> | |||
#include <cppcms/http_context.h> | |||
#include <cppcms/http_request.h> | |||
#include <cppcms/http_response.h> | |||
#include <cppcms/mount_point.h> | |||
#include <cppcms/service.h> | |||
#include "service_impl.h" | |||
#include <cppcms/url_dispatcher.h> | |||
@@ -136,52 +137,81 @@ namespace cppcms { | |||
io::socket socket_; | |||
std::vector<char> input_; | |||
}; | |||
} // impl | |||
struct connection_forwarder::_data {}; | |||
std::string make_scgi_header(std::map<std::string,std::string> const &env,size_t addon_size) | |||
{ | |||
std::string env_str; | |||
env_str.reserve(1000); | |||
connection_forwarder::connection_forwarder(cppcms::service &srv,std::string const &ip,int port) : | |||
application(srv), | |||
ip_(ip), | |||
port_(port) | |||
{ | |||
} | |||
connection_forwarder::~connection_forwarder() | |||
{ | |||
} | |||
void connection_forwarder::main(std::string unused) | |||
{ | |||
booster::shared_ptr<http::context> con = release_context(); | |||
std::string env_str; | |||
env_str.reserve(1000); | |||
std::map<std::string,std::string>::const_iterator cl; | |||
std::pair<void *,size_t> post = con->request().raw_post_data(); | |||
std::map<std::string,std::string> const &env = con->connection().getenv(); | |||
std::map<std::string,std::string>::const_iterator cl; | |||
cl=env.find("CONTENT_LENGTH"); | |||
if(cl!=env.end()) { | |||
env_str.append(cl->first.c_str(),cl->first.size()+1); | |||
env_str.append(cl->second.c_str(),cl->second.size()+1); | |||
} | |||
else { | |||
env_str.append("CONTENT_LENGTH"); | |||
env_str.append("\0" "0",3); | |||
} | |||
cl=env.find("CONTENT_LENGTH"); | |||
if(cl!=env.end()) { | |||
env_str.append(cl->first.c_str(),cl->first.size()+1); | |||
env_str.append(cl->second.c_str(),cl->second.size()+1); | |||
} | |||
else { | |||
env_str.append("CONTENT_LENGTH"); | |||
env_str.append("\0" "0",3); | |||
for(std::map<std::string,std::string>::const_iterator p=env.begin();p!=env.end();++p) { | |||
if(p==cl) | |||
continue; | |||
env_str.append(p->first.c_str(),p->first.size()+1); | |||
env_str.append(p->second.c_str(),p->second.size()+1); | |||
} | |||
std::string header=(boost::format("%1%:",std::locale::classic()) % env_str.size()).str(); | |||
header.reserve(header.size()+env_str.size()+addon_size); | |||
header+=env_str; | |||
header+=','; | |||
return header; | |||
} | |||
for(std::map<std::string,std::string>::const_iterator p=env.begin();p!=env.end();++p) { | |||
if(p==cl) | |||
continue; | |||
env_str.append(p->first.c_str(),p->first.size()+1); | |||
env_str.append(p->second.c_str(),p->second.size()+1); | |||
} | |||
std::string header=(boost::format("%1%:",std::locale::classic()) % env_str.size()).str(); | |||
header.reserve(header.size()+env_str.size()+post.second); | |||
header+=env_str; | |||
header+=','; | |||
} // impl | |||
void forward_connection(booster::shared_ptr<http::context> con,std::string const &ip,int port) | |||
{ | |||
std::map<std::string,std::string> const &env = con->connection().getenv(); | |||
std::pair<void *,size_t> post = con->request().raw_post_data(); | |||
std::string header = impl::make_scgi_header(env,post.second); | |||
header.append(reinterpret_cast<char *>(post.first),post.second); | |||
booster::shared_ptr<impl::tcp_pipe> pipe(new impl::tcp_pipe(con,ip_,port_)); | |||
booster::shared_ptr<impl::tcp_pipe> pipe(new impl::tcp_pipe(con,ip,port)); | |||
pipe->async_send_receive(header); | |||
} | |||
struct forwarder::_data {}; | |||
forwarder::forwarder() | |||
{ | |||
} | |||
forwarder::~forwarder() | |||
{ | |||
} | |||
void forwarder::add_forwarding_rule(booster::shared_ptr<mount_point> p,std::string const &ip,int port) | |||
{ | |||
booster::unique_lock<booster::shared_mutex> lock(mutex_); | |||
rules_[p]=address_type(ip,port); | |||
} | |||
void forwarder::remove_forwarding_rule(booster::shared_ptr<mount_point> p) | |||
{ | |||
booster::unique_lock<booster::shared_mutex> lock(mutex_); | |||
rules_.erase(p); | |||
} | |||
forwarder::address_type forwarder::check_forwading_rules(std::string const &h,std::string const &s,std::string const &p) | |||
{ | |||
booster::shared_lock<booster::shared_mutex> lock(mutex_); | |||
for(rules_type::const_iterator it=rules_.begin();it!=rules_.end();++it) { | |||
if(it->first->match(h,s,p).first) | |||
return it->second; | |||
} | |||
return address_type(std::string(),0); | |||
} | |||
}; |
@@ -23,7 +23,7 @@ | |||
#include <cppcms/http_response.h> | |||
#include <cppcms/http_context.h> | |||
#include <cppcms/json.h> | |||
#include <connection_forwarder.h> | |||
#include <cppcms/forwarder.h> | |||
#include <iostream> | |||
#include "client.h" | |||
@@ -74,7 +74,7 @@ public: | |||
settings["http"]["script_names"][0]="/test"; | |||
srv.reset(new cppcms::service(settings)); | |||
app_=new cppcms::connection_forwarder(*srv,"127.0.0.1",8081); | |||
app_=new mini_forwarder(*srv); | |||
srv->applications_pool().mount(app_); | |||
} | |||
@@ -97,6 +97,13 @@ public: | |||
fw_ok=true; | |||
} | |||
private: | |||
struct mini_forwarder : public cppcms::application { | |||
mini_forwarder(cppcms::service &s) : cppcms::application(s) {} | |||
virtual void main(std::string unused) | |||
{ | |||
cppcms::forward_connection(release_context(),"127.0.0.1",8081); | |||
} | |||
}; | |||
booster::shared_ptr<cppcms::service> srv; | |||
booster::intrusive_ptr<cppcms::application> app_; | |||
}; | |||