Merge PR #929: Drop AWS cloud support
This commit is contained in:
commit
67886a68ab
@ -33,8 +33,6 @@ DeviceControlApplication::DeviceControlApplication(int argc, char *argv[]) : QAp
|
||||
QSettings settings;
|
||||
|
||||
m_discovery = new NymeaDiscovery(this);
|
||||
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
||||
m_discovery->setAwsClient(AWSClient::instance());
|
||||
|
||||
m_engine = new Engine(this);
|
||||
|
||||
|
||||
@ -20,8 +20,6 @@ NymeaAppService::NymeaAppService(int argc, char **argv):
|
||||
QSettings settings;
|
||||
|
||||
NymeaDiscovery *discovery = new NymeaDiscovery(this);
|
||||
AWSClient::instance()->setConfig(settings.value("cloudEnvironment").toString());
|
||||
discovery->setAwsClient(AWSClient::instance());
|
||||
|
||||
settings.beginGroup("ConfiguredHosts");
|
||||
foreach (const QString &childGroup, settings.childGroups()) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,253 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef AWSCLIENT_H
|
||||
#define AWSCLIENT_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QNetworkRequest>
|
||||
#include <QDate>
|
||||
#include <QAbstractListModel>
|
||||
#include <QPointer>
|
||||
|
||||
class QNetworkAccessManager;
|
||||
|
||||
class AWSDevice: public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString id READ id CONSTANT)
|
||||
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
|
||||
Q_PROPERTY(bool online READ online NOTIFY onlineChanged)
|
||||
|
||||
public:
|
||||
AWSDevice(const QString &id, const QString &name, bool online = false, QObject *parent = nullptr);
|
||||
QString id() const;
|
||||
QString name() const;
|
||||
void setName(const QString &name);
|
||||
bool online() const;
|
||||
void setOnline(bool online);
|
||||
|
||||
signals:
|
||||
void onlineChanged();
|
||||
void nameChanged();
|
||||
|
||||
private:
|
||||
QString m_id;
|
||||
QString m_name;
|
||||
bool m_online;
|
||||
};
|
||||
|
||||
class AWSDevices: public QAbstractListModel {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
||||
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
|
||||
public:
|
||||
enum Roles {
|
||||
RoleName,
|
||||
RoleId,
|
||||
RoleOnline
|
||||
};
|
||||
AWSDevices(QObject *parent = nullptr);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
bool busy() const;
|
||||
void setBusy(bool busy);
|
||||
Q_INVOKABLE AWSDevice* getDevice(const QString &uuid) const;
|
||||
Q_INVOKABLE AWSDevice* get(int index) const;
|
||||
void insert(AWSDevice *device);
|
||||
void remove(const QString &uuid);
|
||||
void clear();
|
||||
signals:
|
||||
void countChanged();
|
||||
void busyChanged();
|
||||
private:
|
||||
QList<AWSDevice*> m_list;
|
||||
bool m_busy = false;
|
||||
};
|
||||
|
||||
class AWSConfiguration {
|
||||
public:
|
||||
QByteArray clientId;
|
||||
QString poolId;
|
||||
QString identityPoolId;
|
||||
QString certificateEndpoint;
|
||||
QString certificateApiKey;
|
||||
QString certificateVendorId;
|
||||
QString mqttEndpoint;
|
||||
QString region;
|
||||
QString apiEndpoint;
|
||||
QString pushNotificationSystem;
|
||||
};
|
||||
|
||||
class AWSClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(bool isLoggedIn READ isLoggedIn NOTIFY isLoggedInChanged)
|
||||
Q_PROPERTY(QString username READ username NOTIFY isLoggedInChanged)
|
||||
Q_PROPERTY(bool confirmationPending READ confirmationPending NOTIFY confirmationPendingChanged)
|
||||
Q_PROPERTY(QString userId READ userId NOTIFY isLoggedInChanged)
|
||||
Q_PROPERTY(QByteArray idToken READ idToken NOTIFY isLoggedInChanged)
|
||||
Q_PROPERTY(AWSDevices* awsDevices READ awsDevices CONSTANT)
|
||||
|
||||
Q_PROPERTY(QStringList availableConfigs READ availableConfigs CONSTANT)
|
||||
Q_PROPERTY(QString config READ config WRITE setConfig NOTIFY configChanged)
|
||||
|
||||
public:
|
||||
enum LoginError {
|
||||
LoginErrorNoError,
|
||||
LoginErrorInvalidUserOrPass,
|
||||
LoginErrorInvalidCode,
|
||||
LoginErrorUserExists,
|
||||
LoginErrorLimitExceeded,
|
||||
LoginErrorUnknownError,
|
||||
LoginErrorNetworkError
|
||||
};
|
||||
Q_ENUM(LoginError)
|
||||
|
||||
static AWSClient* instance();
|
||||
|
||||
bool isLoggedIn() const;
|
||||
QString username() const;
|
||||
QString userId() const;
|
||||
AWSDevices* awsDevices() const;
|
||||
bool confirmationPending() const;
|
||||
|
||||
Q_INVOKABLE bool login(const QString &username, const QString &password);
|
||||
Q_INVOKABLE void logout();
|
||||
Q_INVOKABLE void signup(const QString &username, const QString &password);
|
||||
Q_INVOKABLE void confirmRegistration(const QString &code);
|
||||
Q_INVOKABLE void forgotPassword(const QString &username);
|
||||
Q_INVOKABLE void confirmForgotPassword(const QString &username, const QString &code, const QString &newPassword);
|
||||
Q_INVOKABLE void deleteAccount();
|
||||
|
||||
Q_INVOKABLE void unpairDevice(const QString &coreId);
|
||||
|
||||
Q_INVOKABLE void fetchDevices();
|
||||
|
||||
Q_INVOKABLE bool postToMQTT(const QString &coreId, const QString &nonce, QPointer<QObject> sender, std::function<void(bool)> callback);
|
||||
Q_INVOKABLE void getId();
|
||||
|
||||
Q_INVOKABLE void registerPushNotificationEndpoint(const QString ®istrationId, const QString &deviceDisplayName, const QString mobileDeviceId, const QString &mobileDeviceManufacturer, const QString &mobileDeviceModel);
|
||||
|
||||
|
||||
bool tokensExpired() const;
|
||||
QByteArray idToken() const;
|
||||
QString cognitoIdentityId() const;
|
||||
|
||||
void fetchCertificate(const QString &uuid, std::function<void(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint)> callback);
|
||||
|
||||
QStringList availableConfigs() const;
|
||||
QString config() const;
|
||||
void setConfig(const QString &config);
|
||||
|
||||
signals:
|
||||
void loginResult(LoginError error);
|
||||
void signupResult(LoginError error);
|
||||
void confirmationResult(LoginError error);
|
||||
void forgotPasswordResult(LoginError error);
|
||||
void confirmForgotPasswordResult(LoginError error);
|
||||
void deleteAccountResult(LoginError error);
|
||||
|
||||
void isLoggedInChanged();
|
||||
void confirmationPendingChanged();
|
||||
void devicesFetched();
|
||||
|
||||
void configChanged();
|
||||
|
||||
private:
|
||||
explicit AWSClient(QObject *parent = nullptr);
|
||||
static AWSClient* s_instance;
|
||||
|
||||
bool refreshAccessToken();
|
||||
void getCredentialsForIdentity(const QString &identityId);
|
||||
void connectMQTT();
|
||||
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *m_nam = nullptr;
|
||||
|
||||
QString m_userId;
|
||||
QString m_username;
|
||||
QString m_password;
|
||||
|
||||
bool m_loginInProgress = false;
|
||||
|
||||
bool m_confirmationPending = false;
|
||||
|
||||
QByteArray m_accessToken;
|
||||
QDateTime m_accessTokenExpiry;
|
||||
QByteArray m_idToken;
|
||||
QByteArray m_refreshToken;
|
||||
|
||||
QByteArray m_identityId;
|
||||
|
||||
QByteArray m_accessKeyId;
|
||||
QByteArray m_secretKey;
|
||||
QByteArray m_sessionToken;
|
||||
QDateTime m_sessionTokenExpiry;
|
||||
|
||||
class QueuedCall {
|
||||
public:
|
||||
QueuedCall(const QString &method): method(method) { }
|
||||
QueuedCall(const QString &method, const QString &arg1): method(method), arg1(arg1) { }
|
||||
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, const QString &arg3, const QString &arg4, const QString &arg5): method(method), arg1(arg1), arg2(arg2), arg3(arg3), arg4(arg4), arg5(arg5) { }
|
||||
QueuedCall(const QString &method, const QString &arg1, const QString &arg2, QPointer<QObject> sender, std::function<void(bool)> callback): method(method), arg1(arg1), arg2(arg2), sender(sender), callback(callback) {}
|
||||
QString method;
|
||||
QString arg1;
|
||||
QString arg2;
|
||||
QString arg3;
|
||||
QString arg4;
|
||||
QString arg5;
|
||||
QPointer<QObject> sender;
|
||||
std::function<void(bool)> callback;
|
||||
|
||||
static void enqueue(QList<QueuedCall> &queue, const QueuedCall &call) {
|
||||
foreach (const QueuedCall &existingCall, queue) {
|
||||
if (existingCall.method == call.method &&
|
||||
existingCall.arg1 == call.arg1 &&
|
||||
existingCall.arg2 == call.arg2 &&
|
||||
existingCall.arg3 == call.arg3 &&
|
||||
&existingCall.callback == &call.callback) {
|
||||
return; // Already in queue
|
||||
}
|
||||
}
|
||||
queue.append(call);
|
||||
}
|
||||
};
|
||||
void cancelCallQueue();
|
||||
|
||||
QList<QueuedCall> m_callQueue;
|
||||
|
||||
QHash<QString, AWSConfiguration> m_configs;
|
||||
QString m_usedConfig = "";
|
||||
AWSDevices *m_devices;
|
||||
};
|
||||
|
||||
#endif // AWSCLIENT_H
|
||||
@ -1,165 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "cloudtransport.h"
|
||||
|
||||
#include "awsclient.h"
|
||||
#include "remoteproxyconnection.h"
|
||||
|
||||
#include <QUrlQuery>
|
||||
#include <QHostInfo>
|
||||
#include <QPointer>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <QLoggingCategory>
|
||||
Q_DECLARE_LOGGING_CATEGORY(dcCloud)
|
||||
|
||||
using namespace remoteproxyclient;
|
||||
|
||||
CloudTransport::CloudTransport(AWSClient *awsClient, QObject *parent):
|
||||
NymeaTransportInterface(parent),
|
||||
m_awsClient(awsClient)
|
||||
{
|
||||
m_remoteproxyConnection = new RemoteProxyConnection(QUuid::createUuid(), qApp->applicationName(), this);
|
||||
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::remoteConnectionEstablished, this,[this]() {
|
||||
qCDebug(dcCloud) << "CloudTransport: Remote connection established.";
|
||||
emit connected();
|
||||
});
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::disconnected, this,[this]() {
|
||||
qCDebug(dcCloud) << "CloudTransport: Disconnected.";
|
||||
emit disconnected();
|
||||
});
|
||||
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::stateChanged, this,[](RemoteProxyConnection::State state) {
|
||||
qCDebug(dcCloud) << "Proxy state changed:" << state;
|
||||
});
|
||||
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::ready, this,[this]() {
|
||||
qCDebug(dcCloud) << "Proxy ready. Authenticating channel.";
|
||||
m_remoteproxyConnection->authenticate(m_awsClient->idToken(), m_nonce);
|
||||
});
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::dataReady, this, [this](const QByteArray &data) {
|
||||
emit dataReady(data);
|
||||
});
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::errorOccurred, this, [] (QAbstractSocket::SocketError error) {
|
||||
qCDebug(dcCloud) << "Remote proxy Error:" << error;
|
||||
// emit NymeaTransportInterface::error(QAbstractSocket::ConnectionRefusedError);
|
||||
});
|
||||
QObject::connect(m_remoteproxyConnection, &RemoteProxyConnection::sslErrors, this, &CloudTransport::sslErrors);
|
||||
}
|
||||
|
||||
bool CloudTransport::connect(const QUrl &url)
|
||||
{
|
||||
if (!m_awsClient->isLoggedIn()) {
|
||||
qWarning() << "Not logged in to AWS, cannot connect";
|
||||
return false;
|
||||
}
|
||||
|
||||
qCDebug(dcCloud) << "Connecting to" << url;
|
||||
m_url = url;
|
||||
|
||||
m_nonce = QUuid::createUuid().toString();
|
||||
bool postResult = m_awsClient->postToMQTT(url.host(), m_nonce, QPointer<QObject>(this), [this](bool success) {
|
||||
if (success) {
|
||||
qCDebug(dcCloud) << "MQTT Post done. Connecting to remote proxy";
|
||||
m_remoteproxyConnection->connectServer(QUrl("wss://remoteproxy.nymea.io"));
|
||||
} else {
|
||||
qCDebug(dcCloud) << "Posting to MQTT failed";
|
||||
emit error(QAbstractSocket::HostNotFoundError);
|
||||
}
|
||||
});
|
||||
|
||||
if (!postResult) {
|
||||
qWarning() << "Failed to post to MQTT. Cannot continue";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QUrl CloudTransport::url() const
|
||||
{
|
||||
return m_url;
|
||||
}
|
||||
|
||||
void CloudTransport::disconnect()
|
||||
{
|
||||
qCDebug(dcCloud) << "CloudTransport: Disconnecting from server.";
|
||||
m_remoteproxyConnection->disconnectServer();
|
||||
}
|
||||
|
||||
NymeaTransportInterface::ConnectionState CloudTransport::connectionState() const
|
||||
{
|
||||
switch (m_remoteproxyConnection->state()) {
|
||||
case RemoteProxyConnection::StateRemoteConnected:
|
||||
return NymeaTransportInterface::ConnectionStateConnected;
|
||||
case RemoteProxyConnection::StateInitializing:
|
||||
case RemoteProxyConnection::StateHostLookup:
|
||||
case RemoteProxyConnection::StateConnecting:
|
||||
case RemoteProxyConnection::StateConnected:
|
||||
case RemoteProxyConnection::StateAuthenticating:
|
||||
case RemoteProxyConnection::StateReady:
|
||||
case RemoteProxyConnection::StateAuthenticated:
|
||||
return NymeaTransportInterface::ConnectionStateConnecting;
|
||||
case RemoteProxyConnection::StateDisconnected:
|
||||
case RemoteProxyConnection::StateDiconnecting:
|
||||
return NymeaTransportInterface::ConnectionStateDisconnected;
|
||||
}
|
||||
return ConnectionStateDisconnected;
|
||||
}
|
||||
|
||||
void CloudTransport::sendData(const QByteArray &data)
|
||||
{
|
||||
// qCDebug(dcCloud) << "Cloud transport: Sending data:" << data;
|
||||
m_remoteproxyConnection->sendData(data);
|
||||
}
|
||||
|
||||
void CloudTransport::ignoreSslErrors(const QList<QSslError> &errors)
|
||||
{
|
||||
qCDebug(dcCloud) << "CloudTransport: Ignoring SSL errors" << errors;
|
||||
m_remoteproxyConnection->ignoreSslErrors(errors);
|
||||
}
|
||||
|
||||
CloudTransportFactory::CloudTransportFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
NymeaTransportInterface *CloudTransportFactory::createTransport(QObject *parent) const
|
||||
{
|
||||
return new CloudTransport(AWSClient::instance(), parent);
|
||||
}
|
||||
|
||||
QStringList CloudTransportFactory::supportedSchemes() const
|
||||
{
|
||||
return {"cloud"};
|
||||
}
|
||||
|
||||
@ -1,72 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef CLOUDTRANSPORT_H
|
||||
#define CLOUDTRANSPORT_H
|
||||
|
||||
#include "nymeatransportinterface.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
class AWSClient;
|
||||
namespace remoteproxyclient {
|
||||
class RemoteProxyConnection;
|
||||
}
|
||||
|
||||
class CloudTransportFactory: public NymeaTransportInterfaceFactory
|
||||
{
|
||||
public:
|
||||
CloudTransportFactory();
|
||||
NymeaTransportInterface* createTransport(QObject *parent = nullptr) const override;
|
||||
QStringList supportedSchemes() const override;
|
||||
};
|
||||
|
||||
class CloudTransport : public NymeaTransportInterface
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CloudTransport(AWSClient *awsClient, QObject *parent = nullptr);
|
||||
|
||||
bool connect(const QUrl &url) override;
|
||||
QUrl url() const override;
|
||||
void disconnect() override;
|
||||
ConnectionState connectionState() const override;
|
||||
void sendData(const QByteArray &data) override;
|
||||
|
||||
void ignoreSslErrors(const QList<QSslError> &errors) override;
|
||||
private:
|
||||
QUrl m_url;
|
||||
AWSClient *m_awsClient = nullptr;
|
||||
remoteproxyclient::RemoteProxyConnection *m_remoteproxyConnection = nullptr;
|
||||
QString m_nonce;
|
||||
};
|
||||
|
||||
#endif // CLOUDTRANSPORT_H
|
||||
@ -32,7 +32,6 @@
|
||||
#include "upnpdiscovery.h"
|
||||
#include "zeroconfdiscovery.h"
|
||||
#include "bluetoothservicediscovery.h"
|
||||
#include "connection/awsclient.h"
|
||||
#include "../nymeahost.h"
|
||||
|
||||
#include <QUuid>
|
||||
@ -50,14 +49,6 @@ NymeaDiscovery::NymeaDiscovery(QObject *parent) : QObject(parent)
|
||||
m_nymeaHosts = new NymeaHosts(this);
|
||||
|
||||
loadFromDisk();
|
||||
|
||||
m_cloudPollTimer.setInterval(5000);
|
||||
connect(&m_cloudPollTimer, &QTimer::timeout, this, [this](){
|
||||
if (m_awsClient && m_awsClient->isLoggedIn()) {
|
||||
m_awsClient->fetchDevices();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
NymeaDiscovery::~NymeaDiscovery()
|
||||
@ -98,12 +89,6 @@ void NymeaDiscovery::setDiscovering(bool discovering)
|
||||
m_bluetooth->discover();
|
||||
}
|
||||
|
||||
// start polling cloud
|
||||
m_cloudPollTimer.start();
|
||||
// If we're logged in, poll right away
|
||||
if (m_awsClient && m_awsClient->isLoggedIn()) {
|
||||
m_awsClient->fetchDevices();
|
||||
}
|
||||
} else {
|
||||
|
||||
if (m_upnp) {
|
||||
@ -113,8 +98,6 @@ void NymeaDiscovery::setDiscovering(bool discovering)
|
||||
if (m_bluetooth) {
|
||||
m_bluetooth->stopDiscovery();
|
||||
}
|
||||
|
||||
m_cloudPollTimer.stop();
|
||||
}
|
||||
|
||||
emit discoveringChanged();
|
||||
@ -125,23 +108,6 @@ NymeaHosts *NymeaDiscovery::nymeaHosts() const
|
||||
return m_nymeaHosts;
|
||||
}
|
||||
|
||||
AWSClient *NymeaDiscovery::awsClient() const
|
||||
{
|
||||
return m_awsClient;
|
||||
}
|
||||
|
||||
void NymeaDiscovery::setAwsClient(AWSClient *awsClient)
|
||||
{
|
||||
if (m_awsClient != awsClient) {
|
||||
m_awsClient = awsClient;
|
||||
emit awsClientChanged();
|
||||
}
|
||||
|
||||
if (m_awsClient) {
|
||||
connect(m_awsClient, &AWSClient::devicesFetched, this, &NymeaDiscovery::syncCloudDevices);
|
||||
}
|
||||
}
|
||||
|
||||
void NymeaDiscovery::cacheHost(NymeaHost *host)
|
||||
{
|
||||
QSettings settings;
|
||||
@ -231,52 +197,6 @@ void NymeaDiscovery::setUpnpDiscoveryEnabled(bool upnpDiscoveryEnabled)
|
||||
}
|
||||
}
|
||||
|
||||
void NymeaDiscovery::syncCloudDevices()
|
||||
{
|
||||
for (int i = 0; i < m_awsClient->awsDevices()->rowCount(); i++) {
|
||||
AWSDevice *d = m_awsClient->awsDevices()->get(i);
|
||||
NymeaHost *host = m_nymeaHosts->find(d->id());
|
||||
bool alreayAdded = host != nullptr;
|
||||
if (!alreayAdded) {
|
||||
host = new NymeaHost();
|
||||
host->setUuid(d->id());
|
||||
}
|
||||
host->setName(d->name());
|
||||
QUrl url;
|
||||
url.setScheme("cloud");
|
||||
url.setHost(d->id());
|
||||
Connection *conn = host->connections()->find(url);
|
||||
if (!conn) {
|
||||
conn = new Connection(url, Connection::BearerTypeCloud, true, d->id());
|
||||
qCDebug(dcDiscovery) << "Adding new connection to host:" << host->name() << conn->url().toString();
|
||||
host->connections()->addConnection(conn);
|
||||
}
|
||||
conn->setOnline(d->online());
|
||||
if (!alreayAdded) {
|
||||
qCDebug(dcDiscovery) << "Adding new host:" << d->name() << d->id();
|
||||
m_nymeaHosts->addHost(host);
|
||||
}
|
||||
}
|
||||
|
||||
QList<NymeaHost*> hostsToRemove;
|
||||
for (int i = 0; i < m_nymeaHosts->rowCount(); i++) {
|
||||
NymeaHost *host = m_nymeaHosts->get(i);
|
||||
for (int j = 0; j < host->connections()->rowCount(); j++) {
|
||||
if (host->connections()->get(j)->bearerType() == Connection::BearerTypeCloud) {
|
||||
if (m_awsClient->awsDevices()->getDevice(host->uuid().toString()) == nullptr) {
|
||||
host->connections()->removeConnection(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (host->connections()->rowCount() == 0) {
|
||||
hostsToRemove.append(host);
|
||||
}
|
||||
}
|
||||
while (!hostsToRemove.isEmpty()) {
|
||||
m_nymeaHosts->removeHost(hostsToRemove.takeFirst());
|
||||
}
|
||||
}
|
||||
|
||||
void NymeaDiscovery::loadFromDisk()
|
||||
{
|
||||
|
||||
@ -35,7 +35,6 @@
|
||||
#include <QTimer>
|
||||
#include <QUuid>
|
||||
|
||||
#include "connection/awsclient.h"
|
||||
#include "connection/nymeahost.h"
|
||||
|
||||
class NymeaHosts;
|
||||
@ -52,8 +51,6 @@ class NymeaDiscovery : public QObject
|
||||
Q_PROPERTY(bool zeroconfDiscoveryEnabled READ zeroconfDiscoveryEnable WRITE setZeroconfDiscoveryEnabled NOTIFY zeroconfDiscoveryEnabledChanged)
|
||||
Q_PROPERTY(bool upnpDiscoveryEnabled READ upnpDiscoveryEnabled WRITE setUpnpDiscoveryEnabled NOTIFY upnpDiscoveryEnabledChanged)
|
||||
|
||||
Q_PROPERTY(AWSClient* awsClient READ awsClient WRITE setAwsClient NOTIFY awsClientChanged)
|
||||
|
||||
Q_PROPERTY(NymeaHosts* nymeaHosts READ nymeaHosts CONSTANT)
|
||||
|
||||
public:
|
||||
@ -65,9 +62,6 @@ public:
|
||||
|
||||
NymeaHosts *nymeaHosts() const;
|
||||
|
||||
AWSClient* awsClient() const;
|
||||
void setAwsClient(AWSClient *awsClient);
|
||||
|
||||
Q_INVOKABLE void cacheHost(NymeaHost* host);
|
||||
|
||||
bool zeroconfDiscoveryEnable() const;
|
||||
@ -81,7 +75,6 @@ public slots:
|
||||
|
||||
signals:
|
||||
void discoveringChanged();
|
||||
void awsClientChanged();
|
||||
|
||||
void serverUuidResolved(const QUuid &uuid, const QString &url);
|
||||
|
||||
@ -90,8 +83,6 @@ signals:
|
||||
void upnpDiscoveryEnabledChanged(bool upnpDiscoveryEnabled);
|
||||
|
||||
private slots:
|
||||
void syncCloudDevices();
|
||||
|
||||
void loadFromDisk();
|
||||
|
||||
void updateActiveBearers();
|
||||
@ -100,14 +91,10 @@ private:
|
||||
bool m_discovering = false;
|
||||
NymeaHosts *m_nymeaHosts = nullptr;
|
||||
|
||||
AWSClient *m_awsClient = nullptr;
|
||||
|
||||
UpnpDiscovery *m_upnp = nullptr;
|
||||
ZeroconfDiscovery *m_zeroConf = nullptr;
|
||||
BluetoothServiceDiscovery *m_bluetooth = nullptr;
|
||||
|
||||
QTimer m_cloudPollTimer;
|
||||
|
||||
QList<QUuid> m_pendingHostResolutions;
|
||||
|
||||
bool m_zeroconfDiscoveryEnabled = true;
|
||||
|
||||
@ -1,177 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#include "sigv4utils.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QCryptographicHash>
|
||||
#include <QMessageAuthenticationCode>
|
||||
#include <QtDebug>
|
||||
#include <QUrlQuery>
|
||||
#include <QList>
|
||||
|
||||
SigV4Utils::SigV4Utils()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void SigV4Utils::signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString ®ion, const QString &service, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray &payload)
|
||||
{
|
||||
QByteArray dateTime;
|
||||
if (request.rawHeaderList().contains("X-Amz-Date")) {
|
||||
dateTime = request.rawHeader("X-AMZ-Date");
|
||||
} else {
|
||||
dateTime = SigV4Utils::getCurrentDateTime();
|
||||
request.setRawHeader("X-Amz-Date", dateTime);
|
||||
}
|
||||
|
||||
if (!sessionToken.isEmpty()) {
|
||||
request.setRawHeader("x-amz-security-token", sessionToken);
|
||||
}
|
||||
|
||||
QByteArray canonicalRequest = SigV4Utils::getCanonicalRequest(operation, request, payload);
|
||||
// qDebug() << "canonical request:" << qUtf8Printable(canonicalRequest);
|
||||
QByteArray stringToSign = SigV4Utils::getStringToSign(canonicalRequest, dateTime, region.toUtf8(), service.toUtf8());
|
||||
// qDebug() << "string to sign:" << stringToSign;
|
||||
QByteArray signature = SigV4Utils::getSignature(stringToSign, secretAccessKey, dateTime, region, service);
|
||||
// qDebug() << "signature:" << signature;
|
||||
QByteArray authorizeHeader = SigV4Utils::getAuthorizationHeader(accessKeyId, dateTime, region, service, request, signature);
|
||||
|
||||
request.setRawHeader("Authorization", authorizeHeader);
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getCurrentDateTime()
|
||||
{
|
||||
return QDateTime::currentDateTime().toUTC().toString("yyyyMMddThhmmssZ").toUtf8();
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray ®ion, const QByteArray &service, const QByteArray &payload)
|
||||
{
|
||||
QByteArray algorithm = "AWS4-HMAC-SHA256";
|
||||
QByteArray dateTime = getCurrentDateTime();
|
||||
QByteArray credentialScope = getCredentialScope(dateTime, region, service);
|
||||
|
||||
QByteArray canonicalQueryString;
|
||||
canonicalQueryString += "X-Amz-Algorithm=AWS4-HMAC-SHA256";
|
||||
canonicalQueryString += "&X-Amz-Credential=" + QByteArray(accessKeyId + '/' + credentialScope).toPercentEncoding();
|
||||
canonicalQueryString += "&X-Amz-Date=" + dateTime;
|
||||
if (request.rawHeaderList().count() > 0){
|
||||
canonicalQueryString += "&X-Amz-SignedHeaders=" + request.rawHeaderList().join(';').toLower();
|
||||
}
|
||||
|
||||
QByteArray canonicalRequest = getCanonicalRequest(QNetworkAccessManager::GetOperation, request, payload);
|
||||
|
||||
QByteArray stringToSign = getStringToSign(canonicalRequest, dateTime, region, service);
|
||||
QByteArray signature = getSignature(stringToSign, secretAccessKey, dateTime, region, service);
|
||||
|
||||
canonicalQueryString += "&X-Amz-Signature=" + signature;
|
||||
|
||||
if (!sessionToken.isEmpty()) {
|
||||
canonicalQueryString += "&X-Amz-Security-Token=" + sessionToken.toPercentEncoding();
|
||||
}
|
||||
|
||||
return canonicalQueryString;
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray ®ion, const QByteArray &service)
|
||||
{
|
||||
QCryptographicHash::Algorithm hashAlgorithm = QCryptographicHash::Sha256;
|
||||
return QMessageAuthenticationCode::hash("aws4_request",
|
||||
QMessageAuthenticationCode::hash(service,
|
||||
QMessageAuthenticationCode::hash(region,
|
||||
QMessageAuthenticationCode::hash(date, "AWS4"+key,
|
||||
hashAlgorithm), hashAlgorithm), hashAlgorithm), hashAlgorithm);
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload)
|
||||
{
|
||||
QByteArray canonicalRequest;
|
||||
|
||||
QByteArray method;
|
||||
switch (operation) {
|
||||
case QNetworkAccessManager::GetOperation:
|
||||
method = "GET";
|
||||
break;
|
||||
case QNetworkAccessManager::PostOperation:
|
||||
method = "POST";
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT_X(false, "Network operation not implemented", "SigV4Utils");
|
||||
}
|
||||
QByteArray uri = request.url().path(QUrl::FullyEncoded).toUtf8();
|
||||
QUrlQuery query(request.url());
|
||||
QList<QPair<QString, QString> > queryItems = query.queryItems();
|
||||
QStringList queryItemStrings;
|
||||
for (int i = 0; i < queryItems.count(); i++) {
|
||||
QPair<QString, QString> queryItem = queryItems.at(i);
|
||||
queryItemStrings.append(queryItem.first + '=' + queryItem.second);
|
||||
}
|
||||
queryItemStrings.sort(Qt::CaseInsensitive);
|
||||
|
||||
QByteArray canonicalQueryString = queryItemStrings.join('&').toUtf8();
|
||||
|
||||
QByteArray canonicalHeaders;
|
||||
foreach(const QByteArray &headerName, request.rawHeaderList()) {
|
||||
canonicalHeaders += headerName.toLower() + ':' + request.rawHeader(headerName) + '\n';
|
||||
}
|
||||
|
||||
QByteArray payloadHash = QCryptographicHash::hash(payload, QCryptographicHash::Sha256).toHex();
|
||||
|
||||
canonicalRequest = method + '\n' + uri + '\n' + canonicalQueryString + '\n' + canonicalHeaders + '\n' + request.rawHeaderList().join(';').toLower() + '\n' + payloadHash;
|
||||
return canonicalRequest;
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getCredentialScope(const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service)
|
||||
{
|
||||
QByteArray credentialScope = dateTime.left(8) + '/' + region + '/' + service + "/aws4_request";
|
||||
return credentialScope;
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service)
|
||||
{
|
||||
QByteArray algorithm = "AWS4-HMAC-SHA256";
|
||||
QByteArray credentialScope = getCredentialScope(dateTime, region, service);
|
||||
|
||||
QByteArray stringToSign = algorithm + '\n' + dateTime + '\n' + credentialScope + '\n' + QCryptographicHash::hash(canonicalRequest, QCryptographicHash::Sha256).toHex();
|
||||
return stringToSign;
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString ®ion, const QString &service)
|
||||
{
|
||||
QByteArray signingKey = getSignatureKey(secretAccessKey, dateTime.left(8), region.toUtf8(), service.toUtf8());
|
||||
QByteArray signature = QMessageAuthenticationCode::hash(stringToSign, signingKey, QCryptographicHash::Sha256).toHex();
|
||||
return signature;
|
||||
}
|
||||
|
||||
QByteArray SigV4Utils::getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString ®ion, const QString &service, const QNetworkRequest &request, const QByteArray &signature)
|
||||
{
|
||||
QByteArray authHeader = "AWS4-HMAC-SHA256 Credential=" + accessKeyId + '/' + dateTime.left(8) + '/' + region.toUtf8() + '/' + service.toUtf8() + '/' + "aws4_request, SignedHeaders=" + request.rawHeaderList().join(';').toLower() + ", Signature=" + signature;
|
||||
return authHeader;
|
||||
}
|
||||
@ -1,61 +0,0 @@
|
||||
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
||||
*
|
||||
* Copyright 2013 - 2020, nymea GmbH
|
||||
* Contact: contact@nymea.io
|
||||
*
|
||||
* This file is part of nymea.
|
||||
* This project including source code and documentation is protected by
|
||||
* copyright law, and remains the property of nymea GmbH. All rights, including
|
||||
* reproduction, publication, editing and translation, are reserved. The use of
|
||||
* this project is subject to the terms of a license agreement to be concluded
|
||||
* with nymea GmbH in accordance with the terms of use of nymea GmbH, available
|
||||
* under https://nymea.io/license
|
||||
*
|
||||
* GNU General Public License Usage
|
||||
* Alternatively, this project may be redistributed and/or modified under the
|
||||
* terms of the GNU General Public License as published by the Free Software
|
||||
* Foundation, GNU version 3. This project is distributed in the hope that it
|
||||
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this project. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
* For any further details and any questions please contact us under
|
||||
* contact@nymea.io or see our FAQ/Licensing Information on
|
||||
* https://nymea.io/license/faq
|
||||
*
|
||||
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
|
||||
|
||||
#ifndef SIGV4UTILS_H
|
||||
#define SIGV4UTILS_H
|
||||
|
||||
#include <QString>
|
||||
#include <QNetworkRequest>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class SigV4Utils
|
||||
{
|
||||
public:
|
||||
SigV4Utils();
|
||||
|
||||
// Signes a request by adding the "X-AMZ-Date" (if not present) and "X-AMZ-Signature" headers
|
||||
static void signRequest(QNetworkAccessManager::Operation operation, QNetworkRequest &request, const QString ®ion, const QString &service, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken = QByteArray(), const QByteArray &payload = QByteArray());
|
||||
|
||||
|
||||
static QByteArray getCurrentDateTime();
|
||||
|
||||
|
||||
static QByteArray getCanonicalQueryString(const QNetworkRequest &request, const QByteArray &accessKeyId, const QByteArray &secretAccessKey, const QByteArray &sessionToken, const QByteArray ®ion, const QByteArray &service, const QByteArray &payload);
|
||||
static QByteArray getCanonicalRequest(QNetworkAccessManager::Operation operation, const QNetworkRequest &request, const QByteArray &payload);
|
||||
static QByteArray getCanonicalHeaders(const QNetworkRequest &request);
|
||||
static QByteArray getCredentialScope(const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service);
|
||||
static QByteArray getStringToSign(const QByteArray &canonicalRequest, const QByteArray &dateTime, const QByteArray ®ion, const QByteArray &service);
|
||||
static QByteArray getSignatureKey(const QByteArray &key, const QByteArray &date, const QByteArray ®ion, const QByteArray &service);
|
||||
static QByteArray getSignature(const QByteArray &stringToSign, const QByteArray &secretAccessKey, const QByteArray &dateTime, const QString ®ion, const QString &service);
|
||||
static QByteArray getAuthorizationHeader(const QByteArray &accessKeyId, const QByteArray &dateTime, const QString ®ion, const QString &service, const QNetworkRequest &request, const QByteArray &signature);
|
||||
|
||||
};
|
||||
|
||||
#endif // SIGV4UTILS_H
|
||||
@ -35,7 +35,6 @@
|
||||
#include "logmanager.h"
|
||||
#include "tagsmanager.h"
|
||||
#include "configuration/nymeaconfiguration.h"
|
||||
#include "connection/awsclient.h"
|
||||
#include "system/systemcontroller.h"
|
||||
#include "configuration/networkmanager.h"
|
||||
|
||||
@ -56,19 +55,7 @@ Engine::Engine(QObject *parent) :
|
||||
connect(m_thingManager, &ThingManager::fetchingDataChanged, this, &Engine::onThingManagerFetchingChanged);
|
||||
|
||||
connect(m_jsonRpcClient, &JsonRpcClient::connectedChanged, this, [this]() {
|
||||
qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected() << "AWS status:" << AWSClient::instance()->awsDevices()->rowCount();
|
||||
if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) {
|
||||
if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid()) == nullptr) {
|
||||
m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId());
|
||||
}
|
||||
}
|
||||
});
|
||||
connect(m_jsonRpcClient, &JsonRpcClient::cloudConnectionStateChanged, this, [this](){
|
||||
if (m_jsonRpcClient->connected() && m_jsonRpcClient->cloudConnectionState() == JsonRpcClient::CloudConnectionStateConnected) {
|
||||
if (AWSClient::instance()->awsDevices()->getDevice(m_jsonRpcClient->serverUuid()) == nullptr) {
|
||||
m_jsonRpcClient->setupRemoteAccess(AWSClient::instance()->idToken(), AWSClient::instance()->userId());
|
||||
}
|
||||
}
|
||||
qDebug() << "JSONRpc connected changed:" << m_jsonRpcClient->connected();
|
||||
});
|
||||
}
|
||||
|
||||
@ -112,22 +99,6 @@ SystemController *Engine::systemController() const
|
||||
return m_systemController;
|
||||
}
|
||||
|
||||
void Engine::deployCertificate()
|
||||
{
|
||||
if (!m_jsonRpcClient->connected()) {
|
||||
qWarning() << "JSONRPC not connected. Cannot deploy certificate";
|
||||
return;
|
||||
}
|
||||
if (!AWSClient::instance()->isLoggedIn()) {
|
||||
qWarning() << "Not logged in at AWS. Cannot deploy certificate";
|
||||
return;
|
||||
}
|
||||
AWSClient::instance()->fetchCertificate(m_jsonRpcClient->serverUuid(), [this](const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint){
|
||||
qDebug() << "Certificate received" << certificate << publicKey << privateKey;
|
||||
m_jsonRpcClient->deployCertificate(rootCA, certificate, publicKey, privateKey, endpoint);
|
||||
});
|
||||
}
|
||||
|
||||
void Engine::onConnectedChanged()
|
||||
{
|
||||
qDebug() << "Engine: connected changed:" << m_jsonRpcClient->connected();
|
||||
|
||||
@ -68,8 +68,6 @@ public:
|
||||
NymeaConfiguration *nymeaConfiguration() const;
|
||||
SystemController *systemController() const;
|
||||
|
||||
Q_INVOKABLE void deployCertificate();
|
||||
|
||||
private:
|
||||
JsonRpcClient *m_jsonRpcClient;
|
||||
ThingManager *m_thingManager;
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
#include "connection/tcpsockettransport.h"
|
||||
#include "connection/websockettransport.h"
|
||||
#include "connection/bluetoothtransport.h"
|
||||
#include "connection/cloudtransport.h"
|
||||
#include "connection/tunnelproxytransport.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
@ -61,7 +60,6 @@ JsonRpcClient::JsonRpcClient(QObject *parent) :
|
||||
m_connection->registerTransport(new TcpSocketTransportFactory());
|
||||
m_connection->registerTransport(new WebsocketTransportFactory());
|
||||
m_connection->registerTransport(new BluetoothTransportFactoy());
|
||||
m_connection->registerTransport(new CloudTransportFactory());
|
||||
m_connection->registerTransport(new TunnelProxyTransportFactory());
|
||||
|
||||
connect(m_connection, &NymeaConnection::availableBearerTypesChanged, this, &JsonRpcClient::availableBearerTypesChanged);
|
||||
@ -174,13 +172,6 @@ bool JsonRpcClient::tokenExists(const QString &serverUuid) const
|
||||
return settings.contains(QUuid(serverUuid).toString());
|
||||
}
|
||||
|
||||
void JsonRpcClient::getCloudConnectionStatus()
|
||||
{
|
||||
JsonRpcReply *reply = createReply("JSONRPC.IsCloudConnected", QVariantMap(), this, "isCloudConnectedReply");
|
||||
m_replies.insert(reply->commandId(), reply);
|
||||
sendRequest(reply->requestMap());
|
||||
}
|
||||
|
||||
void JsonRpcClient::setNotificationsEnabledResponse(int commandId, const QVariantMap ¶ms)
|
||||
{
|
||||
qCDebug(dcJsonRpc()) << "Notification configuration response:" << commandId << qUtf8Printable(QJsonDocument::fromVariant(params).toJson());
|
||||
@ -224,34 +215,9 @@ void JsonRpcClient::notificationReceived(const QVariantMap &data)
|
||||
return;
|
||||
}
|
||||
|
||||
if (data.value("notification").toString() == "JSONRPC.CloudConnectedChanged") {
|
||||
QMetaEnum connectionStateEnum = QMetaEnum::fromType<CloudConnectionState>();
|
||||
m_cloudConnectionState = static_cast<CloudConnectionState>(connectionStateEnum.keyToValue(data.value("params").toMap().value("connectionState").toByteArray().data()));
|
||||
emit cloudConnectionStateChanged();
|
||||
return;
|
||||
}
|
||||
|
||||
qCWarning(dcJsonRpc()) << "JsonRpcClient: Unhandled notification received" << data;
|
||||
}
|
||||
|
||||
void JsonRpcClient::isCloudConnectedReply(int /*commandId*/, const QVariantMap &data)
|
||||
{
|
||||
// qDebug() << "Cloud is connected" << data;
|
||||
QMetaEnum connectionStateEnum = QMetaEnum::fromType<CloudConnectionState>();
|
||||
m_cloudConnectionState = static_cast<CloudConnectionState>(connectionStateEnum.keyToValue(data.value("connectionState").toByteArray().data()));
|
||||
emit cloudConnectionStateChanged();
|
||||
}
|
||||
|
||||
void JsonRpcClient::setupRemoteAccessReply(int commandId, const QVariantMap &data)
|
||||
{
|
||||
qDebug() << "Setup Remote Access reply" << commandId << data;
|
||||
}
|
||||
|
||||
void JsonRpcClient::deployCertificateReply(int commandId, const QVariantMap &data)
|
||||
{
|
||||
qDebug() << "deploy certificate reply:" << commandId << data;
|
||||
}
|
||||
|
||||
void JsonRpcClient::getVersionsReply(int /*commandId*/, const QVariantMap &data)
|
||||
{
|
||||
m_serverQtVersion = data.value("qtVersion").toString();
|
||||
@ -317,23 +283,6 @@ bool JsonRpcClient::authenticated() const
|
||||
return m_authenticated;
|
||||
}
|
||||
|
||||
JsonRpcClient::CloudConnectionState JsonRpcClient::cloudConnectionState() const
|
||||
{
|
||||
return m_cloudConnectionState;
|
||||
}
|
||||
|
||||
void JsonRpcClient::deployCertificate(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint)
|
||||
{
|
||||
QVariantMap params;
|
||||
params.insert("rootCA", rootCA);
|
||||
params.insert("certificatePEM", certificate);
|
||||
params.insert("publicKey", publicKey);
|
||||
params.insert("privateKey", privateKey);
|
||||
params.insert("endpoint", endpoint);
|
||||
|
||||
sendCommand("JSONRPC.SetupCloudConnection", params, this, "deployCertificateReply");
|
||||
}
|
||||
|
||||
QHash<QString, QString> JsonRpcClient::cacheHashes() const
|
||||
{
|
||||
return m_cacheHashes;
|
||||
@ -424,15 +373,6 @@ int JsonRpcClient::requestPushButtonAuth(const QString &deviceName)
|
||||
return reply->commandId();
|
||||
}
|
||||
|
||||
int JsonRpcClient::setupRemoteAccess(const QString &idToken, const QString &userId)
|
||||
{
|
||||
qDebug() << "Calling SetupRemoteAccess";
|
||||
QVariantMap params;
|
||||
params.insert("idToken", idToken);
|
||||
params.insert("userId", userId);
|
||||
return sendCommand("JSONRPC.SetupRemoteAccess", params, this, "setupRemoteAccessReply");
|
||||
}
|
||||
|
||||
bool JsonRpcClient::ensureServerVersion(const QString &jsonRpcVersion)
|
||||
{
|
||||
return QVersionNumber(m_jsonRpcVersion) >= QVersionNumber::fromString(jsonRpcVersion);
|
||||
@ -731,7 +671,7 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms)
|
||||
}
|
||||
|
||||
QVersionNumber minimumRequiredVersion = QVersionNumber(5, 0);
|
||||
QVersionNumber maximumMajorVersion = QVersionNumber(6);
|
||||
QVersionNumber maximumMajorVersion = QVersionNumber(7);
|
||||
if (m_jsonRpcVersion < minimumRequiredVersion) {
|
||||
qCWarning(dcJsonRpc()) << "Nymea core doesn't support minimum required version. Required:" << minimumRequiredVersion << "Found:" << m_jsonRpcVersion;
|
||||
emit invalidMinimumVersion(m_jsonRpcVersion.toString(), minimumRequiredVersion.toString());
|
||||
@ -829,8 +769,6 @@ void JsonRpcClient::helloReply(int /*commandId*/, const QVariantMap ¶ms)
|
||||
}
|
||||
|
||||
setNotificationsEnabled();
|
||||
getCloudConnectionStatus();
|
||||
|
||||
}
|
||||
|
||||
JsonRpcReply::JsonRpcReply(int commandId, QString nameSpace, QString method, QVariantMap params, QPointer<QObject> caller, const QString &callback):
|
||||
|
||||
@ -55,7 +55,6 @@ class JsonRpcClient : public QObject
|
||||
Q_PROPERTY(bool authenticationRequired READ authenticationRequired NOTIFY authenticationRequiredChanged)
|
||||
Q_PROPERTY(bool pushButtonAuthAvailable READ pushButtonAuthAvailable NOTIFY pushButtonAuthAvailableChanged)
|
||||
Q_PROPERTY(bool authenticated READ authenticated NOTIFY authenticatedChanged)
|
||||
Q_PROPERTY(CloudConnectionState cloudConnectionState READ cloudConnectionState NOTIFY cloudConnectionStateChanged)
|
||||
Q_PROPERTY(QString serverVersion READ serverVersion NOTIFY handshakeReceived)
|
||||
Q_PROPERTY(QString jsonRpcVersion READ jsonRpcVersion NOTIFY handshakeReceived)
|
||||
Q_PROPERTY(QString serverUuid READ serverUuid NOTIFY handshakeReceived)
|
||||
@ -67,14 +66,6 @@ class JsonRpcClient : public QObject
|
||||
Q_PROPERTY(UserInfo::PermissionScopes permissions READ permissions NOTIFY permissionsChanged)
|
||||
|
||||
public:
|
||||
enum CloudConnectionState {
|
||||
CloudConnectionStateDisabled,
|
||||
CloudConnectionStateUnconfigured,
|
||||
CloudConnectionStateConnecting,
|
||||
CloudConnectionStateConnected
|
||||
};
|
||||
Q_ENUM(CloudConnectionState)
|
||||
|
||||
explicit JsonRpcClient(QObject *parent = nullptr);
|
||||
|
||||
void registerNotificationHandler(QObject *handler, const QString &nameSpace, const QString &method);
|
||||
@ -93,8 +84,6 @@ public:
|
||||
bool authenticationRequired() const;
|
||||
bool pushButtonAuthAvailable() const;
|
||||
bool authenticated() const;
|
||||
CloudConnectionState cloudConnectionState() const;
|
||||
void deployCertificate(const QByteArray &rootCA, const QByteArray &certificate, const QByteArray &publicKey, const QByteArray &privateKey, const QString &endpoint);
|
||||
QHash<QString, QString> cacheHashes() const;
|
||||
// Note: This does not reflect the actual permission scopes of the user but is translated to effective permissions
|
||||
// That, is, if the user has the admin permission, all of the other scopes will be set too even if they might not be explicitly set
|
||||
@ -119,7 +108,6 @@ public:
|
||||
Q_INVOKABLE int createUser(const QString &username, const QString &password, const QString &displayName, const QString &email);
|
||||
Q_INVOKABLE int authenticate(const QString &username, const QString &password, const QString &deviceName);
|
||||
Q_INVOKABLE int requestPushButtonAuth(const QString &deviceName);
|
||||
Q_INVOKABLE int setupRemoteAccess(const QString &idToken, const QString &userId);
|
||||
|
||||
|
||||
signals:
|
||||
@ -142,7 +130,6 @@ signals:
|
||||
void pushButtonAuthFailed();
|
||||
void createUserSucceeded();
|
||||
void createUserFailed(const QString &error);
|
||||
void cloudConnectionStateChanged();
|
||||
void serverQtVersionChanged();
|
||||
void serverNameChanged();
|
||||
void permissionsChanged();
|
||||
@ -170,7 +157,6 @@ private:
|
||||
bool m_authenticationRequired = false;
|
||||
bool m_pushButtonAuthAvailable = false;
|
||||
bool m_authenticated = false;
|
||||
CloudConnectionState m_cloudConnectionState = CloudConnectionStateDisabled;
|
||||
int m_pendingPushButtonTransaction = -1;
|
||||
QString m_serverUuid;
|
||||
QVersionNumber m_jsonRpcVersion;
|
||||
@ -185,7 +171,6 @@ private:
|
||||
QString m_username;
|
||||
|
||||
void setNotificationsEnabled();
|
||||
void getCloudConnectionStatus();
|
||||
|
||||
// json handler
|
||||
Q_INVOKABLE void processAuthenticate(int commandId, const QVariantMap &data);
|
||||
@ -194,9 +179,6 @@ private:
|
||||
|
||||
Q_INVOKABLE void setNotificationsEnabledResponse(int commandId, const QVariantMap ¶ms);
|
||||
Q_INVOKABLE void notificationReceived(const QVariantMap &data);
|
||||
Q_INVOKABLE void isCloudConnectedReply(int commandId, const QVariantMap &data);
|
||||
Q_INVOKABLE void setupRemoteAccessReply(int commandId, const QVariantMap &data);
|
||||
Q_INVOKABLE void deployCertificateReply(int commandId, const QVariantMap &data);
|
||||
Q_INVOKABLE void getVersionsReply(int commandId, const QVariantMap &data);
|
||||
|
||||
void sendRequest(const QVariantMap &request);
|
||||
|
||||
@ -93,7 +93,6 @@
|
||||
#include "ruletemplates/statedescriptortemplate.h"
|
||||
#include "ruletemplates/ruleactiontemplate.h"
|
||||
#include "ruletemplates/ruleactionparamtemplate.h"
|
||||
#include "connection/awsclient.h"
|
||||
#include "models/thingmodel.h"
|
||||
#include "models/sortfilterproxymodel.h"
|
||||
#include "system/systemcontroller.h"
|
||||
@ -156,14 +155,6 @@ static QObject* interfacesModel_provider(QQmlEngine *engine, QJSEngine *scriptEn
|
||||
return new Interfaces();
|
||||
}
|
||||
|
||||
static QObject* awsClientProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
|
||||
return AWSClient::instance();
|
||||
}
|
||||
|
||||
static QObject* typesProvider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
@ -297,9 +288,6 @@ void registerQmlTypes() {
|
||||
qmlRegisterUncreatableType<WirelessAccessPoints>(uri, 1, 0, "WirelessAccessPoints", "Can't create this in QML. Get it from the Engine instance.");
|
||||
qmlRegisterType<WirelessAccessPointsProxy>(uri, 1, 0, "WirelessAccessPointsProxy");
|
||||
|
||||
qmlRegisterSingletonType<AWSClient>(uri, 1, 0, "AWSClient", awsClientProvider);
|
||||
qmlRegisterUncreatableType<AWSDevice>(uri, 1, 0, "AWSDevice", "Can't create this in QML. Get it from AWSClient");
|
||||
|
||||
qmlRegisterType<RuleTemplates>(uri, 1, 0, "RuleTemplates");
|
||||
qmlRegisterType<RuleTemplatesFilterModel>(uri, 1, 0, "RuleTemplatesFilterModel");
|
||||
qmlRegisterUncreatableType<RuleTemplate>(uri, 1, 0, "RuleTemplate", "Get them from RuleTemplates");
|
||||
|
||||
@ -124,7 +124,6 @@ SOURCES += \
|
||||
$${PWD}/connection/websockettransport.cpp \
|
||||
$${PWD}/connection/tcpsockettransport.cpp \
|
||||
$${PWD}/connection/bluetoothtransport.cpp \
|
||||
$${PWD}/connection/awsclient.cpp \
|
||||
$${PWD}/connection/discovery/nymeadiscovery.cpp \
|
||||
$${PWD}/connection/discovery/upnpdiscovery.cpp \
|
||||
$${PWD}/connection/discovery/zeroconfdiscovery.cpp \
|
||||
@ -165,8 +164,6 @@ SOURCES += \
|
||||
$${PWD}/ruletemplates/ruleactiontemplate.cpp \
|
||||
$${PWD}/ruletemplates/stateevaluatortemplate.cpp \
|
||||
$${PWD}/ruletemplates/statedescriptortemplate.cpp \
|
||||
$${PWD}/connection/cloudtransport.cpp \
|
||||
$${PWD}/connection/sigv4utils.cpp \
|
||||
$${PWD}/ruletemplates/ruleactionparamtemplate.cpp \
|
||||
$${PWD}/configuration/serverconfiguration.cpp \
|
||||
$${PWD}/configuration/serverconfigurations.cpp \
|
||||
@ -290,8 +287,6 @@ HEADERS += \
|
||||
$${PWD}/connection/websockettransport.h \
|
||||
$${PWD}/connection/tcpsockettransport.h \
|
||||
$${PWD}/connection/bluetoothtransport.h \
|
||||
$${PWD}/connection/awsclient.h \
|
||||
$${PWD}/connection/sigv4utils.h \
|
||||
$${PWD}/connection/discovery/nymeadiscovery.h \
|
||||
$${PWD}/connection/discovery/upnpdiscovery.h \
|
||||
$${PWD}/connection/discovery/zeroconfdiscovery.h \
|
||||
@ -333,7 +328,6 @@ HEADERS += \
|
||||
$${PWD}/ruletemplates/ruleactiontemplate.h \
|
||||
$${PWD}/ruletemplates/stateevaluatortemplate.h \
|
||||
$${PWD}/ruletemplates/statedescriptortemplate.h \
|
||||
$${PWD}/connection/cloudtransport.h \
|
||||
$${PWD}/ruletemplates/ruleactionparamtemplate.h \
|
||||
$${PWD}/configuration/serverconfiguration.h \
|
||||
$${PWD}/configuration/serverconfigurations.h \
|
||||
|
||||
@ -93,13 +93,11 @@
|
||||
<file>ui/system/PluginsPage.qml</file>
|
||||
<file>ui/system/PluginParamsPage.qml</file>
|
||||
<file>ui/system/AboutNymeaPage.qml</file>
|
||||
<file>ui/system/CloudSettingsPage.qml</file>
|
||||
<file>ui/system/ConnectionInterfacesPage.qml</file>
|
||||
<file>ui/system/ConnectionInterfaceDelegate.qml</file>
|
||||
<file>ui/appsettings/AboutPage.qml</file>
|
||||
<file>ui/appsettings/AppSettingsPage.qml</file>
|
||||
<file>ui/appsettings/DeveloperOptionsPage.qml</file>
|
||||
<file>ui/appsettings/CloudLoginPage.qml</file>
|
||||
<file>ui/fonts/Ubuntu-B.ttf</file>
|
||||
<file>ui/fonts/Ubuntu-BI.ttf</file>
|
||||
<file>ui/fonts/Ubuntu-C.ttf</file>
|
||||
|
||||
@ -100,12 +100,6 @@ ApplicationWindow {
|
||||
value: settings.units === "metric" ? Types.UnitSystemMetric : Types.UnitSystemImperial
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: AWSClient
|
||||
property: "config"
|
||||
value: "cloudEnvironment" in app ? app.cloudEnvironment : settings.cloudEnvironment
|
||||
}
|
||||
|
||||
Binding {
|
||||
target: PushNotifications
|
||||
property: "enabled"
|
||||
@ -141,7 +135,6 @@ ApplicationWindow {
|
||||
|
||||
property NymeaDiscovery nymeaDiscovery: NymeaDiscovery {
|
||||
objectName: "discovery"
|
||||
awsClient: AWSClient
|
||||
bluetoothDiscoveryEnabled: false// PlatformPermissions.bluetoothPermission === PlatformPermissions.PermissionStatusGranted
|
||||
}
|
||||
|
||||
|
||||
@ -61,48 +61,4 @@ SettingsPageBase {
|
||||
text: qsTr("Configure logging categories")
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("../appsettings/LoggingCategories.qml"))
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("Advanced options")
|
||||
visible: settings.showHiddenOptions
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.leftMargin: app.margins; Layout.rightMargin: app.margins
|
||||
visible: settings.showHiddenOptions
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Cloud environment")
|
||||
}
|
||||
|
||||
ComboBox {
|
||||
currentIndex: model.indexOf(app.settings.cloudEnvironment)
|
||||
model: AWSClient.availableConfigs
|
||||
onActivated: {
|
||||
app.settings.cloudEnvironment = model[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("nymea:cloud")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.margins
|
||||
Layout.rightMargin: Style.margins
|
||||
text: qsTr("Note: nymea:cloud is deprecated and will be removed in a future version.")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
NymeaItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Cloud login")
|
||||
subText: qsTr("Log into %1:cloud and manage connected %1 systems").arg(Configuration.systemName)
|
||||
iconName: "../images/connections/cloud.svg"
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("CloudLoginPage.qml"))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -186,27 +186,4 @@ SettingsPageBase {
|
||||
popup.open()
|
||||
}
|
||||
}
|
||||
|
||||
SettingsPageSectionHeader {
|
||||
text: qsTr("nymea:cloud")
|
||||
}
|
||||
|
||||
Label {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.margins
|
||||
Layout.rightMargin: Style.margins
|
||||
text: qsTr("Note: nymea:cloud based remote connection is deprecated and will be removed in a future version.")
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
NymeaItemDelegate {
|
||||
Layout.fillWidth: true
|
||||
iconName: "../images/connections/cloud.svg"
|
||||
text: qsTr("Cloud")
|
||||
subText: qsTr("Connect this %1 system to %1:cloud").arg(Configuration.systemName)
|
||||
visible: NymeaUtils.hasPermissionScope(engine.jsonRpcClient.permissions, UserInfo.PermissionScopeAdmin)
|
||||
onClicked: pageStack.push(Qt.resolvedUrl("CloudSettingsPage.qml"))
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
TEMPLATE = subdirs
|
||||
|
||||
SUBDIRS = testrunner unit
|
||||
SUBDIRS = testrunner
|
||||
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea
|
||||
@ -1,9 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
my-header1:value2,value2,value1
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;my-header1;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,6 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value2
|
||||
My-Header1:value2
|
||||
My-Header1:value1
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,7 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value2
|
||||
My-Header1:value2
|
||||
My-Header1:value1
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=c9d5ea9f3f72853aea855b47ea873832890dbdd183b4468f858259531a5138ea
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
dc7f04a3abfde8d472b0ab1a418b741b7c67174dad1551b4117b15527fbe966c
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=ba17b383a53190154eb5fa66a1b836cc297cc0a3d70a5d00705980573d8ff790
|
||||
@ -1,9 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
my-header1:value1,value2,value3
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;my-header1;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,6 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value1
|
||||
value2
|
||||
value3
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,7 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value1
|
||||
value2
|
||||
value3
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=ba17b383a53190154eb5fa66a1b836cc297cc0a3d70a5d00705980573d8ff790
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
b7b6cbfd8a0430b78891e986784da2630c8a135a8595cec25b26ea94f926ee55
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01
|
||||
@ -1,9 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
my-header1:value4,value1,value3,value2
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;my-header1;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,7 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value4
|
||||
My-Header1:value1
|
||||
My-Header1:value3
|
||||
My-Header1:value2
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,8 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1:value4
|
||||
My-Header1:value1
|
||||
My-Header1:value3
|
||||
My-Header1:value2
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;x-amz-date, Signature=08c7e5a9acfcfeb3ab6b2185e75ce8b1deb5e634ec47601a50643f830c755c01
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
31ce73cd3f3d9f66977ad3dd957dc47af14df92fcd8509f59b349e9137c58b86
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;my-header2;x-amz-date, Signature=acc3ed3afb60bb290fc8d2dd0098b9911fcaa05412b367055dee359757a9c736
|
||||
@ -1,10 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
my-header1:value1
|
||||
my-header2:"a b c"
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;my-header1;my-header2;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,5 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1: value1
|
||||
My-Header2: "a b c"
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,6 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
My-Header1: value1
|
||||
My-Header2: "a b c"
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;my-header1;my-header2;x-amz-date, Signature=acc3ed3afb60bb290fc8d2dd0098b9911fcaa05412b367055dee359757a9c736
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
a726db9b0df21c14f559d0a978e563112acb1b9e05476f0a6a1c7d68f28605c7
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=07ef7494c76fa4850883e2b006601f940f8a34d404d0cfa977f52a65bbf5f24f
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
6a968768eefaa713e2a6b16b589a8ea192661f098f37349f4e2c0082757446f9
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
Param1=value1
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=a67d582fa61cc504c4bae71f336f98b97f1ea3c7a6bfe1b6e45aec72011b9aeb
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
1e24db194ed7d0eec2de28d7369675a243488e08526e8c1c73571282f7c517ab
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
Param1=value1&Param2=value2
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?Param2=value2&Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?Param2=value2&Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=b97d918cfa904a5beff61c982a1b6f458b799221646efd99d3219ec94cdf2500
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
816cd5b414d056048ba4f7c5386d6e0533120fb1fcfa93762cf0fc39e2cf19e0
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=eedbc4e291e521cf13422ffca22be7d2eb8146eecf653089df300a15b2382bd1
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
Param1=Value1&Param1=value2
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?Param1=value2&Param1=Value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?Param1=value2&Param1=Value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=eedbc4e291e521cf13422ffca22be7d2eb8146eecf653089df300a15b2382bd1
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
704b4cef673542d84cdff252633f065e8daeba5f168b77116f8b1bcaf3d38f89
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5772eed61e12b33fae39ee5e7012498b51d56abc0abb7c60486157bd471c4694
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
Param1=value1&Param1=value2
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?Param1=value2&Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?Param1=value2&Param1=value1 HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5772eed61e12b33fae39ee5e7012498b51d56abc0abb7c60486157bd471c4694
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
c968629d70850097a2d8781c9bf7edcb988b04cac14cca9be4acc3595f884606
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz=-._~0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=9c3e54bfcdf0b19771a7f523ee5669cdf59bc7cc0884027167c21bb143a40197
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
c30d4703d9f799439be92736156d47ccfb2d879ddf56f5befa6d1d6aab979177
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
%E1%88%B4=bar
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /?ሴ=bar HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /?ሴ=bar HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=2cdec8eed098649ff3a119c94853b13c643bcf08f8b0a1d91e12c9027818dd04
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
eb30c5bed55734080471a834cc727ae56beb50e5f39d1bff6d0d38cb192a7073
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET / HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /example1/example2/../.. HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /example1/example2/../.. HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /example/.. HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /example/.. HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,4 +0,0 @@
|
||||
AWS4-HMAC-SHA256
|
||||
20150830T123600Z
|
||||
20150830/us-east-1/service/aws4_request
|
||||
bb579772317eb040ac9ed261061d46c1f17a8133879d6129b6e1c25292927e63
|
||||
@ -1 +0,0 @@
|
||||
AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
@ -1,8 +0,0 @@
|
||||
GET
|
||||
/
|
||||
|
||||
host:example.amazonaws.com
|
||||
x-amz-date:20150830T123600Z
|
||||
|
||||
host;x-amz-date
|
||||
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
|
||||
@ -1,3 +0,0 @@
|
||||
GET /./ HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
@ -1,4 +0,0 @@
|
||||
GET /./ HTTP/1.1
|
||||
Host:example.amazonaws.com
|
||||
X-Amz-Date:20150830T123600Z
|
||||
Authorization: AWS4-HMAC-SHA256 Credential=AKIDEXAMPLE/20150830/us-east-1/service/aws4_request, SignedHeaders=host;x-amz-date, Signature=5fa00fa31553b73ebf1942676e86291e8372ff2a2260956d9b8aae1d763fbf31
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user