root/src/server.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#ifndef SERVER_H
#define SERVER_H

#include <qhttpserver.h>
#include <qhttpresponse.h>
#include <qhttprequest.h>

#include <QFile>
#include <QDir>

#include "mainwindow.h"
#include "videoplayer.h"
#include "apipushevents.h"

namespace mime {
const QString json = "application/json";
const QString text = "text/plain";
const QString html = "text/html";
};

/// emits bodyReceived
/// Allocate this on heap. You don't have to delete this object.
class RequestBodyListener : public QObject {
    Q_OBJECT
public:
    RequestBodyListener(QHttpResponse* resp, QObject* parent);

signals:
    void bodyReceived(QHttpResponse* resp, const QByteArray& bytes);

public slots:
    void onDataReceived(QByteArray);

private:
    QHttpResponse* resp;
};


class ServerDataReady : public QObject {
    Q_OBJECT
public:
    ServerDataReady(QHttpResponse* resp, QObject* parent = NULL);

signals:
    // Qt signals doesn't have templates
    void floatReady(float);
    void boolReady(bool);

public:
    QHttpResponse* resp;
};

class Server : public QObject
{
    Q_OBJECT
public:
    Server(QString publicDirectoryPath, MainWindow& window, Library& library, VideoPlayer* player);
    int start(int serverPort); ///< returns the listening port
    bool handleApiRequest(QHttpRequest *req, QHttpResponse *resp);
    void sendFile(QHttpRequest *req, QHttpResponse *resp);


    static void simpleWrite(QHttpResponse *resp, int statusCode, const QString &data, QString mime = mime::text);
    static void simpleWriteBytes(QHttpResponse *resp, int statusCode, const QByteArray &data, QString mime = mime::text);
    static void sendRedirect(QHttpResponse *resp, const QString &location);

    void streamVideo(QHttpRequest *req, QHttpResponse *resp);
public slots:
    void handleRequest(QHttpRequest *req, QHttpResponse* resp);

private:
    std::pair<bool, int> tryToBindPort(QHttpServer *server, int originalPort);

    QHttpServer* server;
    QDir publicDirectory; ///< send files in this directory as HTTP GET responses
    MainWindow& window;
    Library& library;
    VideoPlayer* player;
    ApiPushEvents pushEvents;
    Q_DISABLE_COPY(Server)
};

#endif // SERVER_H