示例#1
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnAlbumArtRequest
+---------------------------------------------------------------------*/
NPT_Result 
PLT_FileMediaServer::OnAlbumArtRequest(NPT_HttpResponse& response,
                                       NPT_String        file_path)
{
    NPT_LargeSize            total_len;
    NPT_File                 file(file_path);
    NPT_InputStreamReference stream;

    // prevent hackers from accessing files outside of our root
    if ((file_path.Find("/..") >= 0) || (file_path.Find("\\..") >= 0)) {
        return NPT_FAILURE;
    }

    if (NPT_FAILED(file.Open(NPT_FILE_OPEN_MODE_READ)) || 
        NPT_FAILED(file.GetInputStream(stream))        || 
        NPT_FAILED(stream->GetSize(total_len)) || (total_len == 0)) {
        goto filenotfound;
    } else {
        NPT_String extension = NPT_FilePath::FileExtension(file_path);
        if (extension.GetLength() == 0) {
            goto filenotfound;
        }

        PLT_MetadataHandler* metadataHandler = NULL;
        char* caData;
        int   caDataLen;
        NPT_Result ret = NPT_ContainerFind(m_MetadataHandlers, 
                                           PLT_MetadataHandlerFinder(extension), 
                                           metadataHandler);
        if (NPT_FAILED(ret) || metadataHandler == NULL) {
            goto filenotfound;
        }
        // load the metadatahandler and read the cover art
        if (NPT_FAILED(metadataHandler->Load(*stream)) || 
            NPT_FAILED(metadataHandler->GetCoverArtData(caData, caDataLen))) {
            goto filenotfound;
        }
        
        PLT_HttpHelper::SetContentType(response, "application/octet-stream");
        PLT_HttpHelper::SetBody(response, caData, caDataLen);
        delete caData;
        return NPT_SUCCESS;
    }

filenotfound:
    response.SetStatus(404, "File Not Found");
    return NPT_SUCCESS;
}
示例#2
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::OnAlbumArtRequest
+---------------------------------------------------------------------*/
NPT_Result 
PLT_FileMediaServer::OnAlbumArtRequest(NPT_String filepath, NPT_HttpResponse& response)
{
    NPT_Size total_len;
    NPT_File file(filepath);
    NPT_InputStreamReference stream;

    if (NPT_FAILED(file.Open(NPT_FILE_OPEN_MODE_READ)) || NPT_FAILED(file.GetInputStream(stream)) || 
        NPT_FAILED(stream->GetSize(total_len)) || (total_len == 0)) {
        goto filenotfound;
    } else {
        const char* extension = PLT_MediaItem::GetExtFromFilePath(filepath, m_DirDelimiter);
        if (extension == NULL) {
            goto filenotfound;
        }

        PLT_MetadataHandler* metadataHandler = NULL;
        char* caData;
        int   caDataLen;
        NPT_Result ret = NPT_ContainerFind(m_MetadataHandlers, PLT_MetadataHandlerFinder(extension), metadataHandler);
        if (NPT_FAILED(ret) || metadataHandler == NULL) {
            goto filenotfound;
        }
        // load the metadatahandler and read the cover art
        if (NPT_FAILED(metadataHandler->Load(*stream)) || NPT_FAILED(metadataHandler->GetCoverArtData(caData, caDataLen))) {
            goto filenotfound;
        }
        PLT_HttpHelper::SetContentType(&response, "application/octet-stream");
        PLT_HttpHelper::SetBody(&response, caData, caDataLen);
        delete caData;
        return NPT_SUCCESS;
    }

filenotfound:
    response.SetStatus(404, "File Not Found");
    return NPT_SUCCESS;
}
示例#3
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::BuildFromFilePath
+---------------------------------------------------------------------*/
PLT_MediaObject*
PLT_FileMediaServer::BuildFromFilePath(const NPT_String&        filepath, 
                                       bool                     with_count /* = true */,
                                       const NPT_SocketAddress* req_local_address /* = NULL */,
                                       bool                     keep_extension_in_title /* = false */)
{
    NPT_String            root = m_Path;
    PLT_MediaItemResource resource;
    PLT_MediaObject*      object = NULL;

    /* retrieve the entry type (directory or file) */
    NPT_FileInfo info; 
    NPT_CHECK_LABEL_FATAL(NPT_File::GetInfo(filepath, &info), failure);

    if (info.m_Type == NPT_FileInfo::FILE_TYPE_REGULAR) {
        object = new PLT_MediaItem();

        /* Set the title using the filename for now */
        object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
        if (object->m_Title.GetLength() == 0) goto failure;

        /* Set the protocol Info from the extension */
        resource.m_ProtocolInfo = PLT_MediaItem::GetProtInfoFromExt(NPT_FilePath::FileExtension(filepath));
        if (resource.m_ProtocolInfo.GetLength() == 0)  goto failure;

        /* Set the resource file size */
        resource.m_Size = info.m_Size;
 
        /* format the resource URI */
        NPT_String url = filepath.SubString(root.GetLength()+1);

        // get list of ip addresses
        NPT_List<NPT_String> ips;
        NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);

        // if we're passed an interface where we received the request from
        // move the ip to the top
        if (req_local_address && req_local_address->GetIpAddress().ToString() != "0.0.0.0") {
            ips.Remove(req_local_address->GetIpAddress().ToString());
            ips.Insert(ips.GetFirstItem(), req_local_address->GetIpAddress().ToString());
        }

        // iterate through list and build list of resources
        NPT_List<NPT_String>::Iterator ip = ips.GetFirstItem();
        while (ip) {
            /* prepend the base URI and url encode it */ 
            //resource.m_Uri = NPT_Uri::Encode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
            resource.m_Uri = BuildResourceUri(m_FileBaseUri, *ip, url);

            /* Look to see if a metadatahandler exists for this extension */
            PLT_MetadataHandler* handler = NULL;
            NPT_Result res = NPT_ContainerFind(
                m_MetadataHandlers, 
                PLT_MetadataHandlerFinder(NPT_FilePath::FileExtension(filepath)), 
                handler);
            if (NPT_SUCCEEDED(res) && handler) {
                /* if it failed loading data, reset the metadatahandler so we don't use it */
                if (NPT_SUCCEEDED(handler->LoadFile(filepath))) {
                    /* replace the title with the one from the Metadata */
                    NPT_String newTitle;
                    if (handler->GetTitle(newTitle) != NULL) {
                        object->m_Title = newTitle;
                    }

                    /* assign description */
                    handler->GetDescription(object->m_Description.long_description);

                    /* assign album art uri if we haven't yet */
                    /* prepend the album art base URI and url encode it */ 
                    if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) {
                        object->m_ExtraInfo.album_art_uri = 
                            NPT_Uri::PercentEncode(BuildResourceUri(m_AlbumArtBaseUri, *ip, url), 
                                                   NPT_Uri::UnsafeCharsToEncode);
                    }

                    /* duration */
                    handler->GetDuration(resource.m_Duration);

                    /* protection */
                    handler->GetProtection(resource.m_Protection);
                }
            }

            object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClassFromExt(NPT_FilePath::FileExtension(filepath));
            object->m_Resources.Add(resource);

            ++ip;
        }
    } else {
        object = new PLT_MediaContainer;

        /* Assign a title for this container */
        if (filepath.Compare(root, true) == 0) {
            object->m_Title = "Root";
        } else {
            object->m_Title = NPT_FilePath::BaseName(filepath, keep_extension_in_title);
            if (object->m_Title.GetLength() == 0) goto failure;
        }

        /* Get the number of children for this container */
        NPT_Cardinal count = 0;
        if (with_count && NPT_SUCCEEDED(NPT_File::GetCount(filepath, count))) {
            ((PLT_MediaContainer*)object)->m_ChildrenCount = count;
        }

        object->m_ObjectClass.type = "object.container";
    }

    /* is it the root? */
    if (filepath.Compare(root, true) == 0) {
        object->m_ParentID = "-1";
        object->m_ObjectID = "0";
    } else {
        NPT_String directory = NPT_FilePath::DirectoryName(filepath);
        /* is the parent path the root? */
        if (directory.GetLength() == root.GetLength()) {
            object->m_ParentID = "0";
        } else {
            object->m_ParentID = "0" + filepath.SubString(root.GetLength(), directory.GetLength() - root.GetLength());
        }
        object->m_ObjectID = "0" + filepath.SubString(root.GetLength());
    }

    return object;

failure:
    delete object;
    return NULL;
}
示例#4
0
/*----------------------------------------------------------------------
|   PLT_FileMediaServer::BuildFromFilePath
+---------------------------------------------------------------------*/
PLT_MediaObject*
PLT_FileMediaServer::BuildFromFilePath(const NPT_String& filepath, 
                                       bool              with_count /* = true */,
                                       NPT_SocketInfo*   info /* = NULL */,
                                       bool              keep_extension_in_title /* = false */)
{
    NPT_String            delimiter = m_DirDelimiter;
    NPT_String            root = m_Path;
    PLT_MediaItemResource resource;
    PLT_MediaObject*      object = NULL;
    int                   dir_delim_index;

    /* make sure this is a valid entry */
    /* and retrieve the entry type (directory or file) */
    NPT_DirectoryEntryInfo entry_info; 
    if (!ProceedWithEntry(filepath, entry_info)) goto failure;

    /* find the last directory delimiter */
    dir_delim_index = filepath.ReverseFind(delimiter);
    if (dir_delim_index < 0) goto failure;

    if (entry_info.type == NPT_FILE_TYPE) {
        object = new PLT_MediaItem();

        /* we need a valid extension to retrieve the mimetype for the protocol info */
        int ext_index = filepath.ReverseFind('.');
        if (ext_index <= 0 || ext_index < dir_delim_index) {
            ext_index = filepath.GetLength();
        }

        /* Set the title using the filename for now */
        object->m_Title = filepath.SubString(dir_delim_index+1, 
            keep_extension_in_title?filepath.GetLength():ext_index - dir_delim_index -1);
        if (object->m_Title.GetLength() == 0) goto failure;

        /* Set the protocol Info from the extension */
        const char* ext = ((const char*)filepath) + ext_index;
        resource.m_ProtocolInfo = PLT_MediaItem::GetProtInfoFromExt(ext);
        if (resource.m_ProtocolInfo.GetLength() == 0)  goto failure;

        /* Set the resource file size */
        resource.m_Size = entry_info.size;
 
        /* format the resource URI */
        NPT_String url = filepath.SubString(root.GetLength());

        // get list of ip addresses
        NPT_List<NPT_String> ips;
        NPT_CHECK_LABEL_SEVERE(PLT_UPnPMessageHelper::GetIPAddresses(ips), failure);

        // if we're passed an interface where we received the request from
        // move the ip to the top
        if (info && info->local_address.GetIpAddress().ToString() != "0.0.0.0") {
            ips.Remove(info->local_address.GetIpAddress().ToString());
            ips.Insert(ips.GetFirstItem(), info->local_address.GetIpAddress().ToString());
        }

        // iterate through list and build list of resources
        NPT_List<NPT_String>::Iterator ip = ips.GetFirstItem();
        while (ip) {
            NPT_HttpUrl uri = m_FileBaseUri;
            NPT_HttpUrlQuery query;
            query.AddField("path", url);
            uri.SetHost(*ip);
            uri.SetQuery(query.ToString());
            //uri.SetPath(uri.GetPath() + url);

            /* prepend the base URI and url encode it */ 
            //resource.m_Uri = NPT_Uri::Encode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
            resource.m_Uri = uri.ToString();

            /* Look to see if a metadatahandler exists for this extension */
            PLT_MetadataHandler* handler = NULL;
            NPT_Result res = NPT_ContainerFind(m_MetadataHandlers, PLT_MetadataHandlerFinder(ext), handler);
            if (NPT_SUCCEEDED(res) && handler) {
                /* if it failed loading data, reset the metadatahandler so we don't use it */
                if (NPT_SUCCEEDED(handler->LoadFile(filepath))) {
                    /* replace the title with the one from the Metadata */
                    NPT_String newTitle;
                    if (handler->GetTitle(newTitle) != NULL) {
                        object->m_Title = newTitle;
                    }

                    /* assign description */
                    handler->GetDescription(object->m_Description.long_description);

                    /* assign album art uri if we haven't yet */
                    /* prepend the album art base URI and url encode it */ 
                    if (object->m_ExtraInfo.album_art_uri.GetLength() == 0) {
                        NPT_HttpUrl uri = m_AlbumArtBaseUri;
                        NPT_HttpUrlQuery query;
                        query.AddField("path", url);
                        uri.SetHost(*ip);
                        uri.SetQuery(query.ToString());
                        //uri.SetPath(uri.GetPath() + url);

                        object->m_ExtraInfo.album_art_uri = NPT_Uri::PercentEncode(uri.ToString(), NPT_Uri::UnsafeCharsToEncode);
                    }

                    /* duration */
                    handler->GetDuration((NPT_UInt32&)resource.m_Duration);

                    /* protection */
                    handler->GetProtection(resource.m_Protection);
                }
            }

            object->m_ObjectClass.type = PLT_MediaItem::GetUPnPClassFromExt(ext);
            object->m_Resources.Add(resource);

            ++ip;
        }
    } else {
        object = new PLT_MediaContainer;

        /* Assign a title for this container */
        if (filepath.Compare(root, true) == 0) {
            object->m_Title = "Root";
        } else {
            object->m_Title = filepath.SubString(dir_delim_index+1, filepath.GetLength() - dir_delim_index -1);
            if (object->m_Title.GetLength() == 0) goto failure;
        }

        /* Get the number of children for this container */
        if (with_count) {
            NPT_Cardinal count = 0;
            NPT_CHECK_LABEL_SEVERE(GetEntryCount(filepath, count), failure);
            ((PLT_MediaContainer*)object)->m_ChildrenCount = count;
        }

        object->m_ObjectClass.type = "object.container";
    }

    /* is it the root? */
    if (filepath.Compare(root, true) == 0) {
        object->m_ParentID = "-1";
        object->m_ObjectID = "0";
    } else {
        /* is the parent path the root? */
        if (dir_delim_index == (int)root.GetLength() - 1) {
            object->m_ParentID = "0";
        } else {
            object->m_ParentID = "0" + delimiter + filepath.SubString(root.GetLength(), dir_delim_index - root.GetLength());
        }
        object->m_ObjectID = "0" + delimiter + filepath.SubString(root.GetLength());
    }

    return object;

failure:
    delete object;
    return NULL;
}