1 /****************************************************************************
3 ** Copyright (C) Qxt Foundation. Some rights reserved.
5 ** This file is part of the QxtWeb module of the Qt eXTension library
7 ** This library is free software; you can redistribute it and/or modify it
8 ** under the terms of th Common Public License, version 1.0, as published by
11 ** This file is provided "AS IS", without WARRANTIES OR CONDITIONS OF ANY
12 ** KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
13 ** WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR
14 ** FITNESS FOR A PARTICULAR PURPOSE.
16 ** You should have received a copy of the CPL along with this file.
17 ** See the LICENSE file and the cpl1.0.txt file included with the source
18 ** distribution for more information. If you did not receive a copy of the
19 ** license, contact the Qxt Foundation.
21 ** <http://libqxt.org> <foundation@libqxt.org>
23 ****************************************************************************/
24 #include "qxtscgiconnector.h"
31 class QxtScgiConnectorPrivate : public QTcpServer,public QxtPrivate<QxtScgiConnector>
33 QXT_DECLARE_PUBLIC(QxtScgiConnector);
37 void incomingConnection ( int socketDescriptor )
39 qDebug("%i, -> incomming",(int)time(NULL));
40 QTcpSocket * tcpSocket = new QTcpSocket;
41 if (!tcpSocket->setSocketDescriptor(socketDescriptor))
48 connect(tcpSocket,SIGNAL(disconnected()),tcpSocket,SLOT(deleteLater())); ///TODO:right. and what id the client disconnects earlier?
50 int eee1=readHeaderFromSocket(tcpSocket,SERVER);
53 tcpSocket->write("Status: 500 INTERNAL SERVER ERROR\r\ncontent-type: text/html\r\n\r\nHEADER NOT READABLE");
56 emit(qxt_p().incomming(SERVER));
59 QTcpSocket * socket_m;
63 int readHeaderFromSocket(QTcpSocket * tcpSocket,server_t & SERVER)
69 ///--------------get the header size----------------
72 while (!size_in.endsWith(':'))
74 if (!tcpSocket->bytesAvailable ())
75 if (!tcpSocket->waitForReadyRead (200))
78 char a[4]; ///4? yes, i know i'm paranoid about bounds.
81 if (!tcpSocket->read (a, 1 ))
86 if (size_in.size()>20)/// after the 20ths char is an attack atemp for sure
93 int size=size_in.toInt()+1;
96 if (size>10240) ///do not accept headers over 10kb
100 ///--------------read the header------------------
102 while (tcpSocket->bytesAvailable ()<size)
104 if (!tcpSocket->waitForReadyRead (200))
107 QByteArray header_in;
108 header_in.resize(size);
110 if (tcpSocket->read (header_in.data(), size )!=size)
113 if (!header_in.endsWith(','))
115 ///--------------parse the header------------------
120 QByteArray a =header_in;
121 while ((i=a.indexOf('\0'))>-1)
125 name= a.left(i).replace('\0',"");
129 SERVER[name]=a.left(i).replace('\0',"").replace("%20"," ");
147 QxtScgiConnector::QxtScgiConnector():QxtAbstractWebConnector()
149 QXT_INIT_PRIVATE(QxtScgiConnector);
153 int QxtScgiConnector::start (quint16 port,const QHostAddress & address)
155 return qxt_d().listen(address,port);
158 QIODevice * QxtScgiConnector::socket()
160 return qxt_d().socket_m;
162 void QxtScgiConnector::sendHeader(server_t & answer)
164 if (!answer.contains("Status"))
165 answer["Status"]="200 OK";
166 if (!answer.contains("Content-Type"))
167 answer["Content-Type"]="text/html; charset=utf-8";
169 server_t::const_iterator i = answer.constBegin();
170 while (i != answer.constEnd())
172 qxt_d().socket_m->write(i.key()+": "+i.value()+"\r\n");
175 qxt_d().socket_m->write("\r\n");
178 void QxtScgiConnector::close()
180 emit(aboutToClose());
181 qxt_d().socket_m->close();
185 QByteArray QxtScgiConnector::content(quint64 maxsize)
187 QIODevice * tcpSocket= qxt_d().socket_m;
193 unsigned int content_size= qxt_d().SERVER["CONTENT_LENGTH"].toUInt();
195 qDebug()<<"receiving content"<<content_size;
203 if (content_size>maxsize)
204 content_size=maxsize;
206 ///--------------read the content------------------
212 while (tcpSocket->bytesAvailable ()<content_size)
214 if (!tcpSocket->waitForReadyRead (2000))
218 QByteArray content_in;
219 content_in.resize(content_size);
222 if (tcpSocket->read (content_in.data(), content_size )!=content_size)
226 tcpSocket->readAll(); //fix apache fcgi bug