Пример #1
0
XData Util::parseXData(const XmlElement& el)
{
    xmpp_stanza_t* elPtr {el.getStanzaPtr()};
    xmpp_stanza_t* field {xmpp_stanza_get_children(elPtr)};  

    std::string type {makeString(xmpp_stanza_get_type(elPtr))};
     
    XData ret {type};

    while(field)
    {
        if(makeString(xmpp_stanza_get_name(field)) == "field")
        {
            std::string fieldType {makeString(xmpp_stanza_get_type(field))};
            std::string var {makeString(xmpp_stanza_get_attribute(field, "var"))};

            std::vector<std::string> values;

            xmpp_stanza_t* value {xmpp_stanza_get_children(field)};

            while(value)
            {
                if(makeString(xmpp_stanza_get_name(value)) == "value")
                {
                    char* text {xmpp_stanza_get_text(value)};
                    values.emplace_back(makeString(text));
                    xmpp_free(value->ctx, text);
                }

                value = xmpp_stanza_get_next(value);
            }

            XData::Field newField {fieldType, var, values};

            if(not newField.isValid())
            {
                throw std::runtime_error {""};
            }

            ret.addField(newField);
        }

        field = xmpp_stanza_get_next(field);
    }

    return ret;
}
Пример #2
0
void HttpFileUpload::start()
{
    if (d->state != State::None) // Attempt to start twice?
        return;

    setState(State::GettingSlot);

    d->result.statusCode = HttpFileUpload::ErrorCode::NoError;
    static QList<QSet<QString>> featureOptions;
    if (featureOptions.isEmpty()) {
        featureOptions << (QSet<QString>() << xmlns_v0_2_5) << (QSet<QString>() << xmlns_v0_3_1);
    }
    d->client->serverInfoManager()->queryServiceInfo(
                QLatin1String("store"), QLatin1String("file"),
                featureOptions, QRegExp("^(upload|http|stor|file|dis|drive).*"), ServerInfoManager::SQ_CheckAllOnNoMatch,
                [this](const QList<DiscoItem> &items)
    {
        d->httpHosts.clear();
        for (const auto &item: items) {
            const QStringList &l = item.features().list();
            XEP0363::version ver = XEP0363::vUnknown;
            QString xmlns;
            quint64 sizeLimit = 0;
            if (l.contains(xmlns_v0_3_1)) {
                ver = XEP0363::v0_3_1;
                xmlns = xmlns_v0_3_1;
            } else if (l.contains(xmlns_v0_2_5)) {
                ver = XEP0363::v0_2_5;
                xmlns = xmlns_v0_2_5;
            }
            if (ver != XEP0363::vUnknown) {
                QList<std::pair<HttpHost,int>> hosts;
                const XData::Field field = item.registeredExtension(xmlns).getField(QLatin1String("max-file-size"));
                if (field.isValid() && field.type() == XData::Field::Field_TextSingle)
                    sizeLimit = field.value().at(0).toULongLong();
                HttpHost host;
                host.ver = ver;
                host.jid = item.jid();
                host.sizeLimit = sizeLimit;
                QVariant metaProps(d->client->serverInfoManager()->serviceMeta(host.jid, "httpprops"));
                if (metaProps.isValid()) {
                    host.props = HostProps(metaProps.value<int>());
                } else {
                    host.props = SecureGet | SecurePut;
                    if (ver == XEP0363::v0_3_1)
                        host.props |= NewestVer;
                }
                int value = 0;
                if (host.props & SecureGet) value += 5;
                if (host.props & SecurePut) value += 5;
                if (host.props & NewestVer) value += 3;
                if (host.props & Failure) value -= 15;
                if (!sizeLimit || d->fileSize < sizeLimit)
                    hosts.append({host,value});

                // no sorting in preference order. most preferred go first
                std::sort(hosts.begin(), hosts.end(), [](const auto &a, const auto &b){
                    return a.second > b.second;
                });
                for (auto &hp: hosts) {
                    d->httpHosts.append(hp.first);
                }
            }
        }
        //d->currentHost = d->httpHosts.begin();
        if (d->httpHosts.isEmpty()) { // if empty as the last resort check all services
            d->result.statusCode   = HttpFileUpload::ErrorCode::NoUploadService;
            d->result.statusString = "No suitable http upload services were found";
            done(State::Error);
        } else {
            tryNextServer();
        }
    });
}