mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-15 00:16:45 +02:00
149 lines
4.4 KiB
C++
149 lines
4.4 KiB
C++
//
|
|
// HTTPConnection.h
|
|
// libraries/embedded-webserver/src
|
|
//
|
|
// Created by Stephen Birarda on 1/16/14.
|
|
// Copyright 2014 High Fidelity, Inc.
|
|
//
|
|
// Heavily based on Andrzej Kapolka's original HTTPConnection class
|
|
// found from another one of his projects.
|
|
// https://github.com/ey6es/witgap/tree/master/src/cpp/server/http
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#ifndef hifi_HTTPConnection_h
|
|
#define hifi_HTTPConnection_h
|
|
|
|
#include <QHash>
|
|
#include <QIODevice>
|
|
#include <QList>
|
|
#include <QtNetwork/QHostAddress>
|
|
#include <QtNetwork/QNetworkAccessManager>
|
|
#include <QObject>
|
|
#include <QPair>
|
|
#include <QTemporaryFile>
|
|
#include <QUrl>
|
|
|
|
#include <memory>
|
|
|
|
class QTcpSocket;
|
|
class HTTPManager;
|
|
class MaskFilter;
|
|
class ServerApp;
|
|
|
|
/// Header hash
|
|
typedef QHash<QByteArray, QByteArray> Headers;
|
|
|
|
/// A form data element
|
|
typedef QPair<Headers, QByteArray> FormData;
|
|
|
|
/// Handles a single HTTP connection.
|
|
class HTTPConnection : public QObject {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
static const char* StatusCode200;
|
|
static const char* StatusCode301;
|
|
static const char* StatusCode302;
|
|
static const char* StatusCode400;
|
|
static const char* StatusCode401;
|
|
static const char* StatusCode403;
|
|
static const char* StatusCode404;
|
|
static const char* StatusCode500;
|
|
static const char* DefaultContentType;
|
|
|
|
/// WebSocket close status codes.
|
|
enum ReasonCode { NoReason = 0, NormalClosure = 1000, GoingAway = 1001 };
|
|
|
|
class Storage {
|
|
public:
|
|
Storage() = default;
|
|
virtual ~Storage() = default;
|
|
|
|
virtual const QByteArray& content() const = 0;
|
|
|
|
virtual qint64 bytesLeftToWrite() const = 0;
|
|
virtual void write(const QByteArray& data) = 0;
|
|
};
|
|
|
|
/// Initializes the connection.
|
|
HTTPConnection(QTcpSocket* socket, HTTPManager* parentManager);
|
|
|
|
/// Destroys the connection.
|
|
virtual ~HTTPConnection();
|
|
|
|
/// Returns a pointer to the underlying socket, to which WebSocket message bodies should be written.
|
|
QTcpSocket* socket() const { return _socket; }
|
|
|
|
/// Returns the request operation.
|
|
QNetworkAccessManager::Operation requestOperation() const { return _requestOperation; }
|
|
|
|
/// Returns a reference to the request URL.
|
|
const QUrl& requestUrl() const { return _requestUrl; }
|
|
|
|
/// Returns a copy of the request header value. If it does not exist, it will return a default constructed QByteArray.
|
|
QByteArray requestHeader(const QString& key) const { return _requestHeaders.value(key.toLower().toLocal8Bit()); }
|
|
|
|
/// Returns a reference to the request content.
|
|
const QByteArray& requestContent() const { return _requestContent->content(); }
|
|
|
|
/// Parses the request content as form data, returning a list of header/content pairs.
|
|
QList<FormData> parseFormData() const;
|
|
|
|
/// Parses the request content as a url encoded form, returning a hash of key/value pairs.
|
|
/// Duplicate keys are not supported.
|
|
QHash<QString, QString> parseUrlEncodedForm();
|
|
|
|
/// Sends a response and closes the connection.
|
|
void respond(const char* code, const QByteArray& content = QByteArray(),
|
|
const char* contentType = DefaultContentType,
|
|
const Headers& headers = Headers());
|
|
void respond(const char* code, std::unique_ptr<QIODevice> device,
|
|
const char* contentType = DefaultContentType,
|
|
const Headers& headers = Headers());
|
|
|
|
protected slots:
|
|
|
|
/// Reads the request line.
|
|
void readRequest();
|
|
|
|
/// Reads the headers.
|
|
void readHeaders();
|
|
|
|
/// Reads the content.
|
|
void readContent();
|
|
|
|
protected:
|
|
void respondWithStatusAndHeaders(const char* code, const char* contentType, const Headers& headers, qint64 size);
|
|
|
|
/// The parent HTTP manager
|
|
HTTPManager* _parentManager;
|
|
|
|
/// The underlying socket.
|
|
QTcpSocket* _socket;
|
|
|
|
/// The stored address.
|
|
QHostAddress _address;
|
|
|
|
/// The requested operation.
|
|
QNetworkAccessManager::Operation _requestOperation;
|
|
|
|
/// The requested URL.
|
|
QUrl _requestUrl;
|
|
|
|
/// The request headers.
|
|
Headers _requestHeaders;
|
|
|
|
/// The last request header processed (used for continuations).
|
|
QByteArray _lastRequestHeader;
|
|
|
|
/// The content of the request.
|
|
std::unique_ptr<Storage> _requestContent;
|
|
|
|
/// Response content
|
|
std::unique_ptr<QIODevice> _responseDevice;
|
|
};
|
|
|
|
#endif // hifi_HTTPConnection_h
|