Пример #1
0
    ~SoapReplier()
    {
        // End of body -- assemble reply
        unsigned int rc = ENOSYS;

        soap::Params result;

        SoapInfo *soap_info = new SoapInfo;
        soap_info->ipe = m_ipe;
        soap_info->access = m_access;
        m_endpoints->reset(soap_info);

        rc = m_service->OnAction(m_action, m_args, &result);

        if (rc)
        {
            m_response->status_line = "HTTP/1.1 801 Error\r\n";

            std::string body(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
                "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\""
                " s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
                " <s:Body>"
                "  <s:Fault><faultcode>soap:Server</faultcode>"
                "  <faultstring>Service error ");
            body += util::SPrintf("%u", rc);
            body += "</faultstring></s:Fault></s:Body></s:Envelope>\r\n";

            LOG(SOAP) << "Soap response is " << body << "\n";

            m_response->body_source.reset(new util::StringStream(body));
        }
        else
        {
            std::string body = soap::CreateBody(m_service->GetData(),
                                                m_action, true,
                                                m_service->GetServiceType(),
                                                result);

            LOG(SOAP) << "Soap response is " << body << "\n";

            m_response->body_source.reset(new util::StringStream(body));
        }
    }
Пример #2
0
bool Server::Impl::StreamForPath(const util::http::Request *rq,
                                 util::http::Response *rs)
{
    LOG(UPNP) << "Got " << rq->verb << " request for " << rq->path << "\n";

    const char *path = rq->path.c_str();
    const char *usn;

    if (rq->path == s_description_path)
    {
        LOG(UPNP) << "Serving description request\n";
        rs->body_source.reset(
            new util::StringStream(Description(rq->local_ep.addr)));
        rs->content_type = "text/xml; charset=\"utf-8\"";
        return true;
    }
    else if (prefixcmp(path, "/upnp/event/", &usn))
    {
        if (rq->verb == "SUBSCRIBE")
        {
            LOG(UPNP) << "I'm being subscribed at\n" << rq->headers;

            Service *service = FindService(usn);
            if (service)
            {
                std::string delivery = rq->GetHeader("callback");
                if (delivery.size() > 2)
                {
                    delivery.erase(0,1);
                    delivery.erase(delivery.size()-1);

                    m_subscriptions.push_back(Subscription(service, delivery));

                    rs->headers["SID"] = delivery; // why not?
                    rs->headers["TIMEOUT"] = "infinite";
                    rs->body_source.reset(new util::StringStream(""));
                }
            }
            else
            {
                TRACE << "Can't find service " << usn << "\n";
            }
            return true;
        }
        else if (rq->verb == "UNSUBSCRIBE")
        {
            LOG(UPNP) << "I'm being unsubscribed at\n" << rq->headers;

            Service *service = FindService(usn);
            if (service)
            {
                std::string delivery = rq->GetHeader("SID");

                for (subscriptions_t::iterator i = m_subscriptions.begin();
                        i != m_subscriptions.end();
                        ++i)
                {
                    if (i->service == service
                            && i->delivery_url == delivery)
                    {
                        m_subscriptions.erase(i);
                        LOG(UPNP) << "Found and erased subscription\n";
                        rs->body_source.reset(new util::StringStream(""));
                        break;
                    }
                }
            }

            return true;
        }
    }
    else if (prefixcmp(path, "/upnp/control/", &usn))
    {
        if (rq->verb == "POST")
        {
            LOG(UPNP) << "I'm being soaped at\n" << rq->headers;
            Service *svc = FindService(usn);
            if (svc)
            {
                std::string action_name = rq->GetHeader("SOAPACTION");
                if (!action_name.empty())
                {
                    action_name.erase(0,action_name.rfind('#')+1);
                    action_name.erase(action_name.rfind('\"'));
                    LOG(UPNP) << "Soap action: " << action_name << "\n";

                    const upnp::Data *data = svc->GetData();
                    unsigned int action = data->actions.Find(action_name.c_str());
                    if (action < data->actions.n)
                    {
                        rs->content_type = "text/xml; charset=\"utf-8\"";
                        rs->body_sink.reset(new SoapReplier(svc, action, rs,
                                                            rq->local_ep,
                                                            rq->access,
                                                            &m_endpoints));
                        return true;
                    }
                    else
                    {
                        LOG(UPNP) << "Action " << action_name << " not found\n";
                    }
                }
            }
            else
            {
                LOG(UPNP) << "Service " << usn << " not found\n";
            }
        }
    }

    return false;
}