/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #ifndef CPPCMS_IMPL_CGI_API_H #define CPPCMS_IMPL_CGI_API_H #include #include #include #include #include #include #include #include #include #include #include #include "string_map.h" namespace booster { namespace aio { class io_service; class acceptor; class stream_socket; } } namespace cppcms { class service; class application; namespace http { class context; class request; class response; } namespace impl { class multipart_parser; namespace cgi { typedef booster::callback handler; typedef booster::callback io_handler; typedef booster::callback callback; typedef cppcms::http::context::handler ehandler; class connection; class acceptor : public booster::noncopyable { public: virtual void async_accept() = 0; virtual booster::aio::acceptor &socket() = 0; #ifndef CPPCMS_WIN32 virtual booster::shared_ptr accept(int fd) = 0; #endif virtual void sndbuf(int v) = 0; virtual void rcvbuf(int v) = 0; virtual void stop() = 0; virtual ~acceptor(){} }; class CPPCMS_API connection : public booster::noncopyable, public booster::enable_shared_from_this { public: connection(cppcms::service &srv); virtual ~connection(); cppcms::service &service(); void async_prepare_request( http::context *context, ehandler const &on_post_data_ready); void async_write_response( http::response &response, bool complete_response, ehandler const &on_response_written); void aync_wait_for_close_by_peer(callback const &on_eof); std::string getenv(std::string const &key) { return env_.get_safe(key.c_str()); } char const *cgetenv(char const *key) { return env_.get_safe(key); } std::string getenv(char const *key) { return env_.get_safe(key); } virtual std::map const &getenv() { if(map_env_.empty() && env_.begin()!=env_.end()) { for(string_map::iterator p=env_.begin();p!=env_.end();++p) { map_env_[p->key]=p->value; } } return map_env_; } bool is_reuseable(); std::string last_error(); /****************************************************************************/ // These are abstract member function that should be implemented by // actual protocol like FCGI, SCGI, HTTP or CGI public: bool has_pending(); virtual bool nonblocking_write(booster::aio::const_buffer const &buf,bool eof,booster::system::error_code &e); virtual void async_write(booster::aio::const_buffer const &buf,bool eof,handler const &h); virtual bool write(booster::aio::const_buffer const &buf,bool eof,booster::system::error_code &e); virtual void on_async_write_start() = 0; virtual void on_async_write_progress(bool completed) = 0; virtual void do_eof() = 0; virtual booster::aio::const_buffer format_output(booster::aio::const_buffer const &in,bool completed,booster::system::error_code &e) = 0; virtual bool write_to_socket(booster::aio::const_buffer const &in,booster::system::error_code &e); virtual booster::aio::io_service &get_io_service() = 0; protected: void append_pending(booster::aio::const_buffer const &new_data); virtual booster::aio::stream_socket &socket() = 0; virtual void async_read_headers(handler const &h) = 0; virtual bool keep_alive() = 0; // Concept implementation headers virtual void async_read_some(void *,size_t,io_handler const &h) = 0; virtual void on_async_read_complete() {} virtual void async_read_eof(callback const &h) = 0; /****************************************************************************/ protected: string_pool pool_; string_map env_; std::vector pending_output_; booster::shared_ptr self(); void async_read(void *,size_t,io_handler const &h); private: struct reader; struct cgi_forwarder; struct async_write_binder; struct async_write_handler; friend struct reader; friend struct writer; friend struct async_write_binder; friend struct async_write_handler; friend struct cgi_forwarder; void set_error(ehandler const &h,std::string s); void on_headers_read(booster::system::error_code const &e,http::context *,ehandler const &h); void load_content(http::context *,ehandler const &h); void on_some_content_read(booster::system::error_code const &e,size_t n,http::context *,ehandler const &h); void handle_eof(callback const &on_eof); void handle_http_error(int code,http::context *context,ehandler const &h); void handle_http_error_eof(booster::system::error_code const &e,int code,ehandler const &h); cppcms::service *service_; std::string async_chunk_; std::string error_; bool request_in_progress_; std::map map_env_; booster::intrusive_ptr cached_async_write_binder_; }; } // cgi } // impl } // cppcms #endif