etherealjoy 12f3661d6f Qt5cpp plug memleaks (#7695)
* Small fixes to prevent crash when empty json body is provided.

* WIP: plug mem-leaks

* fixup: add the QJsonObject instance in toJsonArray instead of pointer

* fixup: simplify toJsonMap

Actually the original solution is incomplete, because "innerType" maps to a single C++ type. Have a look at Qt's builtin QJsonObject::fromVariantMap.

* Updates to antis81:patch-1 after tests.

* update to remove string allocation

* Updates due to address of members being passed

* Update PetStore Examples

* Small updates for Header includes
2018-03-07 20:54:40 +08:00

326 lines
10 KiB
C++

/**
* Swagger Petstore
* This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.
*
* OpenAPI spec version: 1.0.0
* Contact: apiteam@swagger.io
*
* NOTE: This class is auto generated by the swagger code generator program.
* https://github.com/swagger-api/swagger-codegen.git
* Do not edit the class manually.
*/
#include "SWGHttpRequest.h"
#include <QDateTime>
#include <QUrl>
#include <QFileInfo>
#include <QBuffer>
#include <QtGlobal>
namespace Swagger {
SWGHttpRequestInput::SWGHttpRequestInput() {
initialize();
}
SWGHttpRequestInput::SWGHttpRequestInput(QString v_url_str, QString v_http_method) {
initialize();
url_str = v_url_str;
http_method = v_http_method;
}
void SWGHttpRequestInput::initialize() {
var_layout = NOT_SET;
url_str = "";
http_method = "GET";
}
void SWGHttpRequestInput::add_var(QString key, QString value) {
vars[key] = value;
}
void SWGHttpRequestInput::add_file(QString variable_name, QString local_filename, QString request_filename, QString mime_type) {
SWGHttpRequestInputFileElement file;
file.variable_name = variable_name;
file.local_filename = local_filename;
file.request_filename = request_filename;
file.mime_type = mime_type;
files.append(file);
}
SWGHttpRequestWorker::SWGHttpRequestWorker(QObject *parent)
: QObject(parent), manager(nullptr)
{
qsrand(QDateTime::currentDateTime().toTime_t());
manager = new QNetworkAccessManager(this);
connect(manager, &QNetworkAccessManager::finished, this, &SWGHttpRequestWorker::on_manager_finished);
}
SWGHttpRequestWorker::~SWGHttpRequestWorker() {
}
QString SWGHttpRequestWorker::http_attribute_encode(QString attribute_name, QString input) {
// result structure follows RFC 5987
bool need_utf_encoding = false;
QString result = "";
QByteArray input_c = input.toLocal8Bit();
char c;
for (int i = 0; i < input_c.length(); i++) {
c = input_c.at(i);
if (c == '\\' || c == '/' || c == '\0' || c < ' ' || c > '~') {
// ignore and request utf-8 version
need_utf_encoding = true;
}
else if (c == '"') {
result += "\\\"";
}
else {
result += c;
}
}
if (result.length() == 0) {
need_utf_encoding = true;
}
if (!need_utf_encoding) {
// return simple version
return QString("%1=\"%2\"").arg(attribute_name, result);
}
QString result_utf8 = "";
for (int i = 0; i < input_c.length(); i++) {
c = input_c.at(i);
if (
(c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'Z')
|| (c >= 'a' && c <= 'z')
) {
result_utf8 += c;
}
else {
result_utf8 += "%" + QString::number(static_cast<unsigned char>(input_c.at(i)), 16).toUpper();
}
}
// return enhanced version with UTF-8 support
return QString("%1=\"%2\"; %1*=utf-8''%3").arg(attribute_name, result, result_utf8);
}
void SWGHttpRequestWorker::execute(SWGHttpRequestInput *input) {
// reset variables
QByteArray request_content = "";
response = "";
error_type = QNetworkReply::NoError;
error_str = "";
bool isFormData = false;
// decide on the variable layout
if (input->files.length() > 0) {
input->var_layout = MULTIPART;
}
if (input->var_layout == NOT_SET) {
input->var_layout = input->http_method == "GET" || input->http_method == "HEAD" ? ADDRESS : URL_ENCODED;
}
// prepare request content
QString boundary = "";
if (input->var_layout == ADDRESS || input->var_layout == URL_ENCODED) {
// variable layout is ADDRESS or URL_ENCODED
if (input->vars.count() > 0) {
bool first = true;
isFormData = true;
foreach (QString key, input->vars.keys()) {
if (!first) {
request_content.append("&");
}
first = false;
request_content.append(QUrl::toPercentEncoding(key));
request_content.append("=");
request_content.append(QUrl::toPercentEncoding(input->vars.value(key)));
}
if (input->var_layout == ADDRESS) {
input->url_str += "?" + request_content;
request_content = "";
}
}
}
else {
// variable layout is MULTIPART
boundary = "__-----------------------"
+ QString::number(QDateTime::currentDateTime().toTime_t())
+ QString::number(qrand());
QString boundary_delimiter = "--";
QString new_line = "\r\n";
// add variables
foreach (QString key, input->vars.keys()) {
// add boundary
request_content.append(boundary_delimiter);
request_content.append(boundary);
request_content.append(new_line);
// add header
request_content.append("Content-Disposition: form-data; ");
request_content.append(http_attribute_encode("name", key));
request_content.append(new_line);
request_content.append("Content-Type: text/plain");
request_content.append(new_line);
// add header to body splitter
request_content.append(new_line);
// add variable content
request_content.append(input->vars.value(key));
request_content.append(new_line);
}
// add files
for (QList<SWGHttpRequestInputFileElement>::iterator file_info = input->files.begin(); file_info != input->files.end(); file_info++) {
QFileInfo fi(file_info->local_filename);
// ensure necessary variables are available
if (
file_info->local_filename == nullptr || file_info->local_filename.isEmpty()
|| file_info->variable_name == nullptr || file_info->variable_name.isEmpty()
|| !fi.exists() || !fi.isFile() || !fi.isReadable()
) {
// silent abort for the current file
continue;
}
QFile file(file_info->local_filename);
if (!file.open(QIODevice::ReadOnly)) {
// silent abort for the current file
continue;
}
// ensure filename for the request
if (file_info->request_filename == nullptr || file_info->request_filename.isEmpty()) {
file_info->request_filename = fi.fileName();
if (file_info->request_filename.isEmpty()) {
file_info->request_filename = "file";
}
}
// add boundary
request_content.append(boundary_delimiter);
request_content.append(boundary);
request_content.append(new_line);
// add header
request_content.append(QString("Content-Disposition: form-data; %1; %2").arg(
http_attribute_encode("name", file_info->variable_name),
http_attribute_encode("filename", file_info->request_filename)
));
request_content.append(new_line);
if (file_info->mime_type != nullptr && !file_info->mime_type.isEmpty()) {
request_content.append("Content-Type: ");
request_content.append(file_info->mime_type);
request_content.append(new_line);
}
request_content.append("Content-Transfer-Encoding: binary");
request_content.append(new_line);
// add header to body splitter
request_content.append(new_line);
// add file content
request_content.append(file.readAll());
request_content.append(new_line);
file.close();
}
// add end of body
request_content.append(boundary_delimiter);
request_content.append(boundary);
request_content.append(boundary_delimiter);
}
if(input->request_body.size() > 0) {
qDebug() << "got a request body";
request_content.clear();
request_content.append(input->request_body);
}
// prepare connection
QNetworkRequest request = QNetworkRequest(QUrl(input->url_str));
if (SWGHttpRequestWorker::sslDefaultConfiguration != nullptr) {
request.setSslConfiguration(*SWGHttpRequestWorker::sslDefaultConfiguration);
}
request.setRawHeader("User-Agent", "Swagger-Client");
foreach(QString key, input->headers.keys()) {
request.setRawHeader(key.toStdString().c_str(), input->headers.value(key).toStdString().c_str());
}
if (request_content.size() > 0 && !isFormData) {
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
}
else if (input->var_layout == URL_ENCODED) {
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
}
else if (input->var_layout == MULTIPART) {
request.setHeader(QNetworkRequest::ContentTypeHeader, "multipart/form-data; boundary=" + boundary);
}
if (input->http_method == "GET") {
manager->get(request);
}
else if (input->http_method == "POST") {
manager->post(request, request_content);
}
else if (input->http_method == "PUT") {
manager->put(request, request_content);
}
else if (input->http_method == "HEAD") {
manager->head(request);
}
else if (input->http_method == "DELETE") {
manager->deleteResource(request);
}
else {
#if (QT_VERSION >= 0x050800)
manager->sendCustomRequest(request, input->http_method.toLatin1(), request_content);
#else
QBuffer *buffer = new QBuffer;
buffer->setData(request_content);
buffer->open(QIODevice::ReadOnly);
QNetworkReply* reply = manager->sendCustomRequest(request, input->http_method.toLatin1(), buffer);
buffer->setParent(reply);
#endif
}
}
void SWGHttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
error_type = reply->error();
response = reply->readAll();
error_str = reply->errorString();
reply->deleteLater();
emit on_execution_finished(this);
}
QSslConfiguration* SWGHttpRequestWorker::sslDefaultConfiguration;
}