3 #include "httpserver.h"
4 #include "httprequest.h"
5 #include "httphandler.h"
17 // HttpConnection -------------------------------------------------------------
19 HttpConnection::HttpConnection(HttpServer *server, QTcpSocket *socket)
24 setup_connections(socket);
27 HttpConnection::~HttpConnection()
29 if(m_handler) m_server->destroy_handler(m_handler);
32 void HttpConnection::setup_connections(QTcpSocket *socket)
34 connect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
35 connect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
38 void HttpConnection::delete_connections(QTcpSocket *socket)
40 disconnect(socket, SIGNAL(disconnected()), socket, SLOT(deleteLater()));
41 disconnect(socket, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
44 void HttpConnection::setup_connections(HttpHandler *handler)
46 connect(this, SIGNAL(attach(QSharedPointer<HttpRequest>)),
47 handler, SLOT(attach(QSharedPointer<HttpRequest>)));
49 connect(handler, SIGNAL(writeSocket(QByteArray)),
50 this, SLOT(onWriteSocket(QByteArray)));
51 connect(handler, SIGNAL(flushSocket()), this, SLOT(onFlushSocket()));
52 connect(handler, SIGNAL(closeSocket()), this, SLOT(onCloseSocket()));
54 connect(handler, SIGNAL(finished()), this, SLOT(end_response()));
57 void HttpConnection::delete_connections(HttpHandler *handler)
59 disconnect(this, SIGNAL(attach(QSharedPointer<HttpRequest>)),
60 handler, SLOT(attach(QSharedPointer<HttpRequest>)));
62 disconnect(handler, SIGNAL(writeSocket(QByteArray)),
63 this, SLOT(onWriteSocket(QByteArray)));
64 disconnect(handler, SIGNAL(flushSocket()), this, SLOT(onFlushSocket()));
65 disconnect(handler, SIGNAL(closeSocket()), this, SLOT(onCloseSocket()));
67 disconnect(handler, SIGNAL(finished()), this, SLOT(end_response()));
70 QTcpSocket* HttpConnection::socket()
72 return qobject_cast<QTcpSocket*>(parent());
75 void HttpConnection::onReadyRead()
77 QTcpSocket* sock = socket();
79 int size = sock->bytesAvailable();
81 QByteArray bytes = sock->read(size);
84 for(int i = 0; i <= LoopLimit; i++)
86 if(m_request.isNull())
88 m_request.reset(new HttpRequest);
89 m_parser.attach(m_request.data());
91 if(m_request->state() == HttpRequest::Initial
92 || m_request->state() == HttpRequest::Partial)
94 int n = m_parser.push(nRead, bytes);
95 assert(n || m_request->state() == HttpRequest::Ready);
98 if(m_request->state() == HttpRequest::Ready)
100 m_requests.push_back(m_request);
101 m_parser.detach(m_request.data());
105 if(nRead == size) break;
109 void HttpConnection::onWriteSocket(QByteArray bytes)
111 QTcpSocket *sock = socket();
112 int result = sock->write(bytes);
113 assert(bytes.size() == result);
116 void HttpConnection::onFlushSocket()
121 void HttpConnection::onCloseSocket()
129 void HttpConnection::begin_response()
133 if(m_handler) return; // 処理中の場合
134 if(m_requests.isEmpty()) return; // 処理すべきリクエストがない場合
136 QSharedPointer<HttpRequest> request(m_requests.front());
137 m_requests.pop_front();
138 m_handler = m_server->create_handler(request->method(), request->url());
139 if(!m_handler) // ハンドラが返ってこない場合、即断する。
141 QTcpSocket *sock = socket();
142 delete_connections(sock);
146 setup_connections(m_handler);
147 emit attach(request); // ハンドラと接続する。
153 void HttpConnection::end_response()
156 delete_connections(m_handler);
157 m_server->destroy_handler(m_handler);
162 // HttpServer -----------------------------------------------------------------
164 HttpServer::HttpServer(Settings *settings, QObject *parent)
166 , m_settings(settings)
167 , m_server(/* QObject */new QTcpServer(this))
168 , m_handler(/* QObject */new HttpHandler(this))
170 qRegisterMetaType<QSharedPointer<HttpRequest> >("QSharedPointer<HttpRequest>");
171 /* QObject */install(new HttpModule404(this));
172 connect(m_server, SIGNAL(newConnection()), this, SLOT(onNewConnection()));
174 quint16 port = m_settings->value("HttpServer/port").toUInt();
175 bool result = m_server->listen(QHostAddress::LocalHost, port);
176 if(!result) result = m_server->listen(QHostAddress::LocalHost, 0);
177 if(!result) qFatal("An error occured in HttpServer().");
180 quint16 HttpServer::port() const
182 return m_server->serverPort();
185 void HttpServer::install(HttpModule *module)
187 m_modules.push_front(module);
190 HttpHandler* HttpServer::create_handler(QByteArray method, QByteArray url)
192 for(HttpModule *module : m_modules)
193 if(HttpHandler *handler = module->create_handler(method, url))
195 m_handlers[handler] = module;
201 void HttpServer::destroy_handler(HttpHandler *handler)
203 auto it = m_handlers.find(handler);
204 assert(it != m_handlers.end());
205 it.value()->destroy_handler(handler);
206 int n = m_handlers.remove(handler);
210 void HttpServer::onNewConnection()
212 QTcpSocket *socket = m_server->nextPendingConnection();
213 /*ソケットによって保持*/ new HttpConnection(this, socket);