1 #include "httpserver.h"
2 #include "httprequest.h"
3 #include "httphandler.h"
13 // HttpConnection -------------------------------------------------------------
15 HttpConnection::HttpConnection(HttpServer *server, QTcpSocket *socket)
20 setup_connections(socket);
23 HttpConnection::~HttpConnection()
25 if(m_handler) m_server->destroy_handler(m_handler);
28 void HttpConnection::setup_connections(QTcpSocket *socket)
30 connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
31 connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
34 void HttpConnection::delete_connections(QTcpSocket *socket)
36 disconnect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
37 disconnect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
40 void HttpConnection::setup_connections(HttpHandler *handler)
42 connect(this, SIGNAL(attach(QSharedPointer<HttpRequest>)),
43 handler, SLOT(attach(QSharedPointer<HttpRequest>)));
45 connect(handler, SIGNAL(writeSocket(QByteArray)),
46 this, SLOT(onWriteSocket(QByteArray)));
47 connect(handler, SIGNAL(flushSocket()), this, SLOT(onFlushSocket()));
48 connect(handler, SIGNAL(closeSocket()), this, SLOT(onCloseSocket()));
50 connect(handler, SIGNAL(finished()), this, SLOT(end_response()));
53 void HttpConnection::delete_connections(HttpHandler *handler)
55 disconnect(this, SIGNAL(attach(QSharedPointer<HttpRequest>)),
56 handler, SLOT(attach(QSharedPointer<HttpRequest>)));
58 disconnect(handler, SIGNAL(writeSocket(QByteArray)),
59 this, SLOT(onWriteSocket(QByteArray)));
60 disconnect(handler, SIGNAL(flushSocket()), this, SLOT(onFlushSocket()));
61 disconnect(handler, SIGNAL(closeSocket()), this, SLOT(onCloseSocket()));
63 disconnect(handler, SIGNAL(finished()), this, SLOT(end_response()));
66 QTcpSocket* HttpConnection::socket()
68 return qobject_cast<QTcpSocket*>(parent());
71 void HttpConnection::onReadyRead()
73 QTcpSocket* sock = socket();
75 int size = sock->bytesAvailable();
77 QByteArray bytes = sock->read(size);
80 for(int i = 0; i <= LoopLimit; i++)
82 if(m_request.isNull())
84 m_request.reset(new HttpRequest);
85 m_parser.attach(m_request.data());
87 if(m_request->state() == HttpRequest::Initial
88 || m_request->state() == HttpRequest::Partial)
90 int n = m_parser.push(nRead, bytes);
91 assert(n || m_request->state() == HttpRequest::Ready);
94 if(m_request->state() == HttpRequest::Ready)
96 m_requests.push_back(m_request);
97 m_parser.detach(m_request.data());
101 if(nRead == size) break;
105 void HttpConnection::onWriteSocket(QByteArray bytes)
107 QTcpSocket *sock = socket();
108 int result = sock->write(bytes);
109 assert(bytes.size() == result);
112 void HttpConnection::onFlushSocket()
117 void HttpConnection::onCloseSocket()
125 void HttpConnection::begin_response()
129 if(m_handler) return; // 処理中の場合
130 if(m_requests.isEmpty()) return; // 処理すべきリクエストがない場合
132 QSharedPointer<HttpRequest> request(m_requests.front());
133 m_requests.pop_front();
134 m_handler = m_server->create_handler(request->method(), request->url());
135 if(!m_handler) // ハンドラが返ってこない場合、即断する。
137 QTcpSocket *sock = socket();
138 delete_connections(sock);
142 setup_connections(m_handler);
143 emit attach(request); // ハンドラと接続する。
149 void HttpConnection::end_response()
152 delete_connections(m_handler);
153 m_server->destroy_handler(m_handler);
158 // HttpServer -----------------------------------------------------------------
160 HttpServer::HttpServer(QObject *parent)
162 , m_server(/* QObject */new QTcpServer(this))
163 , m_handler(/* QObject */new HttpHandler(this))
165 qRegisterMetaType<QSharedPointer<HttpRequest> >("QSharedPointer<HttpRequest>");
166 /* QObject */install(new HttpModule404(this));
167 connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
170 bool HttpServer::listen(QList<quint16> ports, QHostAddress const &address)
172 for(quint16 n : ports) if(m_server->listen(address, n)) return true;
176 bool HttpServer::listen(quint16 port, QHostAddress const &address)
178 return m_server->listen(address, port);
181 quint16 HttpServer::port() const
183 return m_server->serverPort();
186 void HttpServer::install(HttpModule *module)
188 m_modules.push_front(module);
191 HttpHandler* HttpServer::create_handler(QByteArray method, QByteArray url)
193 for(HttpModule *module : m_modules)
194 if(HttpHandler *handler = module->create_handler(method, url))
196 m_handlers[handler] = module;
202 void HttpServer::destroy_handler(HttpHandler *handler)
204 auto it = m_handlers.find(handler);
205 assert(it != m_handlers.end());
206 it.value()->destroy_handler(handler);
207 int n = m_handlers.remove(handler);
211 void HttpServer::onNewConnection()
213 QTcpSocket *socket = m_server->nextPendingConnection();
214 /*ソケットによって保持*/ new HttpConnection(this, socket);