mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 08:08:42 +00:00
.. Makes it easier to identify code that has been snaffled in from other repositories and check licensing .. The httpserver is now no longer optional, since it is delivered as contributed source.
157 lines
4.0 KiB
C++
157 lines
4.0 KiB
C++
/**
|
|
@file
|
|
@author Stefan Frings
|
|
*/
|
|
|
|
#include "httpresponse.h"
|
|
|
|
HttpResponse::HttpResponse(QTcpSocket* socket) {
|
|
this->socket=socket;
|
|
statusCode=200;
|
|
statusText="OK";
|
|
sentHeaders=false;
|
|
sentLastPart=false;
|
|
buffersize=40960;
|
|
barry.reserve(40960);
|
|
userdata_=NULL;
|
|
}
|
|
|
|
void HttpResponse::setHeader(QByteArray name, QByteArray value) {
|
|
Q_ASSERT(sentHeaders==false);
|
|
headers.insert(name,value);
|
|
}
|
|
|
|
void HttpResponse::setHeader(QByteArray name, int value) {
|
|
Q_ASSERT(sentHeaders==false);
|
|
headers.insert(name,QByteArray::number(value));
|
|
}
|
|
|
|
QMap<QByteArray,QByteArray>& HttpResponse::getHeaders() {
|
|
return headers;
|
|
}
|
|
|
|
void HttpResponse::setStatus(int statusCode, QByteArray description) {
|
|
this->statusCode=statusCode;
|
|
statusText=description;
|
|
}
|
|
|
|
void HttpResponse::writeHeaders() {
|
|
Q_ASSERT(sentHeaders==false);
|
|
QByteArray buffer;
|
|
buffer.append("HTTP/1.1 ");
|
|
buffer.append(QByteArray::number(statusCode));
|
|
buffer.append(' ');
|
|
buffer.append(statusText);
|
|
buffer.append("\r\n");
|
|
foreach(QByteArray name, headers.keys()) {
|
|
buffer.append(name);
|
|
buffer.append(": ");
|
|
buffer.append(headers.value(name));
|
|
buffer.append("\r\n");
|
|
}
|
|
foreach(HttpCookie cookie,cookies.values()) {
|
|
buffer.append("Set-Cookie: ");
|
|
buffer.append(cookie.toByteArray());
|
|
buffer.append("\r\n");
|
|
}
|
|
buffer.append("\r\n");
|
|
writeToSocket(buffer);
|
|
sentHeaders=true;
|
|
}
|
|
|
|
bool HttpResponse::writeToSocket(QByteArray data) {
|
|
int remaining=data.size();
|
|
char* ptr=data.data();
|
|
while (socket->isOpen() && remaining>0) {
|
|
// Wait until the previous buffer content is written out, otherwise it could become very large
|
|
socket->waitForBytesWritten(-1);
|
|
int written=socket->write(ptr,remaining);
|
|
if (written==-1) {
|
|
return false;
|
|
}
|
|
ptr+=written;
|
|
remaining-=written;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void HttpResponse::bwrite(QByteArray data)
|
|
{
|
|
if (barry.size() && (barry.size() + data.size() > buffersize)) {
|
|
// flush buffer
|
|
write(barry);
|
|
barry = data;
|
|
} else {
|
|
barry.append(data);
|
|
}
|
|
}
|
|
|
|
void HttpResponse::flush()
|
|
{
|
|
if (barry.size()) {
|
|
write(barry, true);
|
|
barry.clear();
|
|
}
|
|
}
|
|
|
|
void HttpResponse::write(QByteArray data, bool lastPart) {
|
|
Q_ASSERT(sentLastPart==false);
|
|
if (sentHeaders==false) {
|
|
QByteArray connectionMode=headers.value("Connection");
|
|
if (!headers.contains("Content-Length") && !headers.contains("Transfer-Encoding") && connectionMode!="close" && connectionMode!="Close") {
|
|
if (!lastPart) {
|
|
headers.insert("Transfer-Encoding","chunked");
|
|
}
|
|
else {
|
|
headers.insert("Content-Length",QByteArray::number(data.size()));
|
|
}
|
|
}
|
|
writeHeaders();
|
|
}
|
|
bool chunked=headers.value("Transfer-Encoding")=="chunked" || headers.value("Transfer-Encoding")=="Chunked";
|
|
if (chunked) {
|
|
if (data.size()>0) {
|
|
QByteArray buffer=QByteArray::number(data.size(),16);
|
|
buffer.append("\r\n");
|
|
writeToSocket(buffer);
|
|
writeToSocket(data);
|
|
writeToSocket("\r\n");
|
|
}
|
|
}
|
|
else {
|
|
writeToSocket(data);
|
|
}
|
|
if (lastPart) {
|
|
if (chunked) {
|
|
writeToSocket("0\r\n\r\n");
|
|
}
|
|
else if (!headers.contains("Content-Length")) {
|
|
socket->disconnectFromHost();
|
|
}
|
|
sentLastPart=true;
|
|
}
|
|
}
|
|
|
|
|
|
bool HttpResponse::hasSentLastPart() const {
|
|
return sentLastPart;
|
|
}
|
|
|
|
|
|
void HttpResponse::setCookie(const HttpCookie& cookie) {
|
|
Q_ASSERT(sentHeaders==false);
|
|
if (!cookie.getName().isEmpty()) {
|
|
cookies.insert(cookie.getName(),cookie);
|
|
}
|
|
}
|
|
|
|
QMap<QByteArray,HttpCookie>& HttpResponse::getCookies() {
|
|
return cookies;
|
|
}
|
|
|
|
void HttpResponse::redirect(const QByteArray& url) {
|
|
setStatus(303,"See Other");
|
|
setHeader("Location",url);
|
|
write("Redirect",true);
|
|
}
|