Enable customizing the save statistics time interval
[qBittorrent.git] / src / base / http / responsegenerator.cpp
blobb34b973dbe4b8a90d874185cb727ece7d917c003
1 /*
2 * Bittorrent Client using Qt and libtorrent.
3 * Copyright (C) 2014 Vladimir Golovnev <glassez@yandex.ru>
4 * Copyright (C) 2006 Ishan Arora and Christophe Dumez <chris@qbittorrent.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 * In addition, as a special exception, the copyright holders give permission to
21 * link this program with the OpenSSL project's "OpenSSL" library (or with
22 * modified versions of it that use the same license as the "OpenSSL" library),
23 * and distribute the linked executables. You must obey the GNU General Public
24 * License in all respects for all of the code used other than "OpenSSL". If you
25 * modify file(s), you may extend this exception to your version of the file(s),
26 * but you are not obligated to do so. If you do not wish to do so, delete this
27 * exception statement from your version.
30 #include "responsegenerator.h"
32 #include <QDateTime>
34 #include "base/http/types.h"
35 #include "base/utils/gzip.h"
37 QByteArray Http::toByteArray(Response response)
39 compressContent(response);
41 response.headers[HEADER_DATE] = httpDate();
42 if (QString &value = response.headers[HEADER_CONTENT_LENGTH]; value.isEmpty())
43 value = QString::number(response.content.length());
45 QByteArray buf;
46 buf.reserve(1024 + response.content.length());
48 // Status Line
49 buf.append("HTTP/1.1 ") // TODO: depends on request
50 .append(QByteArray::number(response.status.code))
51 .append(' ')
52 .append(response.status.text.toLatin1())
53 .append(CRLF);
55 // Header Fields
56 for (auto i = response.headers.constBegin(); i != response.headers.constEnd(); ++i)
58 buf.append(i.key().toLatin1())
59 .append(": ")
60 .append(i.value().toLatin1())
61 .append(CRLF);
64 // the first empty line
65 buf += CRLF;
67 // message body
68 buf += response.content;
70 return buf;
73 QString Http::httpDate()
75 // [RFC 7231] 7.1.1.1. Date/Time Formats
76 // example: "Sun, 06 Nov 1994 08:49:37 GMT"
78 return QLocale::c().toString(QDateTime::currentDateTimeUtc(), u"ddd, dd MMM yyyy HH:mm:ss"_s)
79 .append(u" GMT");
82 void Http::compressContent(Response &response)
84 if (response.headers.value(HEADER_CONTENT_ENCODING) != u"gzip")
85 return;
87 response.headers.remove(HEADER_CONTENT_ENCODING);
89 // for very small files, compressing them only wastes cpu cycles
90 const int contentSize = response.content.size();
91 if (contentSize <= 1024) // 1 kb
92 return;
94 // filter out known hard-to-compress types
95 const QString contentType = response.headers[HEADER_CONTENT_TYPE];
96 if ((contentType == CONTENT_TYPE_GIF) || (contentType == CONTENT_TYPE_PNG))
97 return;
99 // try compressing
100 bool ok = false;
101 const QByteArray compressedData = Utils::Gzip::compress(response.content, 6, &ok);
102 if (!ok)
103 return;
105 // "Content-Encoding: gzip\r\n" is 24 bytes long
106 if ((compressedData.size() + 24) >= contentSize)
107 return;
109 response.content = compressedData;
110 response.headers[HEADER_CONTENT_ENCODING] = u"gzip"_s;