Example #1
0
void HttpHeaderContentType::Process(const Brx& aValue)
{
    Parser parser(aValue);
    
    try {
        Brn type = parser.Next(';');
        Parser parser2(type);  // get first word of the type
        iType.Replace(parser2.Next());
        SetReceived();
    }
    catch (BufferOverflow&) {
        return;
    }
    
    Brn key;
    Brn value;
    
    for (;;) {
        key.Set(parser.Next('='));
        if (key.Bytes() == 0) {
            return;
        }
        value.Set(parser.Next());
        Process(key, value);
    }
}
Example #2
0
Brn XmlParserBasic::Element(const Brx& aTag, const Brx& aDocument, Brn& aRemaining)
{
    EParserState state = eSearchOpen;
    TInt ignoreClose = 0;
    Brn namesp;
    Brn name;
    Brn attributes;
    Brn ns;
    TUint index;
    TUint startIndex = 0;
    Brn docTrimmed(Ascii::Trim(aDocument));
    Brn doc(docTrimmed);
    Brn remaining(docTrimmed);
    Brn retStart;
    ETagType tagType;
    for (;;) {
        NextTag(doc, name, attributes, ns, index, remaining, tagType);
        if (Ascii::CaseInsensitiveEquals(name, aTag)) {
            if (state == eSearchOpen) {
                if (tagType == eTagClose) {
                    if (--ignoreClose < 0)
                        THROW(XmlError);
                }
                else if (tagType == eTagOpenClose) {
                    return Brn(Brx::Empty());
                }
                namesp.Set(ns);
                retStart.Set(remaining);
                state = eSearchClose;
            }
            else { // eSearchClose
                if (tagType == eTagOpen) {
                    ++ignoreClose;
                }
                else if (tagType == eTagClose) {
                    if (ignoreClose == 0) {
                        if (namesp != ns) {
                            THROW(XmlError);
                        }
                        aRemaining.Set(remaining);

                        const TUint retBytes = (TUint)(aRemaining.Ptr() - docTrimmed.Ptr()) - startIndex;
                        Brn ret(docTrimmed.Split(startIndex, retBytes));
                        return ret;
                    }
                    ignoreClose--;
                }
            }
        }
        if (remaining.Bytes() == 0) {
            THROW(XmlError);
        }
        if (state != eSearchClose)
        {
            startIndex += (TUint)(remaining.Ptr()-doc.Ptr());
        }
        doc.Set(remaining);
    }
}
Example #3
0
void DviProtocolUpnp::WriteResource(const Brx& aUriTail, TIpAddress aAdapter, std::vector<char*>& aLanguageList, IResourceWriter& aResourceWriter)
{
    if (aUriTail == kDeviceXmlName) {
        Brh xml;
        Brn xmlBuf;
        AutoMutex _(iLock);
        const TInt index = FindListenerForInterface(aAdapter);
        if (index == -1) {
            return;
        }
        if (iDevice.IsRoot()) {
            const Brx& cachedXml = iAdapters[index]->DeviceXml();
            if (cachedXml.Bytes() > 0) {
                xmlBuf.Set(cachedXml);
            }
        }
        if (xmlBuf.Bytes() == 0) {
            GetDeviceXml(xml, aAdapter);
            if (iDevice.IsRoot()) {
                iAdapters[index]->SetDeviceXml(xml);
                xmlBuf.Set(iAdapters[index]->DeviceXml());
            }
            else {
                xmlBuf.Set(xml);
            }
        }
        aResourceWriter.WriteResourceBegin(xmlBuf.Bytes(), kOhNetMimeTypeXml);
        aResourceWriter.WriteResource(xmlBuf.Ptr(), xmlBuf.Bytes());
        aResourceWriter.WriteResourceEnd();
    }
    else {
        Parser parser(aUriTail);
        Brn buf = parser.Next('/');
        Brn rem = parser.Remaining();
        if (buf == DviDevice::kResourceDir) {
            IResourceManager* resMgr = iDevice.ResourceManager();
            if (resMgr != NULL) {
                resMgr->WriteResource(rem, aAdapter, aLanguageList, aResourceWriter);
            }
        }
        else if (rem == kServiceXmlName) {
            iLock.Wait();
            DviService* service = 0;
            const TUint count = iDevice.ServiceCount();
            for (TUint i=0; i<count; i++) {
                DviService& s = iDevice.Service(i);
                if (s.ServiceType().PathUpnp() == buf) {
                    service = &s;
                    break;
                }
            }
            iLock.Signal();
            if (service == 0) {
                THROW(ReaderError);
            }
            DviProtocolUpnpServiceXmlWriter::Write(*service, *this, aResourceWriter);
        }
    }
}
Example #4
0
void DeviceBasic::WriteResource(const Brx& aUriTail, TIpAddress /*aInterface*/, std::vector<char*>& /*aLanguageList*/, IResourceWriter& aResourceWriter)
{
    const Brn kIndexFile("index.html");
    Bwh filePath(iConfigDir);
    Brn file;
    if (aUriTail.Bytes() == 0) {
        file.Set(kIndexFile);
    }
    else {
        file.Set(aUriTail);
    }
    const TByte sep =
#ifdef _WIN32
                      '\\';
#else
                      '/';
#endif
    filePath.Grow(filePath.Bytes() + 1 + file.Bytes()+1);
    filePath.Append(sep);
    filePath.Append(file);
    filePath.PtrZ();

    const char* path = (const char*)filePath.Ptr();
    FILE* fd = fopen(path, "rb");
    if (fd == NULL) {
        return;
    }
    static const TUint kMaxReadSize = 4096;
    struct stat fileStats;
    (void)stat(path, &fileStats);
    TUint bytes = (TUint)fileStats.st_size;
    const char* mime = NULL;
    for (TUint i=filePath.Bytes()-1; i>0; i--) {
        if (filePath[i] == '/' || filePath[i] == '\\') {
            break;
        }    
        if (filePath[i] == '.') {
            const char* ext = (const char*)filePath.Split(i+1, filePath.Bytes()-i-1).Ptr();
            if (strcmp(ext, "html") == 0 || strcmp(ext, "htm") == 0) {
                mime = kOhNetMimeTypeHtml;
            }
            break;
        }
    }
    aResourceWriter.WriteResourceBegin(bytes, mime);
    do {
        TByte buf[kMaxReadSize];
        TUint size = (bytes<kMaxReadSize? bytes : kMaxReadSize);
        size_t records_read = fread(buf, size, 1, fd);
        ASSERT(records_read == 1);
        aResourceWriter.WriteResource(buf, size);
        bytes -= size;
    } while (bytes > 0);
    aResourceWriter.WriteResourceEnd();
    (void)fclose(fd);
}
Example #5
0
Brn ReaderText::ReadLine()
{
    Brn line;
    try {
        line.Set(Ascii::Trim(ReadUntil(Ascii::kLf)));
    }
    catch (ReaderError&) {
        // treat any content following the last newline as a final line
        line.Set(Read(iMaxBytes));
        if (line.Bytes() == 0) {
            throw;
        }
    }
    return line;
}
Example #6
0
void HeaderAcceptLanguage::Process(const Brx& aValue)
{
    SetReceived();
    ClearLanguageList();
    iLanguages.Set(aValue);

    std::vector<PrioritisedLanguage> prioritisedList;
    Parser parser(iLanguages);
    while (parser.Remaining().Bytes() > 0) {
        Brn langBuf = parser.Next(',');
        Parser parser2(langBuf);
        Brn lang = parser2.Next(';');
        parser2.Set(parser2.Remaining());
        Brn qualityBuf = parser2.Next('=');
        if (qualityBuf.Bytes() > 0) {
            qualityBuf.Set(parser2.Remaining());
        }
        TUint quality = ParseQualityValue(qualityBuf);
        PrioritisedLanguage prioritisedLang;
        prioritisedLang.iLanguage = (char*)malloc(lang.Bytes()+1);
        (void)memcpy(prioritisedLang.iLanguage, lang.Ptr(), lang.Bytes());
        prioritisedLang.iLanguage[lang.Bytes()] = '\0';
        prioritisedLang.iPriority = quality;
        AddPrioritisedLanguage(prioritisedList, prioritisedLang);
    }

    for (TUint i=0; i<(TUint)prioritisedList.size(); i++) {
        iLanguageList.push_back(prioritisedList[i].iLanguage);
    }
}
Example #7
0
TBool Ssdp::ParseUrn(const Brx& aUrn, const Brx& aType, Brn& aDomainName, Brn& aDeviceType, TUint& aVer)
{
    Parser parser(aUrn);
    aDomainName.Set(parser.NextNoTrim(kUrnSeparator));
    if (!aType.Equals(parser.NextNoTrim(kUrnSeparator))) {
        return false;
    }
    aDeviceType.Set(parser.NextNoTrim(kUrnSeparator));
    Brn ver = parser.Remaining();
    try {
        aVer = Ascii::Uint(ver);
    }
    catch(AsciiError&) {
        return false;
    }
    return true;
}
Example #8
0
TBool DviServerUpnp::RedirectUri(const Brx& aUri, Brn& aRedirectTo)
{
    if (aUri == iRedirectUriRequested) {
        aRedirectTo.Set(iRedirectUriRedirectedTo);
        return true;
    }
    return false;
}
Example #9
0
Brn ReaderText::ReadLine(TUint& aBytesConsumed)
{
    Brn line;
    try {
        Brn buf = ReadUntil(Ascii::kLf);
        aBytesConsumed = buf.Bytes() + 1; // +1 for Ascii::kLf
        line.Set(Ascii::Trim(buf));
    }
    catch (ReaderError&) {
        // treat any content following the last newline as a final line
        Brn buf = Read(iMaxBytes);
        aBytesConsumed = buf.Bytes() + 1; // +1 for Ascii::kLf
        line.Set(Ascii::Trim(buf));
        if (line.Bytes() == 0) {
            throw;
        }
    }
    return line;
}
Example #10
0
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType)
{
    Brn root = XmlParserBasic::Find("root", iXml);
    Brn device = XmlParserBasic::Find("device", root);
    Brn udn = XmlParserBasic::Find("UDN", device);
    if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) {
        Brn deviceList = XmlParserBasic::Find("deviceList", device);
        do {
            Brn remaining;
            device.Set(XmlParserBasic::Find("device", deviceList, remaining));
            udn.Set(XmlParserBasic::Find("UDN", device));
            deviceList.Set(remaining);
        } while (!CpiDeviceUpnp::UdnMatches(udn, Udn()));
    }
    Brn serviceList = XmlParserBasic::Find("serviceList", device);
    Brn service;
    Brn serviceType;
    Brn devServiceTypeNoVer;
    const Brx& targServiceType = aServiceType.FullName();
    // Must have backwards compatibility. Need to compare service type and version separately.
    Parser serviceParser = targServiceType;
    serviceParser.Next(':');    // urn
    serviceParser.Next(':');    // schema url
    serviceParser.Next(':');    // service
    serviceParser.Next(':');    // name
    Brn targServiceTypeNoVer(targServiceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version)
    do {
        Brn remaining;
        service.Set(XmlParserBasic::Find("service", serviceList, remaining));
        serviceType.Set(XmlParserBasic::Find("serviceType", service));
        serviceList.Set(remaining);
        // Parse service type and version separately.
        serviceParser.Set(serviceType);
        serviceParser.Next(':');    // urn
        serviceParser.Next(':');    // schema url
        serviceParser.Next(':');    // service
        serviceParser.Next(':');    // name
        devServiceTypeNoVer.Set(serviceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version)
        // MUST allow use of device with version >= target version
    } while (devServiceTypeNoVer != targServiceTypeNoVer);
    Brn path = XmlParserBasic::Find(aType, service);
    if (path.Bytes() == 0) {
        // no event url => service doesn't have any evented state variables
        THROW(XmlError);
    }

    // now create a uri using the scheme/host/port of the device xml location
    // plus the path we've just constructed
    Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx
    aUri.Replace(iLocation);
    base.Append(aUri.Scheme());
    base.Append("://");
    base.Append(aUri.Host());
    base.Append(':');
    Ascii::AppendDec(base, aUri.Port());
    aUri.Replace(base, path);
}
Example #11
0
TUint CpiDeviceUpnp::Version(const TChar* aDomain, const TChar* aName, TUint /*aProxyVersion*/) const
{
    ServiceType serviceType(iDevice->GetCpStack().Env(), aDomain, aName, 0);
    const Brx& targServiceType = serviceType.FullName();
    // Must have backwards compatibility. Need to compare service type and version separately.
    Parser serviceParser = targServiceType;
    serviceParser.Next(':');    // urn
    serviceParser.Next(':');    // schema url
    serviceParser.Next(':');    // service
    serviceParser.Next(':');    // name
    Brn targServiceTypeNoVer(targServiceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version)

    try {
        Brn root = XmlParserBasic::Find("root", iXml);
        Brn device = XmlParserBasic::Find("device", root);
        Brn udn = XmlParserBasic::Find("UDN", device);
        if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) {
            Brn deviceList = XmlParserBasic::Find("deviceList", device);
            do {
                Brn remaining;
                device.Set(XmlParserBasic::Find("device", deviceList, remaining));
                udn.Set(XmlParserBasic::Find("UDN", device));
                deviceList.Set(remaining);
            } while (!CpiDeviceUpnp::UdnMatches(udn, Udn()));
        }
        Brn serviceList = XmlParserBasic::Find("serviceList", device);
        Brn service;
        Brn serviceType;
        Brn devServiceTypeNoVer;
        for (;;) {
            Brn remaining;
            service.Set(XmlParserBasic::Find("service", serviceList, remaining));
            serviceType.Set(XmlParserBasic::Find("serviceType", service));
            serviceList.Set(remaining);
            // Parse service type and version separately.
            serviceParser.Set(serviceType);
            serviceParser.Next(':');    // urn
            serviceParser.Next(':');    // schema url
            serviceParser.Next(':');    // service
            serviceParser.Next(':');    // name
            devServiceTypeNoVer.Set(serviceType.Ptr(), serviceParser.Index()); // full name minus ":x" (where x is version)
            if (devServiceTypeNoVer == targServiceTypeNoVer) {
                Brn devVersionBuf = serviceParser.NextToEnd();    // version
                try {
                    return Ascii::Uint(devVersionBuf);
                }
                catch (AsciiError&) {
                    THROW(XmlError);
                }
            }
        }
    }
    catch (XmlError&) {
        return 0;
    }
}
Example #12
0
void WsProtocol76::Read(Brn& aData, TBool& aClosed)
{
    aData.Set(NULL, 0);
    aClosed = false;

    Brn data = iReadBuffer.ReadUntil(kMsgEnd);
    if (data.Bytes() == 1 && data[0] == kFrameCloseStart) {
        Brn msg = iReadBuffer.Read(1);
        if (msg[0] != kMsgCloseEnd) {
            THROW(WebSocketError);
        }
        LOG(kDvWebSocket, "WS: Received close cmd from browser\n");
        Close();
        aClosed = true;
        return;
    }
    if (data[0] != kFrameMsgStart) {
        LOG2(kDvWebSocket, kError, "WS: Unexpected leading byte - %u\n", data[0]);
        THROW(WebSocketError);
    }
    aData.Set(data.Split(1, data.Bytes()-1));
}
Example #13
0
TBool CpiDeviceUpnp::GetAttribute(const char* aKey, Brh& aValue) const
{
    Brn key(aKey);
    
    Parser parser(key);
    
    if (parser.Next('.') == Brn("Upnp")) {
        Brn property = parser.Remaining();

        if (property == Brn("Location")) {
            aValue.Set(iLocation);
            return (true);
        }
        if (property == Brn("DeviceXml")) {
            aValue.Set(iXml);
            return (true);
        }

        const DeviceXml* device = iDeviceXml;
        
        if (parser.Next('.') == Brn("Root")) {
            device = &iDeviceXmlDocument->Root();
            property.Set(parser.Remaining());
        }
        
        try {
            if (property == Brn("FriendlyName")) {
                device->GetFriendlyName(aValue);
                return (true);
            }
            if (property == Brn("PresentationUrl")) {
                device->GetPresentationUrl(aValue);
                return (true);
            }
            
            Parser parser(property);
            
            Brn token = parser.Next('.');
            
            if (token == Brn("Service")) {
                aValue.Set(device->ServiceVersion(parser.Remaining()));
                return (true);
            }
        }
        catch (XmlError&) {
        }
    }

    return (false);
}
Example #14
0
void ReaderHttpRequest::Read(TUint aTimeoutMs)
{
    TUint count = 0;
    iMethod = 0;
    ResetHeaders();

    for (;;) {
        Brn line;
        {
            Timer timer(MakeFunctor(*this, &ReaderHttpRequest::ReadTimeout));
            if (aTimeoutMs > 0) {
                timer.FireIn(aTimeoutMs);
            }
            line.Set(Ascii::Trim(iReader.ReadUntil(Ascii::kLf)));
            timer.Cancel();
        }
//        LOG(kHttp, "HTTP Read Request   ");
//        LOG(kHttp, line);
//        LOG(kHttp, "\n");
        TUint bytes = line.Bytes();
        if (!bytes) {
            if (count == 0) {
                continue; // a blank line before first header - ignore (RFC 2616 section 4.1)
            }
            if (iMethod == 0) {
                THROW(HttpError);
            }
            return;
        }

        if (Ascii::IsWhitespace(line[0])) {
            continue; // a line starting with spaces is a continuation line
        }
    
        Parser parser(line);

        if (count == 0) { // method
            Brn method = parser.Next();
            Brn uri = parser.Next();
            Brn version = Ascii::Trim(parser.Remaining());
            ProcessMethod(method, uri, version);
        }
        else { // header
            Brn field = parser.Next(':');
            Brn value = Ascii::Trim(parser.Remaining());
            ProcessHeader(field, value);
        }
        count++;
    }
}
Example #15
0
void EventSessionUpnp::ProcessNotification(IEventProcessor& aEventProcessor, const Brx& aEntity)
{
    aEventProcessor.EventUpdateStart();
    OutputProcessorUpnp outputProcessor;
    Brn propertySet = XmlParserBasic::Find("propertyset", aEntity);
    Brn prop;
    Brn remaining;
    try {
        for (;;) {
            prop.Set(XmlParserBasic::Find("property", propertySet, remaining));
            prop.Set(Ascii::Trim(prop));
            if (prop.Bytes() < 8 || prop[0] != '<' || prop[1] == '/') {
                THROW(XmlError);
            }
            Parser parser(prop);
            (void)parser.Next('<');
            Brn tagName = parser.Next('>');
            Brn val = parser.Next('<');
            Brn closingTag = parser.Next('/');
            closingTag.Set(parser.Next('>'));
            if (tagName != closingTag) {
                THROW(XmlError);
            }

            try {
                aEventProcessor.EventUpdate(tagName, val, outputProcessor);
            }
            catch(AsciiError&) {
                THROW(XmlError);
            }

            propertySet.Set(remaining);
        }
    }
    catch(XmlError&) {}
    aEventProcessor.EventUpdateEnd();
}
Example #16
0
void ReaderHttpResponse::Read(TUint aTimeoutMs)
{   
    iReader.ReadFlush();
    ResetHeaders();
    TUint count = 0;
    for (;;) {
        Brn line;
        {
            Timer timer(MakeFunctor(*this, &ReaderHttpResponse::ReadTimeout));
            if (aTimeoutMs > 0) {
                timer.FireIn(aTimeoutMs);
            }
            line.Set(Ascii::Trim(iReader.ReadUntil(Ascii::kLf)));
            timer.Cancel();
        }
        LOG(kHttp, "HTTP Read Response  ");
        LOG(kHttp, line);
        LOG(kHttp, "\n");
        TUint bytes = line.Bytes();
        if (!bytes) {
            if (count == 0) {
                continue; // a blank line before first header - ignore (RFC 2616 section 4.1)
            }
            return;
        }

        if (Ascii::IsWhitespace(line[0])) {
            continue; // a line starting with spaces is a continuation line
        }

        Parser parser(line);

        if (count == 0) { // status
 //            LOG(kHttp, " status   ");
            Brn version = parser.Next(' ');
            Brn code = parser.Next(' ');
            Brn description = Ascii::Trim(parser.Remaining());
            ProcessStatus(version, code, description);
        }
        else { // header
//            LOG(kHttp, " header  ");
            Brn field = parser.Next(':');
            Brn value = Ascii::Trim(parser.Remaining());
            ProcessHeader(field, value);
        }
        count++;
    }
}
Example #17
0
void ShellSession::Run()
{
    FunctorMsg logger = MakeFunctorMsg(*this, &OpenHome::Net::ShellSession::Log);
    FunctorMsg oldLogger = Log::SwapOutput(logger);
    iShutdownSem.Wait();
    for (;;) {
        try {
            Brn buf = iReadBuffer->ReadUntil('\n');
            TUint bytes = buf.Bytes();
            if (bytes > 0 && buf[bytes - 1] == '\r') { // strip any trailing LF
                buf.Set(buf.Ptr(), bytes-1);
            }
            Parser parser(buf);
            Brn command = parser.Next(' ');
            if (command == kCmdExit) {
                break;
            }
            std::vector<Brn> args;
            for (;;) {
                Brn arg = parser.Next(' ');
                if (arg.Bytes() == 0) {
                    break;
                }
                args.push_back(arg);
            }
            iCommandHandler.HandleShellCommand(command, args, *iWriterResponse);
        }
        catch (ReaderError&) {
            break;
        }
        catch (WriterError&) {
            break;
        }
        catch (Exception& e) {
            Log::Print("Unexpected exception: %s from %s:%u\n", e.Message(), e.File(), e.Line());
            break;
        }
    }
    (void)Log::SwapOutput(oldLogger);
    iShutdownSem.Signal();
}
Example #18
0
void WsProtocol80::Read(Brn& aData, TBool& aClosed)
{
    aData.Set(NULL, 0);
    aClosed = false;

    static const TByte kBitMaskFinalFragment = 1<<7;
    static const TByte kBitMaskRsv123        = 0x70;
    static const TByte kBitMaskOpcode        = 0xf;
    static const TByte kBitMaskPayloadMask   = 1<<7;
    static const TByte kBitMaskPayloadLen    = 0x7f;

    // validate framing
    Bws<2> ctrl;
    ctrl.Append(iReadBuffer.Read(2));
    const TByte& byte0 = ctrl.At(0);
    const TByte& byte1 = ctrl.At(1);
    const TBool fragment = ((byte0 & kBitMaskFinalFragment) == 0);
    if (byte0 & kBitMaskRsv123) {
        LOG2(kDvWebSocket, kError, "WS: RSV bit(s) set - %u - but no extension negotiated\n", (byte0 & kBitMaskRsv123) >> 4);
        Close(kCloseProtocolError);
        aClosed = true;
        return;
    }
Example #19
0
void CpiDeviceUpnp::GetServiceUri(Uri& aUri, const TChar* aType, const ServiceType& aServiceType)
{
    Brn root = XmlParserBasic::Find("root", iXml);
    Brn device = XmlParserBasic::Find("device", root);
    Brn udn = XmlParserBasic::Find("UDN", device);
    if (!CpiDeviceUpnp::UdnMatches(udn, Udn())) {
        Brn deviceList = XmlParserBasic::Find("deviceList", device);
        do {
            Brn remaining;
            device.Set(XmlParserBasic::Find("device", deviceList, remaining));
            udn.Set(XmlParserBasic::Find("UDN", device));
            deviceList.Set(remaining);
        } while (!CpiDeviceUpnp::UdnMatches(udn, Udn()));
    }
    Brn serviceList = XmlParserBasic::Find("serviceList", device);
    Brn service;
    Brn serviceType;
    const Brx& targServiceType = aServiceType.FullName();
    do {
        Brn remaining;
        service.Set(XmlParserBasic::Find("service", serviceList, remaining));
        serviceType.Set(XmlParserBasic::Find("serviceType", service));
        serviceList.Set(remaining);
    } while (serviceType != targServiceType);
    Brn path = XmlParserBasic::Find(aType, service);
    if (path.Bytes() == 0) {
        // no event url => service doesn't have any evented state variables
        THROW(XmlError);
    }

    // now create a uri using the scheme/host/port of the device xml location
    // plus the path we've just constructed
    Bws<40> base; // just need space for http://xxx.xxx.xxx.xxx:xxxxx
    aUri.Replace(iLocation);
    base.Append(aUri.Scheme());
    base.Append("://");
    base.Append(aUri.Host());
    base.Append(':');
    Ascii::AppendDec(base, aUri.Port());
    aUri.Replace(base, path);
}
Example #20
0
void EventSessionUpnp::ProcessNotification(IEventProcessor& aEventProcessor, const Brx& aEntity)
{
    aEventProcessor.EventUpdateStart();
    OutputProcessorUpnp outputProcessor;
    Brn propertySet = XmlParserBasic::Find("propertyset", aEntity);
    Brn prop;
    Brn remaining;
    try {
        for (;;) {
            try {
                prop.Set(XmlParserBasic::Find("property", propertySet, remaining));
            }
            catch (XmlError&) {
                // we've successfully processed all <property> tags from aEntity
                break;
            }
            prop.Set(Ascii::Trim(prop));
            if (prop.Bytes() < 8 || prop[0] != '<' || prop[1] == '/') {
                THROW(XmlError);
            }
            Parser parser(prop);
            (void)parser.Next('<');
            Brn tagNameFull = parser.Next('>');
            Brn tagName = tagNameFull;
            TUint bytes = tagNameFull.Bytes();
            TUint i;
            for (i = 0; i < bytes; i++) {
                if (Ascii::IsWhitespace(tagNameFull[i])) {
                    break;
                }
            }
            if (i < bytes) {
                tagName.Set(tagNameFull.Split(0, i));
            }
            Brn val;
            if (bytes > 0 && tagNameFull[bytes-1] == '/') {
                // empty element tag
                val.Set(Brx::Empty());
                if (i == bytes) { // no white space before '/'
                    tagName.Set(tagName.Split(0, bytes-1));
                }
            }
            else {
                val.Set(parser.Next('<'));
                Brn closingTag = parser.Next('/');
                closingTag.Set(parser.Next('>'));
                if (tagName != closingTag) {
                    THROW(XmlError);
                }
            }

            try {
                aEventProcessor.EventUpdate(tagName, val, outputProcessor);
            }
            catch(AsciiError&) {
                THROW(XmlError);
            }

            propertySet.Set(remaining);
        }
        aEventProcessor.EventUpdateEnd();
    }
    catch(XmlError&) {
        aEventProcessor.EventUpdateError();
    }
}
Example #21
0
void XmlParserBasic::NextTag(const Brx& aDocument, Brn& aName, Brn& aAttributes, Brn& aNamespace, TUint& aIndex, Brn& aRemaining, ETagType& aType)
{
    aName.Set(Brx::Empty());
    aAttributes.Set(Brx::Empty());
    aNamespace.Set(Brx::Empty());
    aRemaining.Set(Brx::Empty());
    Parser parser(aDocument);
    for (;;) {
        Brn item = parser.Next('>');
        TUint bytes = item.Bytes();
        if (bytes > 0 && item[0] != '<') {
            Parser valueParser(item);
            Brn value = valueParser.Next('<');
            bytes -= value.Bytes();
            item.Set(item.Split(value.Bytes(), bytes));
            item.Set(Ascii::Trim(item));
            bytes = item.Bytes();
        }
        if (bytes < 2 || item[0] != '<') {
            THROW(XmlError);
        }
        aIndex = (TUint)(item.Ptr() - aDocument.Ptr());
        if (item[1] == '?') {
            if (bytes < 3) { // catch special case of <?>
                THROW(XmlError);
            }
            if (item[bytes - 1] == '?') { // processing instruction
                continue;
            }
            THROW(XmlError);
        }

        aRemaining.Set(parser.Remaining());

        TUint start = 1; // skip opening '<'
        TUint len = bytes-1;
        if (item[1] == '/') {
            aType = eTagClose;
            start++;
            len--;
        }
        else if (item[bytes-1] == '/') {
            aType = eTagOpenClose;
            len--;
        }
        else {
            aType = eTagOpen;
        }

        parser.Set(item.Split(start, len));
        aName.Set(parser.NextWhiteSpace());
        aAttributes.Set(parser.Remaining());

        if (Ascii::Contains(aName, ':')) { // collect the namespace
            parser.Set(aName);
            aNamespace.Set(parser.Next(':'));
            if (!aNamespace.Bytes()) {
                THROW(XmlError);
            }
            aName.Set(parser.Remaining());
        }
        else {
            aNamespace.Set(Brx::Empty());
        }

        if (!aName.Bytes()) {
            THROW(XmlError);
        }

        return;
    }
}
Example #22
0
void ProviderPlaylist::ReadList(Net::IDvInvocation& aResponse, const Brx& aIdList, Net::IDvInvocationResponseString& aTrackList)
{
    Log::Print("ProviderPlaylist::ReadList\n");
    uint32_t tracksMax;
    GetPropertyTracksMax(tracksMax);
    vector<uint32_t> v;
    v.reserve(tracksMax);

    try {
        Parser parser(aIdList);
        Brn id;
        id.Set(parser.Next(' '));

        for( ; id != Brx::Empty(); id.Set(parser.Next(' ')) ) {
            v.push_back(Ascii::Uint(id));
            if(v.size() > tracksMax) {
                THROW(AsciiError);
            }
        }
    }
    catch(AsciiError) {
        aResponse.Error(kInvalidRequest, kInvalidRequestMsg);
    }

    Brn entryStart("<Entry>");
    Brn entryEnd("</Entry>");
    Brn idStart("<Id>");
    Brn idEnd("</Id>");
    Brn uriStart("<Uri>");
    Brn uriEnd("</Uri>");
    Brn metaStart("<Metadata>");
    Brn metaEnd("</Metadata>");

    aResponse.StartResponse();
    aTrackList.Write(Brn("<TrackList>"));

    for( vector<uint32_t>::const_iterator id=v.begin(); id!= v.end(); id++) {

        const Track* track = 0;

        iMutex.Wait();
        list<Track*>::const_iterator i = find_if(iList.begin(), iList.end(), bind2nd(mem_fun(&Track::IsId),*id));
        if(i != iList.end()) {
            track = *i;
            track->IncRef();
        }   
        iMutex.Signal();

        if(track) {
            aTrackList.Write(entryStart);

            aTrackList.Write(idStart);
            Ascii::StreamWriteUint(aTrackList, *id);
            aTrackList.Write(idEnd);

            aTrackList.Write(uriStart);
            Converter::ToXmlEscaped(aTrackList, track->Uri());
            aTrackList.Write(uriEnd);

            aTrackList.Write(metaStart);
            Converter::ToXmlEscaped(aTrackList, track->Metadata());
            aTrackList.Write(metaEnd);

            aTrackList.Write(entryEnd);

            track->DecRef();
        }
    }

    aTrackList.Write(Brn("</TrackList>"));
    aTrackList.WriteFlush();
    aResponse.EndResponse();
}
Example #23
0
void CpiDeviceLpec::LpecThread()
{
    try {
        iSocket.Open(iCpStack.Env());
        iSocket.Connect(iLocation, iCpStack.Env().InitParams()->TcpConnectTimeoutMs());
        TBool starting = true;
        for (;;) {
            Brn line = iReadBuffer->ReadUntil(Ascii::kLf);
            if (line.Bytes() > 0 && line[line.Bytes()-1] == Ascii::kCr) {
                line.Set(line.Ptr(), line.Bytes()-1);
            }
            Parser parser(line);
            Brn method = parser.Next(' ');
            if (starting) {
                if (method != Lpec::kMethodAlive) {
                    LOG2(kLpec, kError, "LPEC: unable to find device ");
                    LOG2(kLpec, kError, iLpecName);
                    LOG2(kLpec, kError, ", exiting thread\n");
                    if (iStateChanged) {
                        iStateChanged();
                    }
                    THROW(ReaderError);
                }
                Brn name = parser.Next(' ');
                if (name == iLpecName) {
                    starting = false;
                    Brn udn = parser.Remaining();
                    iDevice = new CpiDevice(iCpStack, udn, *this, *this, NULL);
                    iConnected = true;
                    if (iStateChanged) {
                        iStateChanged();
                    }
                }
            }
            if (method == Lpec::kMethodAlive) {
                LOG(kLpec, "LPEC: Alive - ");
                LOG(kLpec, parser.Remaining());
                LOG(kLpec, "\n");
            }
            else if (method == Lpec::kMethodByeBye) {
                Brn name = parser.Next(' ');
                if (name == iLpecName) {
                    iConnected = false;
                    {
                        if (iStateChanged) {
                            iStateChanged();
                        }
                    }
                    iExiting = true;
                    THROW(ReaderError);
                }
            }
            else if (method == Lpec::kMethodEvent) {
                HandleEventedUpdate(parser.Remaining());
            }
            else if (iResponseHandler == NULL || !iResponseHandler->HandleLpecResponse(method, parser.Remaining())) {
                LOG2(kLpec, kError, "Unexpected LPEC message: ");
                LOG2(kLpec, kError, line);
                LOG2(kLpec, kError, "\n");
            }
        }
    }
    catch (NetworkError&) {
        LogError("NetworkError");
    }
    catch (NetworkTimeout&) {
        LogError("NetworkTimeout");
    }
    catch (WriterError&) {
        LogError("WriterError");
    }
    catch (ReaderError&) {
        if (!iExiting) {
            LogError("ReaderError");
        }
    }
}