Remoto - VFS: VFS_httpd.cpp Source File
Remoto - VFS
VFS_httpd.cpp
Go to the documentation of this file.
1 
2 #include "VFS_httpd.h"
3 
18 QHash<QString, QString> VFS_httpd::MIME_TYPES;
19 
33 VFS_httpd::VFS_httpd(quint16 port, QHostAddress addr, bool ssl, QString sslCertPath, QString sslKeyPath)
34 : VFS_tcp_server(port,addr,ssl,sslCertPath,sslKeyPath)
35 , _httpd(&_socket,port, this)
36 {
37  initMimes();
38 
39  //ssl stuff here!
40  //setSslConfiguration
41 }
42 
44 {
45 }
46 
53 {
54  return false;
55 }
56 
81 {
82  if (MIME_TYPES.size() > 0) return; //only init once
83 
84  MIME_TYPES.insert("html","text/html");
85  MIME_TYPES.insert("rhtml","text/html"); //our special type of processed html
86  MIME_TYPES.insert("js","text/javascript");
87  MIME_TYPES.insert("json","application/json");
88  MIME_TYPES.insert("css","text/css");
89  MIME_TYPES.insert("ico","image/ico");
90  MIME_TYPES.insert("png","image/png");
91  MIME_TYPES.insert("jpg","image/jpg");
92  MIME_TYPES.insert("jpeg","image/jpeg");
93  MIME_TYPES.insert("gif","image/gif");
94  MIME_TYPES.insert("eot","application/vnd.ms-fontobject");
95  MIME_TYPES.insert("svg","image/svg+xml");
96  MIME_TYPES.insert("ttf","application/x-font-ttf");
97  MIME_TYPES.insert("woff","text/plain");
98 }
99 
110 {
111  //if (_httpd.listen())
113  {
114  connect( &_httpd, SIGNAL( newRequest(QHttpRequest*, QHttpResponse*) ),
115  this, SLOT( handle(QHttpRequest*, QHttpResponse*) ) );
116 
117  return true;
118  }
119  else
120  VFS::WARN( QString("%1 could not listen on port %2. Is it already in use?").arg(className()).arg(_port) );
121 
122  return false;
123 }
124 
137 {
138  while(_socket.hasPendingConnections())
139  {
140  QTcpSocket *s = _socket.nextPendingConnection();
141 /*
142  VFS_tcp_client *client = newClient( s );//, _ssl, _sslConfiguration ); //if it is ssl, it will have already been negotiated, no?
143 
144  connect( client, SIGNAL( disconnected() ),
145  client, SLOT( deleteLater() ) );
146 
147  connect( client, SIGNAL( error(QAbstractSocket::SocketError) ),
148  this, SLOT( clientError(QAbstractSocket::SocketError) ) );
149 */
150  QHttpConnection *connection = new QHttpConnection(s, &_httpd);
151  connect(connection, SIGNAL(newRequest(QHttpRequest *, QHttpResponse *)),
152  &_httpd, SIGNAL(newRequest(QHttpRequest *, QHttpResponse *)) );
153 
154  //client->initSSL(); //seems like this should run, but theoretically we've already established encryption at this point
155  }
156 }
157 
168 void VFS_httpd::handle(QHttpRequest *req, QHttpResponse *resp)
169 {
170  VFS::LOG( QString("HTTP Request: %1").arg(req->url().toString()) );
171 
172  VFS_httpd_responder *r = new VFS_httpd_responder(req, resp); //as a new object so it can delete itself later
173  r->respond();
174 }
175 
176 /*
177 void VFS_httpd::addOutstandingRequest()
178 {
179  QTcpSocket *s = dynamic_cast<QTcpSocket *>(sender());
180 
181  s->startTimer(3000);
182 }
183 
184 void VFS_httpd::timeoutOutstandingRequest()
185 {
186  printf("TIMEOUT!\n");
187 
188  QTcpSocket *s = dynamic_cast<QTcpSocket *>(sender());
189 
190  s->close();
191 }
192 */
193 
206 VFS_httpd_responder::VFS_httpd_responder(QHttpRequest *req, QHttpResponse *resp)
207 : QObject(nullptr)
208 , _m_req(req)
209 , _m_resp(resp)
210 , _size(0)
211 , _status(404)
212 {
213 }
214 
222 {
223  //delete _m_req;
224  //delete _m_resp;
225 
226  //m_req->deleteLater();
227  //m_resp->deleteLater();
228 }
229 
237 {
238  VFS::WARN("HTTPD Responder should be overridden in a subclass... Responding with error page.");
239 
240  validatePath(_m_req->url()); //sets url and path
241 
242  switch(_status)
243  {
244  default: { _m_resp->writeHead(_status);
245  _m_resp->end( errorPage() );
246  }
247  break;
248  };
249 
250 // connect(_m_req, SIGNAL(data(const QByteArray&)), this, SLOT(accumulate(const QByteArray&)), Qt::UniqueConnection);
251  //connect(_m_req, SIGNAL(end()), this, SLOT(reply()));
252  //connect(_m_req, SIGNAL(end()), _m_resp, SLOT(end()));
253 // connect(_m_resp, SIGNAL(done()), this, SLOT(deleteLater()), Qt::UniqueConnection);
254 }
255 
264 {
265  _url = url;
266  _path = _url.path();
267 
268  _status = 403; //forbidden
269 }
270 
278 //this happens on a browser push?
279 void VFS_httpd_responder::accumulate(const QByteArray &data)
280 {
281  Q_UNUSED(data);
282 
283  VFS::ERROR("Accumulate!\n");
284  printf(" Accumulated: %s",qUtf8Printable(data));
285 
286  //m_resp->write(data);
287 }
288 
297 {
298  QString s = QString("%1: %2").arg(_status).arg(STATUS_CODES.value(_status));
299  QString r = QString("Requested: %1<br><i>Serving on port %2</i>").arg(_url.toString()).arg(_url.port());
300  QString e = QString("<html><head><title>%1</title></head><body><h1>%1</h1>%2</body></html>\n").arg(s).arg(r);
301 
302  return e.toUtf8();
303 }
304 
Holds the request and response objects for future use.
Definition: VFS_httpd.h:45
QHttpResponse * _m_resp
http response object
Definition: VFS_httpd.h:55
QUrl _url
requested url
Definition: VFS_httpd.h:57
virtual void accumulate(const QByteArray &)
This seems to be used during an http push request.
Definition: VFS_httpd.cpp:279
QString _path
path component of url
Definition: VFS_httpd.h:58
VFS_httpd_responder(QHttpRequest *req, QHttpResponse *resp)
Definition: VFS_httpd.cpp:206
QHttpRequest * _m_req
http request object
Definition: VFS_httpd.h:54
virtual QByteArray errorPage()
The default error page.
Definition: VFS_httpd.cpp:296
virtual ~VFS_httpd_responder()
VFS_httpd_responder destructor.
Definition: VFS_httpd.cpp:221
virtual void validatePath(QUrl url)
Validates the incoming path.
Definition: VFS_httpd.cpp:263
virtual void respond()
Send an http response back to the client.
Definition: VFS_httpd.cpp:236
int _status
http status
Definition: VFS_httpd.h:61
VFS_httpd(quint16 port, QHostAddress addr=QHostAddress::Any, bool ssl=false, QString sslCertPath="", QString sslKeyPath="")
VFS_httpd constructor.
Definition: VFS_httpd.cpp:33
virtual bool isContainer()
A VFS_httpd node cannot contain children.
Definition: VFS_httpd.cpp:52
QHttpServer _httpd
QHttpServer instance.
Definition: VFS_httpd.h:27
virtual void createNewConnection()
The server has received a new http connection request.
Definition: VFS_httpd.cpp:136
virtual void handle(QHttpRequest *req, QHttpResponse *resp)
Handle an incoming http request.
Definition: VFS_httpd.cpp:168
virtual ~VFS_httpd()
Definition: VFS_httpd.cpp:43
void initMimes()
Initialize the mime map.
Definition: VFS_httpd.cpp:80
virtual bool listen()
Start listening for incoming connections.
Definition: VFS_httpd.cpp:109
static QHash< QString, QString > MIME_TYPES
The mime type map.
Definition: VFS_httpd.h:24
QString className()
Return the class name of a node.
Definition: VFS_node.cpp:2039
Open a listening TCP port for other clients to connect to.
virtual bool listen()
Open the server socket and listen for new connections.
VFSQTcpServer _socket
TCP socket used for connections.
quint16 _port
TCP port to listen on, or 0 to find an available one.
static void LOG(QString message, int level=0, QString user="server")
Send a message to the VFS::_messages VFS_stream.
Definition: VFS.cpp:209
static void ERROR(QString message, int level=0, QString user="server")
Send a message to the VFS::_errors VFS_stream.
Definition: VFS.cpp:307
static void WARN(QString message, int level=0, QString user="server")
Send a message to the VFS::_warnings VFS_stream.
Definition: VFS.cpp:258
url(value, options)