diff options
Diffstat (limited to '0.8/src/sock/sock.cpp')
| -rw-r--r-- | 0.8/src/sock/sock.cpp | 446 |
1 files changed, 0 insertions, 446 deletions
diff --git a/0.8/src/sock/sock.cpp b/0.8/src/sock/sock.cpp deleted file mode 100644 index fdba716..0000000 --- a/0.8/src/sock/sock.cpp +++ /dev/null @@ -1,446 +0,0 @@ -/*:* - *: File: ./src/sock/sock.cpp - *: - *: yChat; Homepage: ychat.buetow.org; Version 0.9.0-CURRENT - *: - *: Copyright (C) 2003 Paul C. Buetow, Volker Richter - *: Copyright (C) 2004 Paul C. Buetow - *: Copyright (C) 2005 EXA Digital Solutions GbR - *: Copyright (C) 2006, 2007 Paul C. Buetow - *: - *: 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - *:*/ - -#ifndef SOCK_CPP -#define SOCK_CPP - -#include <arpa/inet.h> -#include <errno.h> -#include <sys/types.h> -#include <unistd.h> -#include <fcntl.h> - -#include "sock.h" -#include "../tool/tool.h" - -using namespace std; - -vector< sock* > sock::vec_socks; -int sock::i_id_counter = 0; - -sock::sock() -{ - this->i_id = ++i_id_counter; - - this->b_run = true; - this->i_req = 0; - this->p_reqp = new reqp(); - -#ifdef LOGGING - this->log_daemon = new logd( wrap::CONF->get_elem( "httpd.logging.accessfile" ), - wrap::CONF->get_elem( "httpd.logging.access_lines" ) ); -#endif - - this->p_ip_cache_map = new shashmap < string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> >; - vec_socks.push_back(this); -} - -//<<* -/* -void -sock::chat_stream(context *p_context, string s_msg) -{ - p_user->set_context(p_sock); - - _send(p_sock, s_msg.c_str(), s_msg.size()); // FOOBAR - - for (int i = 0; i < PUSHSTR; ++i) - _send(p_sock, " \n", 2); - - p_user->set_sock(p_sock); -} -*/ -//*>> - -int -sock::_make_server_socket( int i_port ) -{ - size_t i_sock; - struct sockaddr_in name; - - // create the server socket. - i_sock = socket (AF_INET, SOCK_STREAM, 0); - // i_sock = socket (PF_INET, SOCK_STREAM, 0); - if (i_sock < 0) - { - wrap::system_message(SOCKERR, errno); - - if ( ++i_port > MAXPORT ) - exit(1); - - wrap::system_message(SOCKERR, errno); - - return _make_server_socket( i_port ); - } - - // give the server socket a name. - name.sin_family = AF_INET; - name.sin_addr.s_addr = htonl(INADDR_ANY); - name.sin_port = htons(i_port); - int i_optval = 1; - - if (bind(i_sock, (struct sockaddr *) &name, sizeof (name)) < 0) - { - wrap::system_message(BINDERR, errno); - - if (++i_port > MAXPORT) - exit(1); - - wrap::system_message(string(SOCKERR) + tool::int2string(i_port)); - - // Re-run recursive. - return _make_server_socket(i_port); - } - - setsockopt(i_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&i_optval, sizeof(int)); - - if (set_nonblock(i_server_sock) < 0) - { - wrap::system_message(NONBLER, errno); - exit(EXIT_FAILURE); - } - - wrap::system_message(SOCKCRT + string("localhost:") + tool::int2string(i_port)); - - i_server_port = i_port; - i_server_sock = i_sock; - - if (listen(i_sock, BACKLOG) < 0) - { - wrap::system_message(LISTERR, errno); - exit(EXIT_FAILURE); - } - - wrap::system_message(SOCKRDY); - return i_sock; -} - -#ifdef OPENSSL -// This method is virtual, and is overloaded by sslsock! -bool -sock::_main_loop_do_ssl_stuff(int &i_new_sock) -{ - return 0; -} -#endif - -void -sock::process_request() -{ - int i; - struct sockaddr_in clientname; - socklen_t size; - - ++i_req; - int i_client_sock = accept(i_server_sock, (struct sockaddr *) &clientname, &size); - - if (i_client_sock == -1) - { - switch (errno) - { - case EAGAIN: - case EINTR: - return; - } - } - - if (0 < set_nonblock(i_client_sock)) - { - wrap::system_message(NONBCER, errno); - } - -#ifdef OPENSSL - _main_loop_do_ssl_stuff(i_client_sock); -#endif - -#ifdef VERBOSE - wrap::system_message(NEWREQU - + tool::int2string(i_req) + " " - + string(inet_ntoa( clientname.sin_addr )) + ":" - + tool::int2string(ntohs ( clientname.sin_port )) - + " @" + tool::int2string(get_id()) - ); -#endif - - context *p_context = new context(this, new struct event, i_client_sock); - - event_set(p_context->p_event, i_client_sock, EV_READ , handle_client_read, p_context); - event_add(p_context->p_event, NULL); -} - -void -sock::clean_ipcache() -{ - int i_ipcachesize = wrap::CONF->get_int("httpd.ipcachesize"); - int i_currentsize = p_ip_cache_map->size(); - - if (i_currentsize > 0 && (i_ipcachesize == 0 || i_ipcachesize <= i_currentsize)) - wrap::system_message(SOCKCA2+tool::int2string(i_currentsize)+","+tool::int2string(i_ipcachesize)+")"); -} - -void -sock::init_event_handlers() -{ - for (vector< sock* >::iterator iter = sock::vec_socks.begin(); - iter != sock::vec_socks.end(); ++iter) - { - wrap::system_message(EVENTSO, (*iter)->get_id()); - (*iter)->init_server_event_handler(); - } -} - -void -sock::init_server_event_handler() -{ - event_set(&ev_handle_server_accept, i_server_sock, EV_READ | EV_PERSIST, handle_server_accept, this); - event_add(&ev_handle_server_accept, NULL); -} - -void -sock::handle_server_accept(int i_fd, short event, void *p_arg) -{ - sock *p_sock = static_cast<sock*>(p_arg); - p_sock->process_request(); -} - -void -sock::handle_client_read(int i_fd, short event, void *p_arg) -{ - static int i_size = READSOCK * sizeof(char); - context *p_context = static_cast<context*>(p_arg); - - if (-1 == read(i_fd, p_context->c_buf, i_size)) - { - switch (errno) - { - case EAGAIN: - case EINTR: - event_add(p_context->p_event, NULL); - return; - } - } - p_context->del_event(); - - string s_buf(p_context->c_buf); - string s_query(""); - - bool b_is_post_request; - - if (strncmp("POST", p_context->c_buf, 4) == 0) - { - b_is_post_request = true;; - - int i_pos = s_buf.find(" HTTP", 0) + 1; - - if (i_pos == string::npos && i_pos <= 5) - { - wrap::system_message(HTTPERR); - delete p_context; - return; - } - - s_query.append(s_buf.substr(5, i_pos - 5)); - } - - else if (strncmp("GET", p_context->c_buf, 3) == 0) - { - b_is_post_request = false; - int i_pos = s_buf.find(" HTTP", 0) + 1; - - if (i_pos == string::npos && i_pos <= 5) - { - wrap::system_message(HTTPERR); - delete p_context; - return; - } - - s_query.append(s_buf.substr(5, i_pos - 5)); - } - - // Invalid request - else - { - wrap::system_message(HTTPERR); - delete p_context; - return; - } - - // Remove /.. from the query - int i_pos, i_pos2; - while ( (i_pos = s_query.find("/..")) != string::npos ) - s_query.replace(i_pos, 3, "/"); - - sock *p_sock = p_context->p_sock; - - p_context->p_map_params = new map<string, string>; - map<string, string>& map_params = *p_context->p_map_params; - - struct sockaddr_in client; - static socklen_t client_size = sizeof(client); - getpeername(i_fd, (struct sockaddr *) &client, &client_size); - - shashmap< string, unsigned, self_hash<unsigned>, equals_allocator<unsigned> > *p_ip_cache_map - = p_sock->get_ip_cache_map(); - - unsigned &i_addr = client.sin_addr.s_addr; - - if ( (map_params["REMOTE_ADDR"] = p_ip_cache_map->get_elem(i_addr)) == "" ) - { - map_params["REMOTE_ADDR"] = string(inet_ntoa(client.sin_addr)); - p_ip_cache_map->set_elem(map_params["REMOTE_ADDR"], i_addr); - wrap::system_message(SOCKCAC+map_params["REMOTE_ADDR"]); - } - - // Get HTTP Header values - i_pos = s_buf.find("\n"); - if (i_pos != string::npos) - { - map_params["QUERY_STRING"] = tool::trim(s_buf.substr(0,i_pos-1)); - - do - { - string s_line(s_buf.substr(0, i_pos)); - i_pos2 = s_line.find(":"); - - if (i_pos2 != string::npos && s_line.length() > i_pos2+1) - map_params[ tool::trim(s_line.substr(0, i_pos2)) ] = tool::trim(s_line.substr(i_pos2+1)); - - s_buf = s_buf.substr(s_line.size() + 1); - i_pos = s_buf.find("\n"); - - } - while (i_pos != string::npos); - } - - // Get request string parameters - string s_parameters = tool::url_decode(s_query); - string s_tmp, s_request(""); - - if ( (i_pos = s_parameters.find("?")) != string::npos) - { - s_request.append(s_parameters.substr(0, i_pos)); - s_parameters = s_parameters.substr(i_pos+1); - } - - else if ( (i_pos = s_parameters.find(" ")) != string::npos) - { - s_request.append(s_parameters.substr(0, i_pos)); - } - - else - { - s_request.append(s_parameters); - } - - if (b_is_post_request) - s_parameters = s_buf; - - while ( (i_pos = s_parameters.find("&")) != string::npos ) - { - s_tmp = s_parameters.substr(0, i_pos ); - - if ( (i_pos2 = s_tmp.find("=")) != string::npos ) - map_params[ s_tmp.substr(0, i_pos2) ] = tool::replace( s_tmp.substr( i_pos2+1 ), "\\AND", "&"); - - s_parameters = s_parameters.substr(i_pos+1); - } - - // Get the last request parameter, which does not have a "&" on the end! - if ( (i_pos = s_parameters.find("=")) != string::npos ) - { - if ( (i_pos2 = s_parameters.find(" ")) != string::npos ) - map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr(i_pos+1, i_pos2-i_pos-1); - else - map_params[ s_parameters.substr(0, i_pos) ] = s_parameters.substr(i_pos+1); - } - -#ifdef VERBOSE - wrap::system_message(REQUEST + s_request); -#endif - - if (s_request.empty()) - s_request = wrap::CONF->get_elem("httpd.startsite"); - - map_params["request"] = s_request; - - { - string s_ext(tool::get_extension(s_request)); - - if ( s_ext == "" ) - s_ext = "default"; - - map_params["content-type"] = wrap::CONF->get_elem( "httpd.contenttypes." + s_ext ); - } - -//#ifdef VERBOSE -// for (map<string, string>::iterator i = map_params.begin(); i != map_params.end(); ++i) -// cout << "=>" << i->first << "=" << i->second << "<=" << endl; -//#endif - - p_context->p_response = new string(""); - p_sock->get_req_parser()->parse(p_context); - - struct event *p_ev_handle_client_write = new struct event; - p_context->p_event = p_ev_handle_client_write; - - event_set(p_ev_handle_client_write, i_fd, EV_WRITE, handle_client_write, p_context); - event_add(p_ev_handle_client_write, NULL); -} - -void -sock::handle_client_write(int i_fd, short event, void *p_arg) -{ - static int i_char_size = sizeof(char); - - context *p_context = static_cast<context*>(p_arg); - string *p_response = p_context->p_response; - - if (-1 == write(i_fd, p_response->c_str(), p_response->length()*i_char_size)) - { - switch (errno) - { - case EAGAIN: - case EINTR: - event_add(p_context->p_event, NULL); - return; - } - } - - delete p_context; -} - -int -sock::set_nonblock(int i_sock) -{ - if (fcntl(i_sock, F_SETFL, O_NONBLOCK) < 0) - { - wrap::system_message(SOCKER5, errno); - return -1; - } - - return 0; -} - -#endif |
