C++ のシンタックスハイライト対応
300 行くらい JavaScript 書いて C++ も色がつくようになった。やる気++。
/* Copyright (c) 2012 QtHttpServer Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the QtHttpServer nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL QTHTTPSERVER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef QHTTPCONNECTION_H
#define QHTTPCONNECTION_H
#include <QtNetwork/QTcpSocket>
class QHttpRequest;
class QHttpReply;
class QWebSocket;
class QHttpConnection : public QTcpSocket
{
Q_OBJECT
public:
#if QT_VERSION < 0x050000
explicit QHttpConnection(int socketDescriptor, QObject *parent = 0);
#else
explicit QHttpConnection(qintptr socketDescriptor, QObject *parent = 0);
#endif
~QHttpConnection();
const QHttpRequest *requestFor(QHttpReply *reply);
signals:
void ready(QHttpRequest *request, QHttpReply *reply);
void ready(QWebSocket *socket);
private:
class Private;
Private *d;
};
#endif // QHTTPCONNECTION_H
/* Copyright (c) 2012 QtHttpServer Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the QtHttpServer nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL QTHTTPSERVER BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "qhttpconnection_p.h"
#include <QtCore/QTime>
#include <QtCore/QUrl>
#include "qhttprequest.h"
#include "qhttpreply.h"
#include "qwebsocket.h"
class QHttpConnection::Private : public QObject
{
Q_OBJECT
public:
Private(QHttpConnection *parent);
private slots:
void upgrade(const QByteArray &to, const QUrl &url, const QHash<QByteArray, QByteArray> &rawHeaders);
void requestReady();
void replyDone(QObject *);
void websocketReady();
private:
QHttpConnection *q;
int keepAlive;
public:
QMap<QObject*, QHttpRequest*> requestMap;
QTime timer;
};
QHttpConnection::Private::Private(QHttpConnection *parent)
: QObject(parent)
, q(parent)
, keepAlive(100)
{
QHttpRequest *request = new QHttpRequest(q);
connect(request, SIGNAL(ready()), this, SLOT(requestReady()));
connect(request, SIGNAL(upgrade(QByteArray, QUrl, QHash<QByteArray, QByteArray>)), this, SLOT(upgrade(QByteArray, QUrl, QHash<QByteArray, QByteArray>)));
timer.start();
connect(q, SIGNAL(disconnected()), q, SLOT(deleteLater()));
}
void QHttpConnection::Private::upgrade(const QByteArray &to, const QUrl &url, const QHash<QByteArray, QByteArray> &rawHeaders)
{
QHttpRequest *request = qobject_cast<QHttpRequest *>(sender());
disconnect(request, 0, this, 0);
request->deleteLater();
if (to.toLower() == "websocket") {
QWebSocket *socket = new QWebSocket(q, url, rawHeaders);
connect(socket, SIGNAL(ready()), this, SLOT(websocketReady()));
}
}
void QHttpConnection::Private::requestReady()
{
QHttpRequest *request = qobject_cast<QHttpRequest *>(sender());
disconnect(request, SIGNAL(ready()), this, SLOT(requestReady()));
QHttpReply *reply = new QHttpReply(q);
connect(reply, SIGNAL(destroyed(QObject *)), this, SLOT(replyDone(QObject*)));
requestMap.insert(reply, request);
emit q->ready(request, reply);
if (request->hasRawHeader("Connection")) {
// qDebug() << request->rawHeader("Connection") << keepAlive;
if (request->rawHeader("Connection") == QByteArray("Keep-Alive").toLower()) {
if (keepAlive > 0) {
reply->setRawHeader("Keep-Alive", QString::fromUtf8("timeout=1, max=%1").arg(keepAlive--).toUtf8());
reply->setRawHeader("Connection", "Keep-Alive");
request = new QHttpRequest(q);
connect(request, SIGNAL(ready()), this, SLOT(requestReady()));
} else {
reply->setRawHeader("Connection", "Close");
keepAlive = 0;
}
} else {
reply->setRawHeader("Connection", "Close");
keepAlive = 0;
}
} else {
reply->setRawHeader("Connection", "Close");
keepAlive = 0;
}
}
void QHttpConnection::Private::replyDone(QObject *reply)
{
if (requestMap.contains(reply)) {
QHttpRequest *request = requestMap.take(reply);
request->deleteLater();
}
if (keepAlive == 0 && requestMap.isEmpty()) {
q->disconnectFromHost();
}
}
void QHttpConnection::Private::websocketReady()
{
QWebSocket *socket = qobject_cast<QWebSocket *>(sender());
disconnect(socket, SIGNAL(ready()), this, SLOT(websocketReady()));
emit q->ready(socket);
}
#if QT_VERSION < 0x050000
QHttpConnection::QHttpConnection(int socketDescriptor, QObject *parent)
#else
QHttpConnection::QHttpConnection(qintptr socketDescriptor, QObject *parent)
#endif
: QTcpSocket(parent)
, d(new Private(this))
{
setSocketOption(KeepAliveOption, 1);
setSocketDescriptor(socketDescriptor);
}
QHttpConnection::~QHttpConnection()
{
// qDebug() << d << socketDescriptor() << d->timer.elapsed();
// qDebug() << d->timer.elapsed();
}
const QHttpRequest *QHttpConnection::requestFor(QHttpReply *reply)
{
return d->requestMap.value(reply);
}
#include "qhttpconnection.moc"