unter firefox:
Code:
Parse Request
HTTP Note: Request not complete termination not found
HTTP Note: Request not complete termination not found

Parse Request
Send answer
HTTP Note: switch to send mode!
HTTP Note: Sending
HTTP Note: Sending
HTTP Note: switch to recv mode!
unter chrome:
Code:
Parse Request
HTTP Note: Request not complete termination not found
HTTP Note: Request not complete termination not found

Parse Request
Send answer
HTTP Note: switch to send mode!
HTTP Note: switch to recv mode!
HTTP Note: switch to recv mode!
....
Code:
#include <fcntl.h>
#include <sys/epoll.h>
#include <cstdlib>
#include <config.h>
#include <errno.h>

#define READEVENT 0
#define SENDEVENT 1

#include "../queue.h"

using namespace libhttppp;

Queue::Queue(ServerSocket *socket) : ConnectionPool(socket) {
  struct epoll_event *events;
  struct epoll_event  event = {0};
  events = new epoll_event[(socket->getMaxconnections()*sizeof(struct epoll_event))];
  for(int i=0; i<socket->getMaxconnections(); i++)
    events[i].data.fd = -1;
  int epollfd = epoll_create(socket->getMaxconnections());
  
  if (epollfd == -1){
    _httpexception.Cirtical("can't create epoll");
    throw _httpexception;
  }
  
  event.events = EPOLLIN | EPOLLRDHUP;
  event.data.fd = socket->getSocket();
  if (epoll_ctl(epollfd, EPOLL_CTL_ADD, socket->getSocket(), &event) < 0){
    _httpexception.Cirtical("can't create epoll");
    throw _httpexception;
  }
  
  for(;;){
    int n = epoll_wait(epollfd, events, socket->getMaxconnections(), EPOLLWAIT);
    for(int i=0; i<n; i++) {
      if(events[i].data.fd == socket->getSocket()) {
        try{
          /*will create warning debug mode that normally because the check already connection
           * with this socket if getconnection throw they will be create a new one
           */
          ClientSocket *clientsocket = new ClientSocket;
	  clientsocket->setnonblocking();
          event.data.fd =_ServerSocket->acceptEvent(clientsocket);
          event.events = EPOLLIN | EPOLLRDHUP;
          Connection *curcon=addConnection(clientsocket);
          if(epoll_ctl(epollfd, EPOLL_CTL_ADD, event.data.fd, &event)==-1 && errno==EEXIST)
            epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
        }catch(HTTPException &e){
          if(e.isCritical())
            throw e;
        }
        continue;
      }
      
      if(events[i].events & EPOLLOUT) {
        try{
          Connection *curcon=getConnection(events[i].data.fd);
          if(curcon->getSendData()){
            _httpexception.Note("Sending");
            const char *senddata=curcon->getSendData()->getData();
            size_t sendsize=curcon->getSendData()->getDataSize();
            ssize_t sended=_ServerSocket->sendData(curcon->getClientSocket(),(void*)senddata,sendsize);
            if(sended==-1){
              _httpexception.Note("Sending Failed");
              if (errno == EAGAIN){
                continue;
	      }else{
		curcon->cleanSendData();
                goto CloseConnection;
	      }
            }else if(sended>0){
              curcon->resizeSendQueue(sended); 
            }else if(sended==0){
	      curcon->cleanSendData();
	    }
            continue;
          }else{
              event.events = EPOLLIN | EPOLLRDHUP;
              epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
	      _httpexception.Note("switch to recv mode!");
          }
        }catch(HTTPException &e){
           goto CloseConnection;
        }
      }
      
      if(events[i].events & EPOLLIN){
          try{
            Connection *curcon=getConnection(events[i].data.fd);
            char buf[BLOCKSIZE];
            int rcvsize=_ServerSocket->recvData(curcon->getClientSocket(),buf,BLOCKSIZE);
            if(rcvsize==-1){
               if (errno == EAGAIN)
                 continue;
               else
                 goto CloseConnection;
            }
            curcon->addRecvQueue(buf,rcvsize);
            RequestEvent(curcon);
            if(curcon->getSendData()){
              event.events = EPOLLOUT | EPOLLRDHUP;
              epoll_ctl(epollfd, EPOLL_CTL_MOD, events[i].data.fd, &event);
	      _httpexception.Note("switch to send mode!");
            }
          }catch(HTTPException &e){
            if(e.isCritical()){
              throw e;
            }
            if(e.isError())
             goto CloseConnection;
          }
      }
      
      if(events[i].events & EPOLLRDHUP || events[i].events & EPOLLERR) {
          CloseConnection:
            try{
              delConnection(events[i].data.fd);
              epoll_ctl(epollfd, EPOLL_CTL_DEL, events[i].data.fd, &event);
              continue;
            }catch(HTTPException &e){
              delConnection(events[i].data.fd);
            }
            continue;
          ;
      }
    }
  }
  if(events)
    delete[] events;  
}

Queue::~Queue(){

}