PageRenderTime 123ms CodeModel.GetById 60ms app.highlight 15ms RepoModel.GetById 45ms app.codeStats 0ms

/thirdparty/qxt/qxtweb-standalone/qxtweb/qxtscgiserverconnector.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 191 lines | 106 code | 27 blank | 58 comment | 12 complexity | 0eff8a466b12d20b66de86bc98eba680 MD5 | raw file
  1/****************************************************************************
  2 **
  3 ** Copyright (C) Qxt Foundation. Some rights reserved.
  4 **
  5 ** This file is part of the QxtWeb module of the Qxt library.
  6 **
  7 ** This library is free software; you can redistribute it and/or modify it
  8 ** under the terms of the Common Public License, version 1.0, as published
  9 ** by IBM, and/or under the terms of the GNU Lesser General Public License,
 10 ** version 2.1, as published by the Free Software Foundation.
 11 **
 12 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
 13 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
 14 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
 15 ** FITNESS FOR A PARTICULAR PURPOSE.
 16 **
 17 ** You should have received a copy of the CPL and the LGPL along with this
 18 ** file. See the LICENSE file and the cpl1.0.txt/lgpl-2.1.txt files
 19 ** included with the source distribution for more information.
 20 ** If you did not receive a copy of the licenses, contact the Qxt Foundation.
 21 **
 22 ** <http://libqxt.org>  <foundation@libqxt.org>
 23 **
 24 ****************************************************************************/
 25
 26/*!
 27\class QxtScgiServerConnector
 28
 29\inmodule QxtWeb
 30
 31\brief The QxtScgiServerConnector class provides an SCGI connector for QxtHttpSessionManager
 32
 33
 34QxtScgiServerConnector implements the SCGI protocoll supported by almost all modern web servers.
 35
 36
 37
 38\sa QxtHttpSessionManager
 39*/
 40#include "qxthttpsessionmanager.h"
 41#include "qxtwebevent.h"
 42#include <QTcpServer>
 43#include <QHash>
 44#include <QTcpSocket>
 45#include <QString>
 46
 47#ifndef QXT_DOXYGEN_RUN
 48class QxtScgiServerConnectorPrivate : public QxtPrivate<QxtScgiServerConnector>
 49{
 50public:
 51    QTcpServer* server;
 52};
 53#endif
 54
 55/*!
 56 * Creates a QxtHttpServerConnector with the given \a parent.
 57 */
 58QxtScgiServerConnector::QxtScgiServerConnector(QObject* parent) : QxtAbstractHttpConnector(parent)
 59{
 60    QXT_INIT_PRIVATE(QxtScgiServerConnector);
 61    qxt_d().server = new QTcpServer(this);
 62    QObject::connect(qxt_d().server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
 63}
 64
 65/*!
 66 * \reimp
 67 */
 68bool QxtScgiServerConnector::listen(const QHostAddress& iface, quint16 port)
 69{
 70    return qxt_d().server->listen(iface, port);
 71}
 72
 73/*!
 74 * \internal
 75 */
 76void QxtScgiServerConnector::acceptConnection()
 77{
 78    QTcpSocket* socket = qxt_d().server->nextPendingConnection();
 79    addConnection(socket);
 80}
 81
 82/*!
 83 * \reimp
 84 */
 85bool QxtScgiServerConnector::canParseRequest(const QByteArray& buffer)
 86{
 87    if (buffer.size() < 10)
 88        return false;
 89    QString expectedsize;
 90    for (int i = 0;i < 10;i++)
 91    {
 92        if (buffer.at(i) == ':')
 93        {
 94            break;
 95        }
 96        else
 97        {
 98            expectedsize += buffer.at(i);
 99        }
100    }
101
102    if (expectedsize.isEmpty())
103    {
104        //protocoll error
105        return false;
106    }
107
108    return (buffer.size() > expectedsize.toInt());
109}
110
111/*!
112 * \reimp
113 */
114QHttpRequestHeader QxtScgiServerConnector::parseRequest(QByteArray& buffer)
115{
116    QString expectedsize_s;
117    for (int i = 0;i < 20;i++)
118    {
119        if (buffer.at(i) == ':')
120        {
121            break;
122        }
123        else
124        {
125            expectedsize_s += buffer.at(i);
126        }
127    }
128
129    if (expectedsize_s.isEmpty())
130    {
131        //protocoll error
132        return QHttpRequestHeader();
133    }
134
135
136    buffer = buffer.right(buffer.size() - (expectedsize_s.count() + 1));
137
138
139    QHttpRequestHeader request_m;
140
141    QByteArray name;
142    int i = 0;
143    while ((i = buffer.indexOf('\0')) > -1)
144    {
145        if (name.isEmpty())
146        {
147            name = buffer.left(i);
148        }
149        else
150        {
151            request_m.setValue(QString::fromAscii(name).toLower(), QString::fromAscii(buffer.left(i)));
152            name = "";
153        }
154        buffer = buffer.mid(i + 1);
155    }
156
157
158    request_m.setRequest(request_m.value("request_method"), request_m.value("request_uri"), 1, 0);
159
160
161    foreach(const QString& key, request_m.keys())
162    {
163        if (key.startsWith(QString("http_")))
164        {
165            request_m.setValue(key.right(key.size() - 5), request_m.value(key));
166        }
167    }
168
169    request_m.setValue("Connection", "close");
170
171
172    buffer.chop(1);
173
174
175    return request_m;
176}
177
178/*!
179 * \reimp
180 */
181void QxtScgiServerConnector::writeHeaders(QIODevice* device, const QHttpResponseHeader& response_m)
182{
183
184    device->write(("Status:" + QString::number(response_m.statusCode()) + ' ' + response_m.reasonPhrase() + "\r\n").toAscii());
185
186    foreach(const QString& key, response_m.keys())
187    {
188        device->write((key + ':' + response_m.value(key) + "\r\n").toAscii());
189    }
190    device->write("\r\n");
191}