~ubuntu-branches/ubuntu/trusty/digikam/trusty

« back to all changes in this revision

Viewing changes to extra/kipi-plugins/dlnaexport/extra/hupnp/src/devicehosting/messages/hevent_messages_p.cpp

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2012-09-27 21:41:30 UTC
  • mfrom: (1.2.43)
  • mto: This revision was merged to the branch mainline in revision 86.
  • Revision ID: package-import@ubuntu.com-20120927214130-i8v3ufr21nesp29i
Tags: 4:3.0.0~beta1a-1
* New upstream release

* Fix "wrongly conflicts phonon-backend-vlc" dropped (Closes: #688142)
* debian/watch include download.kde.org

* digikam 3.0.0 uses features from unreleased kdegraphics >=4.10 & ships 
a private version of the kdegraphics libs - this is not the Debian way :-(
* Unsatisfactory Conflicts: libkipi8, libkexiv2-10, libkdcraw20, libksane0
* Suspend digikam-dbg >130Mb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (C) 2010, 2011 Tuomo Penttinen, all rights reserved.
 
3
 *
 
4
 *  Author: Tuomo Penttinen <tp@herqq.org>
 
5
 *
 
6
 *  This file is part of Herqq UPnP (HUPnP) library.
 
7
 *
 
8
 *  Herqq UPnP is free software: you can redistribute it and/or modify
 
9
 *  it under the terms of the GNU Lesser General Public License as published by
 
10
 *  the Free Software Foundation, either version 3 of the License, or
 
11
 *  (at your option) any later version.
 
12
 *
 
13
 *  Herqq UPnP is distributed in the hope that it will be useful,
 
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
16
 *  GNU Lesser General Public License for more details.
 
17
 *
 
18
 *  You should have received a copy of the GNU Lesser General Public License
 
19
 *  along with Herqq UPnP. If not, see <http://www.gnu.org/licenses/>.
 
20
 */
 
21
 
 
22
#include "hevent_messages_p.h"
 
23
 
 
24
#include "../../general/hlogger_p.h"
 
25
 
 
26
#include <QtXml/QDomDocument>
 
27
 
 
28
#include <QtCore/QRegExp>
 
29
#include <QtCore/QStringList>
 
30
 
 
31
#include <QtNetwork/QHostAddress>
 
32
 
 
33
namespace Herqq
 
34
{
 
35
 
 
36
namespace Upnp
 
37
{
 
38
 
 
39
/*******************************************************************************
 
40
 * HSubscribeRequest
 
41
 *******************************************************************************/
 
42
namespace
 
43
{
 
44
inline bool isValidCallback(const QUrl& callback)
 
45
{
 
46
    return callback.isValid() && !callback.isEmpty() &&
 
47
           callback.scheme() == "http" && !(QHostAddress(callback.host()).isNull());
 
48
}
 
49
 
 
50
inline bool isValidEventUrl(const QUrl& eventUrl)
 
51
{
 
52
    return eventUrl.isValid() && !eventUrl.isEmpty() &&
 
53
        !(QHostAddress(eventUrl.host()).isNull());
 
54
}
 
55
}
 
56
 
 
57
HSubscribeRequest::HSubscribeRequest() :
 
58
    m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent()
 
59
{
 
60
}
 
61
 
 
62
HSubscribeRequest::HSubscribeRequest(
 
63
    const QUrl& eventUrl, const HSid& sid, const HTimeout& timeout) :
 
64
        m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent()
 
65
{
 
66
    HLOG(H_AT, H_FUN);
 
67
 
 
68
    if (!isValidEventUrl(eventUrl))
 
69
    {
 
70
        HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString()));
 
71
        return;
 
72
    }
 
73
    else if (sid.isEmpty())
 
74
    {
 
75
        HLOG_WARN("Empty SID");
 
76
        return;
 
77
    }
 
78
 
 
79
    m_timeout  = timeout;
 
80
    m_eventUrl = eventUrl;
 
81
    m_sid      = sid;
 
82
}
 
83
 
 
84
HSubscribeRequest::HSubscribeRequest(
 
85
    const QUrl& eventUrl, const HProductTokens& userAgent, const QUrl& callback,
 
86
    const HTimeout& timeout) :
 
87
        m_callbacks (), m_timeout(), m_sid(), m_eventUrl(), m_userAgent()
 
88
{
 
89
    HLOG(H_AT, H_FUN);
 
90
 
 
91
    if (!isValidEventUrl(eventUrl))
 
92
    {
 
93
        HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString()));
 
94
        return;
 
95
    }
 
96
    else if (!isValidCallback(callback))
 
97
    {
 
98
        HLOG_WARN(QString("Invalid callback: [%1]").arg(callback.toString()));
 
99
        return;
 
100
    }
 
101
 
 
102
    m_callbacks.push_back(callback);
 
103
 
 
104
    m_timeout   = timeout;
 
105
    m_eventUrl  = eventUrl;
 
106
    m_userAgent = userAgent;
 
107
}
 
108
 
 
109
HSubscribeRequest::HSubscribeRequest(
 
110
    const QUrl& eventUrl, const HProductTokens& userAgent,
 
111
    const QList<QUrl>& callbacks, const HTimeout& timeout) :
 
112
        m_callbacks(), m_timeout(), m_sid(), m_eventUrl(), m_userAgent()
 
113
{
 
114
    HLOG(H_AT, H_FUN);
 
115
 
 
116
    if (!isValidEventUrl(eventUrl))
 
117
    {
 
118
        HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString()));
 
119
        return;
 
120
    }
 
121
 
 
122
    foreach(const QUrl& callback, callbacks)
 
123
    {
 
124
        if (!isValidCallback(callback))
 
125
        {
 
126
            HLOG_WARN(QString("Invalid callback: [%1]").arg(callback.toString()));
 
127
            return;
 
128
        }
 
129
    }
 
130
 
 
131
    m_timeout   = timeout;
 
132
    m_eventUrl  = eventUrl;
 
133
    m_userAgent = userAgent;
 
134
    m_callbacks = callbacks;
 
135
}
 
136
 
 
137
HSubscribeRequest::~HSubscribeRequest()
 
138
{
 
139
}
 
140
 
 
141
namespace
 
142
{
 
143
QList<QUrl> parseCallbacks(const QString& arg)
 
144
{
 
145
    QList<QUrl> retVal;
 
146
 
 
147
    QStringList callbacks =
 
148
        arg.split(QRegExp("<[.]*>"), QString::SkipEmptyParts);
 
149
 
 
150
    foreach(QString callbackStr, callbacks)
 
151
    {
 
152
        QUrl callback(callbackStr.remove('<').remove('>'));
 
153
        if (!callback.isValid() || callback.isEmpty() || callback.scheme() != "http")
 
154
        {
 
155
            return QList<QUrl>();
 
156
        }
 
157
 
 
158
        retVal.push_back(callback);
 
159
    }
 
160
 
 
161
    return retVal;
 
162
}
 
163
}
 
164
 
 
165
HSubscribeRequest::RetVal HSubscribeRequest::setContents(
 
166
    const QString& nt, const QUrl& eventUrl, const QString& sid,
 
167
    const QString& callback, const QString& timeout, const QString& userAgent)
 
168
{
 
169
    HLOG(H_AT, H_FUN);
 
170
 
 
171
    // this has to be properly defined no matter what
 
172
    if (!isValidEventUrl(eventUrl))
 
173
    {
 
174
        HLOG_WARN(QString("Invalid eventURL: [%1]").arg(eventUrl.toString()));
 
175
        return BadRequest;
 
176
    }
 
177
 
 
178
    HSubscribeRequest tmp;
 
179
 
 
180
    // these fields are the same regardless of message type
 
181
    tmp.m_eventUrl = eventUrl;
 
182
    tmp.m_timeout  = timeout;
 
183
 
 
184
    if (!HSid(sid).isEmpty())
 
185
    {
 
186
        // this appears to be a renewal, confirm.
 
187
        if (!callback.isEmpty() || !nt.isEmpty())
 
188
        {
 
189
            return IncompatibleHeaders;
 
190
        }
 
191
 
 
192
        tmp.m_sid = sid;
 
193
 
 
194
        *this = tmp;
 
195
        return Success;
 
196
    }
 
197
 
 
198
    // this appears to be an initial subscription
 
199
 
 
200
    if (nt.simplified().compare("upnp:event", Qt::CaseInsensitive) != 0)
 
201
    {
 
202
        return PreConditionFailed;
 
203
    }
 
204
 
 
205
    tmp.m_callbacks = parseCallbacks(callback);
 
206
    if (tmp.m_callbacks.isEmpty())
 
207
    {
 
208
        return PreConditionFailed;
 
209
    }
 
210
 
 
211
    tmp.m_userAgent = HProductTokens(userAgent);
 
212
 
 
213
    *this = tmp;
 
214
    return Success;
 
215
}
 
216
 
 
217
/*******************************************************************************
 
218
 * HSubscribeResponse
 
219
 *******************************************************************************/
 
220
HSubscribeResponse::HSubscribeResponse() :
 
221
    m_sid(), m_timeout(), m_server(), m_responseGenerated()
 
222
{
 
223
}
 
224
 
 
225
HSubscribeResponse::HSubscribeResponse(
 
226
    const HSid& sid, const HProductTokens& server, const HTimeout& timeout,
 
227
    const QDateTime& responseGenerated) :
 
228
        m_sid(sid), m_timeout(timeout), m_server(server),
 
229
        m_responseGenerated(responseGenerated)
 
230
{
 
231
    if (m_sid.isEmpty())
 
232
    {
 
233
        *this = HSubscribeResponse();
 
234
    }
 
235
}
 
236
 
 
237
HSubscribeResponse::~HSubscribeResponse()
 
238
{
 
239
}
 
240
 
 
241
/*******************************************************************************
 
242
 * HUnsubscribeRequest
 
243
 *******************************************************************************/
 
244
HUnsubscribeRequest::HUnsubscribeRequest() :
 
245
    m_eventUrl(), m_sid()
 
246
{
 
247
}
 
248
 
 
249
HUnsubscribeRequest::HUnsubscribeRequest(const QUrl& eventUrl, const HSid& sid) :
 
250
    m_eventUrl(), m_sid()
 
251
{
 
252
    if (sid.isEmpty() || !isValidEventUrl(eventUrl))
 
253
    {
 
254
        return;
 
255
    }
 
256
 
 
257
    m_eventUrl = eventUrl;
 
258
    m_sid      = sid;
 
259
}
 
260
 
 
261
HUnsubscribeRequest::~HUnsubscribeRequest()
 
262
{
 
263
}
 
264
 
 
265
HUnsubscribeRequest::RetVal HUnsubscribeRequest::setContents(
 
266
    const QUrl& eventUrl, const QString& sid)
 
267
{
 
268
    HUnsubscribeRequest tmp;
 
269
 
 
270
    tmp.m_sid = sid;
 
271
    tmp.m_eventUrl = eventUrl;
 
272
 
 
273
    if (tmp.m_sid.isEmpty())
 
274
    {
 
275
        return PreConditionFailed;
 
276
    }
 
277
    else if (!isValidEventUrl(tmp.m_eventUrl))
 
278
    {
 
279
        return BadRequest;
 
280
    }
 
281
 
 
282
    *this = tmp;
 
283
    return Success;
 
284
}
 
285
 
 
286
/*******************************************************************************
 
287
 * HNotifyRequest
 
288
 *******************************************************************************/
 
289
namespace
 
290
{
 
291
HNotifyRequest::RetVal parseData(
 
292
    const QByteArray& data, QList<QPair<QString, QString> >& parsedData)
 
293
{
 
294
    HLOG(H_AT, H_FUN);
 
295
 
 
296
    QDomDocument dd;
 
297
    if (!dd.setContent(data, true))
 
298
    {
 
299
        return HNotifyRequest::InvalidContents;
 
300
    }
 
301
 
 
302
    //QDomNodeList propertySetNodes =
 
303
      //  dd.elementsByTagNameNS("urn:schemas-upnp.org:event-1-0", "propertyset");
 
304
 
 
305
    QDomElement propertySetElement = dd.firstChildElement("propertyset");
 
306
 
 
307
    if (propertySetElement.isNull())
 
308
    {
 
309
        return HNotifyRequest::InvalidContents;
 
310
    }
 
311
 
 
312
    QDomElement propertyElement =
 
313
        propertySetElement.firstChildElement("property");
 
314
        //propertySetNodes.at(0).toElement().elementsByTagNameNS(
 
315
          //  "urn:schemas-upnp.org:event-1-0", "property");
 
316
 
 
317
    QList<QPair<QString, QString> > tmp;
 
318
    while(!propertyElement.isNull())
 
319
    {
 
320
        QDomElement variableElement = propertyElement.firstChildElement();
 
321
        if (variableElement.isNull())
 
322
        {
 
323
            return HNotifyRequest::InvalidContents;
 
324
        }
 
325
 
 
326
        QDomText variableValue = variableElement.firstChild().toText();
 
327
        tmp.push_back(
 
328
            qMakePair(variableElement.localName(), variableValue.data()));
 
329
 
 
330
        propertyElement = propertyElement.nextSiblingElement("property");
 
331
    }
 
332
 
 
333
    parsedData = tmp;
 
334
    return HNotifyRequest::Success;
 
335
}
 
336
}
 
337
 
 
338
HNotifyRequest::HNotifyRequest() :
 
339
    m_callback(), m_sid(), m_seq(0), m_dataAsVariables(), m_data()
 
340
{
 
341
}
 
342
 
 
343
HNotifyRequest::HNotifyRequest(
 
344
    const QUrl& callback, const HSid& sid,
 
345
    quint32 seq, const QByteArray& contents) :
 
346
        m_callback(), m_sid(), m_seq(0), m_dataAsVariables(),
 
347
        m_data    ()
 
348
{
 
349
    HLOG(H_AT, H_FUN);
 
350
 
 
351
    if (!isValidCallback(callback) || sid.isEmpty() || contents.isEmpty())
 
352
    {
 
353
        return;
 
354
    }
 
355
 
 
356
    if (parseData(contents, m_dataAsVariables) != Success)
 
357
    {
 
358
        return;
 
359
    }
 
360
 
 
361
    m_callback = callback;
 
362
    m_sid      = sid;
 
363
    m_seq      = seq;
 
364
    m_data     = contents;
 
365
}
 
366
 
 
367
HNotifyRequest::~HNotifyRequest()
 
368
{
 
369
}
 
370
 
 
371
HNotifyRequest::RetVal HNotifyRequest::setContents(
 
372
    const QUrl& callback,
 
373
    const QString& nt, const QString& nts, const QString& sid,
 
374
    const QString& seq, const QString& contents)
 
375
{
 
376
    HLOG(H_AT, H_FUN);
 
377
 
 
378
    HNt tmpNt(nt, nts);
 
379
    if (tmpNt.type   () != HNt::Type_UpnpEvent ||
 
380
        tmpNt.subType() != HNt::SubType_UpnpPropChange)
 
381
    {
 
382
        return PreConditionFailed;
 
383
    }
 
384
 
 
385
    HNotifyRequest tmp;
 
386
 
 
387
    tmp.m_callback = callback;
 
388
    if (!isValidCallback(tmp.m_callback))
 
389
    {
 
390
        return BadRequest;
 
391
    }
 
392
 
 
393
    tmp.m_sid = sid;
 
394
    if (tmp.m_sid.isEmpty())
 
395
    {
 
396
        return PreConditionFailed;
 
397
    }
 
398
 
 
399
    QString tmpSeq = seq.trimmed();
 
400
 
 
401
    bool ok = false;
 
402
    tmp.m_seq = tmpSeq.toUInt(&ok);
 
403
    if (!ok)
 
404
    {
 
405
        return InvalidSequenceNr;
 
406
    }
 
407
 
 
408
    tmp.m_data = contents.toUtf8();
 
409
 
 
410
    RetVal rv = parseData(tmp.m_data, tmp.m_dataAsVariables);
 
411
    if (rv != Success)
 
412
    {
 
413
        return rv;
 
414
    }
 
415
 
 
416
    *this = tmp;
 
417
    return Success;
 
418
}
 
419
 
 
420
}
 
421
}