2011-11-15 16:44:47 +04:00
|
|
|
/*
|
|
|
|
This file is part of the PhantomJS project from Ofi Labs.
|
|
|
|
|
|
|
|
Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com
|
2012-07-05 04:22:30 +04:00
|
|
|
Copyright (C) 2011 Ivan De Marino <ivan.de.marino@gmail.com>
|
2011-11-15 16:44:47 +04:00
|
|
|
Author: Milian Wolff <milian.wolff@kdab.com>
|
|
|
|
|
|
|
|
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 <organization> 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 <COPYRIGHT HOLDER> 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 "webserver.h"
|
|
|
|
|
2012-12-18 11:12:48 +04:00
|
|
|
#include "encoding.h"
|
2012-02-10 22:42:38 +04:00
|
|
|
#include "mongoose/mongoose.h"
|
2013-06-21 04:41:20 +04:00
|
|
|
#include "consts.h"
|
2011-12-20 20:24:08 +04:00
|
|
|
|
2011-12-20 06:18:08 +04:00
|
|
|
#include <QByteArray>
|
2011-11-07 19:16:54 +04:00
|
|
|
#include <QHostAddress>
|
2011-12-05 10:34:44 +04:00
|
|
|
#include <QMetaType>
|
2011-12-20 20:24:08 +04:00
|
|
|
#include <QThread>
|
2011-12-20 06:18:08 +04:00
|
|
|
#include <QUrl>
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
#include <QVector>
|
2012-03-21 03:58:13 +04:00
|
|
|
#include <QDebug>
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
|
|
|
|
namespace UrlEncodedParser {
|
|
|
|
|
|
|
|
QString unescape(QByteArray in)
|
|
|
|
{
|
|
|
|
// first step: decode '+' to spaces
|
|
|
|
for(int i = 0; i < in.length(); ++i) {
|
|
|
|
QByteRef c = in[i];
|
|
|
|
if (c == '+') {
|
|
|
|
c = ' ';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// now decode as usual
|
|
|
|
return QUrl::fromPercentEncoding(in);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Parse a application/x-www-form-urlencoded data string
|
|
|
|
QVariantMap parse(const QByteArray &data) {
|
|
|
|
QVariantMap ret;
|
|
|
|
if (data.isEmpty()) {
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
foreach(const QByteArray &part, data.split('&')) {
|
|
|
|
const int eqPos = part.indexOf('=');
|
|
|
|
if (eqPos == -1) {
|
|
|
|
ret[unescape(part)] = "";
|
|
|
|
} else {
|
|
|
|
const QByteArray key = part.mid(0, eqPos);
|
|
|
|
const QByteArray value = part.mid(eqPos + 1);
|
|
|
|
ret[unescape(key)] = unescape(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2011-11-15 16:44:47 +04:00
|
|
|
|
|
|
|
static void *callback(mg_event event,
|
|
|
|
mg_connection *conn,
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
const mg_request_info *request)
|
2011-11-15 16:44:47 +04:00
|
|
|
{
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
WebServer* server = static_cast<WebServer*>(request->user_data);
|
|
|
|
if (server->handleRequest(event, conn, request)) {
|
2011-11-15 16:44:47 +04:00
|
|
|
// anything non-null... pretty ugly, why not simply a bool??
|
|
|
|
return server;
|
|
|
|
} else {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-05 04:22:30 +04:00
|
|
|
WebServer::WebServer(QObject *parent)
|
2012-12-29 20:23:10 +04:00
|
|
|
: QObject(parent)
|
2011-11-15 16:44:47 +04:00
|
|
|
, m_ctx(0)
|
|
|
|
{
|
2011-11-07 21:25:57 +04:00
|
|
|
setObjectName("WebServer");
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
qRegisterMetaType<WebServerResponse*>("WebServerResponse*");
|
2011-11-15 16:44:47 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
WebServer::~WebServer()
|
|
|
|
{
|
2011-11-07 21:24:45 +04:00
|
|
|
close();
|
2011-11-15 16:44:47 +04:00
|
|
|
}
|
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
bool WebServer::listenOnPort(const QString& port, const QVariantMap& opts)
|
2011-11-15 16:44:47 +04:00
|
|
|
{
|
2011-11-07 21:24:45 +04:00
|
|
|
close();
|
|
|
|
|
2012-07-05 04:22:30 +04:00
|
|
|
// Create options vector
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
QVector<const char*> options;
|
|
|
|
options << "listening_ports" << qstrdup(qPrintable(port));
|
|
|
|
options << "enable_directory_listing" << "no";
|
2012-03-14 21:51:35 +04:00
|
|
|
if (opts.value("keepAlive", false).toBool()) {
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
options << "enable_keep_alive" << "yes";
|
|
|
|
}
|
|
|
|
options << NULL;
|
2012-07-05 04:22:30 +04:00
|
|
|
|
|
|
|
// Start the server
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
m_ctx = mg_start(&callback, this, options.data());
|
2011-11-15 16:44:47 +04:00
|
|
|
if (!m_ctx) {
|
2011-11-07 21:35:35 +04:00
|
|
|
return false;
|
2011-11-15 16:44:47 +04:00
|
|
|
}
|
2011-11-07 21:35:35 +04:00
|
|
|
|
|
|
|
m_port = port;
|
|
|
|
return true;
|
2011-11-15 16:44:47 +04:00
|
|
|
}
|
|
|
|
|
2011-11-07 21:24:45 +04:00
|
|
|
QString WebServer::port() const
|
|
|
|
{
|
|
|
|
return m_port;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebServer::close()
|
|
|
|
{
|
|
|
|
if (m_ctx) {
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
m_closing = 1;
|
|
|
|
{
|
|
|
|
// make sure we wake up all pending responses, such that mg_stop()
|
|
|
|
// can be called without deadlocking
|
|
|
|
QMutexLocker lock(&m_mutex);
|
2012-03-14 18:45:53 +04:00
|
|
|
foreach(WebServerResponse* response, m_pendingResponses) {
|
|
|
|
response->close();
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
|
|
|
}
|
2011-11-07 21:24:45 +04:00
|
|
|
mg_stop(m_ctx);
|
|
|
|
m_ctx = 0;
|
|
|
|
m_port.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
bool WebServer::handleRequest(mg_event event, mg_connection *conn, const mg_request_info *request)
|
2012-02-15 16:52:57 +04:00
|
|
|
{
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
if (event != MG_NEW_REQUEST) {
|
|
|
|
return false;
|
2012-02-15 16:52:57 +04:00
|
|
|
}
|
|
|
|
|
2014-07-24 21:25:46 +04:00
|
|
|
if (m_closing.loadAcquire()) {
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
return false;
|
2012-02-15 16:52:57 +04:00
|
|
|
}
|
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
// Modelled after http://nodejs.org/docs/latest/api/http.html#http.ServerRequest
|
|
|
|
QVariantMap requestObject;
|
2011-12-20 06:18:08 +04:00
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
///TODO: encoding?!
|
2011-12-20 06:18:08 +04:00
|
|
|
|
2012-09-09 15:24:15 +04:00
|
|
|
qDebug() << "HTTP Request - URI" << request->uri;
|
|
|
|
qDebug() << "HTTP Request - Method" << request->request_method;
|
|
|
|
qDebug() << "HTTP Request - HTTP Version" << request->http_version;
|
|
|
|
qDebug() << "HTTP Request - Query String" << request->query_string;
|
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
if (request->request_method)
|
|
|
|
requestObject["method"] = QString::fromLocal8Bit(request->request_method);
|
|
|
|
if (request->http_version)
|
|
|
|
requestObject["httpVersion"] = QString::fromLocal8Bit(request->http_version);
|
|
|
|
if (request->status_code >=0)
|
|
|
|
requestObject["statusCode"] = request->status_code;
|
2011-12-20 06:18:08 +04:00
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
QByteArray uri(request->uri);
|
|
|
|
if (uri.startsWith('/'))
|
2012-03-20 17:50:53 +04:00
|
|
|
uri = '/' + QUrl::toPercentEncoding(QString::fromLatin1(request->uri + 1), "/?&#");
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
if (request->query_string)
|
|
|
|
uri.append('?').append(QByteArray(request->query_string));
|
|
|
|
requestObject["url"] = uri.data();
|
2011-12-20 06:18:08 +04:00
|
|
|
|
|
|
|
#if 0
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
// Non-standard and thus disable for the time being.
|
|
|
|
requestObject["isSSL"] = request->is_ssl;
|
|
|
|
requestObject["remoteIP"] = QHostAddress(request->remote_ip).toString();;
|
|
|
|
requestObject["remotePort"] = request->remote_port;
|
|
|
|
if (request->remote_user)
|
|
|
|
requestObject["remoteUser"] = QString::fromLocal8Bit(request->remote_user);
|
2011-12-20 06:18:08 +04:00
|
|
|
#endif
|
|
|
|
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
QVariantMap headersObject;
|
2013-06-21 04:41:20 +04:00
|
|
|
QMap<QString, QString> ciHeadersObject; //< FIXME: "case-insensitive" Headers. This shows how desperately we need a better HTTP Server
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
for (int i = 0; i < request->num_headers; ++i) {
|
|
|
|
QString key = QString::fromLocal8Bit(request->http_headers[i].name);
|
|
|
|
QString value = QString::fromLocal8Bit(request->http_headers[i].value);
|
2012-03-23 15:42:16 +04:00
|
|
|
qDebug() << "HTTP Request - Receiving Header" << key << "=" << value;
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
headersObject[key] = value;
|
2013-06-21 04:41:20 +04:00
|
|
|
ciHeadersObject[key.toLower()] = value;
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
|
|
|
requestObject["headers"] = headersObject;
|
|
|
|
|
2012-03-22 22:16:07 +04:00
|
|
|
// Read request body ONLY for POST and PUT, and ONLY if the "Content-Length" is provided
|
2013-06-21 04:41:20 +04:00
|
|
|
if ((requestObject["method"] == "POST" || requestObject["method"] == "PUT") && ciHeadersObject.contains(HTTP_HEADER_CONTENT_LENGTH)) {
|
2012-03-22 22:16:07 +04:00
|
|
|
bool contentLengthKnown = false;
|
2013-06-21 04:41:20 +04:00
|
|
|
uint contentLength = ciHeadersObject[HTTP_HEADER_CONTENT_LENGTH].toUInt(&contentLengthKnown);
|
2012-03-22 22:16:07 +04:00
|
|
|
|
|
|
|
qDebug() << "HTTP Request - Method POST/PUT";
|
|
|
|
|
|
|
|
// Proceed only if we were able to read the "Content-Length"
|
|
|
|
if (contentLengthKnown) {
|
|
|
|
++contentLength; //< make space for null termination
|
|
|
|
char *data = new char[contentLength];
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
int read = mg_read(conn, data, contentLength);
|
2012-03-22 22:16:07 +04:00
|
|
|
data[read] = '\0'; //< adding null termination (no arm if it's already there)
|
|
|
|
|
|
|
|
qDebug() << "HTTP Request - Content Body:" << qPrintable(data);
|
|
|
|
|
2012-03-21 03:58:13 +04:00
|
|
|
// Check if the 'Content-Type' requires decoding
|
2013-06-21 04:41:20 +04:00
|
|
|
if (ciHeadersObject[HTTP_HEADER_CONTENT_TYPE] == "application/x-www-form-urlencoded") {
|
2012-03-22 22:16:07 +04:00
|
|
|
requestObject["post"] = UrlEncodedParser::parse(QByteArray(data, read));
|
2012-09-28 20:17:02 +04:00
|
|
|
requestObject["postRaw"] = QString::fromUtf8(data, read);
|
2012-03-21 03:58:13 +04:00
|
|
|
} else {
|
2012-09-28 20:17:02 +04:00
|
|
|
requestObject["post"] = QString::fromUtf8(data, read);
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
|
|
|
delete[] data;
|
2012-03-22 22:16:07 +04:00
|
|
|
} else {
|
|
|
|
qWarning() << "HTTP Request - Malformed 'Content-Length'";
|
2011-12-20 06:18:08 +04:00
|
|
|
}
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
2011-12-20 06:18:08 +04:00
|
|
|
|
2012-03-14 18:45:53 +04:00
|
|
|
// Emit signal that is catched by the PhantomJS callback,
|
|
|
|
// then wait until response.close() was called from
|
|
|
|
// the PhantomJS script.
|
|
|
|
//
|
|
|
|
// This is achieved using the wait semaphore, which is
|
|
|
|
// acquired here, in the background thread, and released
|
|
|
|
// in WebServerResponse::close() i.e. the foreground thread
|
|
|
|
QSemaphore wait;
|
|
|
|
WebServerResponse responseObject(conn, &wait);
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
responseObject.moveToThread(thread());
|
|
|
|
|
|
|
|
{
|
2014-07-24 21:25:46 +04:00
|
|
|
if (m_closing.loadAcquire()) {
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
return false;
|
2012-02-15 16:52:57 +04:00
|
|
|
}
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
QMutexLocker lock(&m_mutex);
|
2014-07-24 21:25:46 +04:00
|
|
|
if (m_closing.loadAcquire()) {
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
return false;
|
|
|
|
}
|
2012-03-14 18:45:53 +04:00
|
|
|
m_pendingResponses << (&responseObject);
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
2012-03-14 18:45:53 +04:00
|
|
|
newRequest(requestObject, &responseObject);
|
|
|
|
wait.acquire();
|
|
|
|
{
|
2014-07-24 21:25:46 +04:00
|
|
|
if (m_closing.loadAcquire()) {
|
2012-03-14 18:45:53 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
QMutexLocker lock(&m_mutex);
|
2014-07-24 21:25:46 +04:00
|
|
|
if (m_closing.loadAcquire()) {
|
2012-03-14 18:45:53 +04:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
m_pendingResponses.removeOne(&responseObject);
|
support keep-alive in the webserver
The recent patch that brought asynchronous webserver response handling
made it impossible to have proper keep-alive support in the server.
We want the server to support keep-alive though, which is especially
useful when writing a PhantomJS script that allows one to "remote control"
PhantomJS, using the WebServer API, without flooding the TCP connections.
Also the performance might be improved.
Note: This patch reverts commit bbce8920d0a56874daba39c7d69f64e3d64c2eb8,
and resets the Mongoose code to the vanilla 3.0 version. Instead we now
support the async handling of HTTP requests using some QWaitCondition
magic.
Note: keep-alive support is optional, and disabled by default. To enable
it, use something like:
server.listen(port, {"keep-alive": true}, function(request, response) {...});
Like before, calling response.close() is crucial. Furthermore though, a
server that has keep-alive enabled *must* set a proper "Content-Length: ..."
header in it's response, otherwise clients will not be able to know when
the response has finished.
fix memory leaks in webserver
ISSUE: 416 (http://code.google.com/p/phantomjs/issues/detail?id=416)
2012-03-06 16:33:56 +04:00
|
|
|
}
|
2012-03-14 18:45:53 +04:00
|
|
|
return true;
|
2011-11-15 16:44:47 +04:00
|
|
|
}
|
2011-11-05 19:38:08 +04:00
|
|
|
|
|
|
|
|
|
|
|
//BEGIN WebServerResponse
|
|
|
|
|
2012-03-14 18:45:53 +04:00
|
|
|
WebServerResponse::WebServerResponse(mg_connection* conn, QSemaphore* close)
|
2012-12-29 20:23:10 +04:00
|
|
|
: QObject()
|
2012-02-10 22:42:38 +04:00
|
|
|
, m_conn(conn)
|
2011-11-07 20:33:35 +04:00
|
|
|
, m_statusCode(200)
|
|
|
|
, m_headersSent(false)
|
2012-03-14 18:45:53 +04:00
|
|
|
, m_close(close)
|
2011-11-05 19:38:08 +04:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2011-11-07 20:33:35 +04:00
|
|
|
const char* responseCodeString(int code)
|
2011-11-05 19:38:08 +04:00
|
|
|
{
|
2011-11-07 20:33:35 +04:00
|
|
|
// see: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
|
|
|
switch (code) {
|
|
|
|
case 100:
|
|
|
|
return "Continue";
|
|
|
|
case 101:
|
|
|
|
return "Switching Protocols";
|
|
|
|
case 200:
|
|
|
|
return "OK";
|
|
|
|
case 201:
|
|
|
|
return "Created";
|
|
|
|
case 202:
|
|
|
|
return "Accepted";
|
|
|
|
case 203:
|
|
|
|
return "Non-Authoritative Information";
|
|
|
|
case 204:
|
|
|
|
return "No Content";
|
|
|
|
case 205:
|
|
|
|
return "Reset Content";
|
|
|
|
case 206:
|
|
|
|
return "Partial Content";
|
|
|
|
case 300:
|
|
|
|
return "Multiple Choices";
|
|
|
|
case 301:
|
|
|
|
return "Moved Permanently";
|
|
|
|
case 302:
|
|
|
|
return "Found";
|
|
|
|
case 303:
|
|
|
|
return "See Other";
|
|
|
|
case 304:
|
|
|
|
return "Not Modified";
|
|
|
|
case 305:
|
|
|
|
return "Use Proxy";
|
|
|
|
case 307:
|
|
|
|
return "Temporary Redirect";
|
|
|
|
case 400:
|
|
|
|
return "Bad Request";
|
|
|
|
case 401:
|
|
|
|
return "Unauthorized";
|
|
|
|
case 402:
|
|
|
|
return "Payment Required";
|
|
|
|
case 403:
|
|
|
|
return "Forbidden";
|
|
|
|
case 404:
|
|
|
|
return "Not Found";
|
|
|
|
case 405:
|
|
|
|
return "Method Not Allowed";
|
|
|
|
case 406:
|
|
|
|
return "Not Acceptable";
|
|
|
|
case 407:
|
|
|
|
return "Proxy Authentication Required";
|
|
|
|
case 408:
|
|
|
|
return "Request Timeout";
|
|
|
|
case 409:
|
|
|
|
return "Conflict";
|
|
|
|
case 410:
|
|
|
|
return "Gone";
|
|
|
|
case 411:
|
|
|
|
return "Length Required";
|
|
|
|
case 412:
|
|
|
|
return "Precondition Failed";
|
|
|
|
case 413:
|
|
|
|
return "Request Entity Too Large";
|
|
|
|
case 414:
|
|
|
|
return "Request-URI Too Long";
|
|
|
|
case 415:
|
|
|
|
return "Unsupported Media Type";
|
|
|
|
case 416:
|
|
|
|
return "Requested Range not Satisfiable";
|
|
|
|
case 417:
|
|
|
|
return "Expectation Failed";
|
|
|
|
case 500:
|
|
|
|
return "Internal Server Error";
|
|
|
|
case 501:
|
|
|
|
return "Not Implemented";
|
|
|
|
case 502:
|
|
|
|
return "Bad Gateway";
|
|
|
|
case 503:
|
|
|
|
return "Service Unavailable";
|
|
|
|
case 504:
|
|
|
|
return "Gateway Timeout";
|
|
|
|
case 505:
|
|
|
|
return "HTTP Version Not Supported";
|
|
|
|
case 306:
|
|
|
|
// unused: fallthrough
|
|
|
|
default:
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-20 06:18:08 +04:00
|
|
|
void WebServerResponse::writeHead(int statusCode, const QVariantMap &headers)
|
2011-11-07 20:33:35 +04:00
|
|
|
{
|
|
|
|
///TODO: what is the best-practice error handling in javascript? exceptions?
|
|
|
|
Q_ASSERT(!m_headersSent);
|
|
|
|
m_headersSent = true;
|
2011-12-21 19:49:00 +04:00
|
|
|
m_statusCode = statusCode;
|
2011-11-07 20:33:35 +04:00
|
|
|
mg_printf(m_conn, "HTTP/1.1 %d %s\r\n", m_statusCode, responseCodeString(m_statusCode));
|
2012-09-09 15:24:15 +04:00
|
|
|
qDebug() << "HTTP Response - Status Code" << m_statusCode << responseCodeString(m_statusCode);
|
2011-11-07 20:33:35 +04:00
|
|
|
QVariantMap::const_iterator it = headers.constBegin();
|
|
|
|
while(it != headers.constEnd()) {
|
2012-03-22 22:16:07 +04:00
|
|
|
qDebug() << "HTTP Response - Sending Header" << it.key() << "=" << it.value().toString();
|
2011-11-07 20:33:35 +04:00
|
|
|
mg_printf(m_conn, "%s: %s\r\n", qPrintable(it.key()), qPrintable(it.value().toString()));
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
mg_write(m_conn, "\r\n", 2);
|
2011-11-05 19:38:08 +04:00
|
|
|
}
|
|
|
|
|
2012-12-11 20:04:57 +04:00
|
|
|
void WebServerResponse::write(const QVariant &body)
|
2011-11-05 19:38:08 +04:00
|
|
|
{
|
2011-11-07 20:33:35 +04:00
|
|
|
if (!m_headersSent) {
|
2011-12-20 06:18:08 +04:00
|
|
|
writeHead(m_statusCode, m_headers);
|
2011-11-07 20:33:35 +04:00
|
|
|
}
|
2012-12-11 20:04:57 +04:00
|
|
|
|
2012-12-18 11:12:48 +04:00
|
|
|
QByteArray data;
|
|
|
|
if (m_encoding.isEmpty()) {
|
|
|
|
data = body.toString().toUtf8();
|
|
|
|
} else if (m_encoding.toLower() == "binary") {
|
2015-02-07 01:46:50 +03:00
|
|
|
QString str = body.toString();
|
|
|
|
data.reserve(str.length());
|
|
|
|
for (int i = 0; i < str.length(); ++i) {
|
|
|
|
data[i] = (char)str.at(i).unicode();
|
|
|
|
}
|
2012-12-18 11:12:48 +04:00
|
|
|
} else {
|
|
|
|
Encoding encoding;
|
|
|
|
encoding.setEncoding(m_encoding);
|
2015-02-07 01:46:50 +03:00
|
|
|
QByteArray data = encoding.encode(body.toString());
|
2012-12-18 11:12:48 +04:00
|
|
|
}
|
2012-12-11 20:04:57 +04:00
|
|
|
|
2011-11-07 20:33:35 +04:00
|
|
|
mg_write(m_conn, data.constData(), data.size());
|
|
|
|
}
|
|
|
|
|
2012-12-11 20:04:57 +04:00
|
|
|
void WebServerResponse::setEncoding(const QString &encoding)
|
|
|
|
{
|
2012-12-18 11:12:48 +04:00
|
|
|
m_encoding = encoding;
|
2012-12-11 20:04:57 +04:00
|
|
|
}
|
|
|
|
|
2012-02-10 22:42:38 +04:00
|
|
|
void WebServerResponse::close()
|
|
|
|
{
|
2012-03-14 18:45:53 +04:00
|
|
|
m_close->release();
|
2012-02-10 22:42:38 +04:00
|
|
|
}
|
|
|
|
|
2012-03-23 15:42:16 +04:00
|
|
|
void WebServerResponse::closeGracefully()
|
|
|
|
{
|
|
|
|
write("");
|
|
|
|
close();
|
|
|
|
}
|
|
|
|
|
2011-11-07 20:33:35 +04:00
|
|
|
int WebServerResponse::statusCode() const
|
|
|
|
{
|
|
|
|
return m_statusCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebServerResponse::setStatusCode(int code)
|
|
|
|
{
|
|
|
|
///TODO: what is the best-practice error handling in javascript? exceptions?
|
|
|
|
Q_ASSERT(!m_headersSent);
|
|
|
|
m_statusCode = code;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString WebServerResponse::header(const QString &name) const
|
|
|
|
{
|
|
|
|
return m_headers.value(name).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
void WebServerResponse::setHeader(const QString &name, const QString &value)
|
|
|
|
{
|
|
|
|
///TODO: what is the best-practice error handling in javascript? exceptions?
|
|
|
|
Q_ASSERT(!m_headersSent);
|
|
|
|
m_headers.insert(name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
QVariantMap WebServerResponse::headers() const
|
|
|
|
{
|
|
|
|
return m_headers;
|
2011-11-05 19:38:08 +04:00
|
|
|
}
|
|
|
|
|
2011-11-07 20:33:35 +04:00
|
|
|
void WebServerResponse::setHeaders(const QVariantMap &headers)
|
|
|
|
{
|
|
|
|
///TODO: what is the best-practice error handling in javascript? exceptions?
|
|
|
|
Q_ASSERT(!m_headersSent);
|
|
|
|
m_headers = headers;
|
|
|
|
}
|
2011-11-05 19:38:08 +04:00
|
|
|
|
|
|
|
//END WebServerResponse
|