/*---------------------------------------------------------------------- | PLT_DeviceData::GetDescriptionUrl +---------------------------------------------------------------------*/ NPT_String PLT_DeviceData::GetDescriptionUrl(const char* ip_address) { NPT_HttpUrl url = m_URLDescription; // replace host with ip address specified if (ip_address) url.SetHost(ip_address); return url.ToString(); }
/*---------------------------------------------------------------------- | PLT_DeviceData::GetDescriptionUrl +---------------------------------------------------------------------*/ NPT_String PLT_DeviceData::GetDescriptionUrl(const char* bind_addr) { NPT_HttpUrl url = m_URLDescription; // override host if (bind_addr) url.SetHost(bind_addr); return url.ToString(); }
/*---------------------------------------------------------------------- | CUPnPRenderer::ProcessHttpRequest +---------------------------------------------------------------------*/ NPT_Result CUPnPRenderer::ProcessHttpGetRequest(NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response) { // get the address of who sent us some data back NPT_String ip_address = context.GetRemoteAddress().GetIpAddress().ToString(); NPT_String method = request.GetMethod(); NPT_String protocol = request.GetProtocol(); NPT_HttpUrl url = request.GetUrl(); if (url.GetPath() == "/thumb") { NPT_HttpUrlQuery query(url.GetQuery()); NPT_String filepath = query.GetField("path"); if (!filepath.IsEmpty()) { NPT_HttpEntity* entity = response.GetEntity(); if (entity == NULL) return NPT_ERROR_INVALID_STATE; // check the method if (request.GetMethod() != NPT_HTTP_METHOD_GET && request.GetMethod() != NPT_HTTP_METHOD_HEAD) { response.SetStatus(405, "Method Not Allowed"); return NPT_SUCCESS; } // prevent hackers from accessing files outside of our root if ((filepath.Find("/..") >= 0) || (filepath.Find("\\..") >=0)) { return NPT_FAILURE; } #if 1 std::string path; //url #else // open the file CStdString path = CURL::Decode((const char*) filepath); #endif NPT_File file(path.c_str()); NPT_Result result = file.Open(NPT_FILE_OPEN_MODE_READ); if (NPT_FAILED(result)) { response.SetStatus(404, "Not Found"); return NPT_SUCCESS; } NPT_InputStreamReference stream; file.GetInputStream(stream); entity->SetContentType(GetMimeType(filepath)); entity->SetInputStream(stream, true); return NPT_SUCCESS; } } return PLT_MediaRenderer::ProcessHttpGetRequest(request, context, response); }
/*---------------------------------------------------------------------- | PLT_DeviceData::SetURLBase +---------------------------------------------------------------------*/ NPT_Result PLT_DeviceData::SetURLBase(NPT_HttpUrl& url) { // only http scheme supported m_URLBase.SetScheme(url.GetScheme()); // update port if any if (url.GetPort() != NPT_URL_INVALID_PORT) m_URLBase.SetPort(url.GetPort()); // update host if any if (!url.GetHost().IsEmpty()) m_URLBase.SetHost(url.GetHost()); // update path NPT_String path = url.GetPath(); // remove trailing file according to RFC 2396 if (!path.EndsWith("/")) { int index = path.ReverseFind('/'); if (index < 0) return NPT_FAILURE; path.SetLength(index+1); } m_URLBase.SetPath(path, true); return NPT_SUCCESS; }
/*---------------------------------------------------------------------- | PLT_FileMediaServer::BuildResourceUri +---------------------------------------------------------------------*/ NPT_String PLT_FileMediaServer::BuildResourceUri(const NPT_HttpUrl& base_uri, const char* host, const char* file_path) { NPT_HttpUrl uri = base_uri; NPT_HttpUrlQuery query(uri.GetQuery()); NPT_String result; query.AddField("path", file_path); if (host) uri.SetHost(host); uri.SetQuery(query.ToString()); // 360 hack: force inclusion of port result = uri.ToStringWithDefaultPort(0); // 360 hack: it removes the query, so we make it look like a path // and we replace + with urlencoded value of space result.Replace('?', "%3F"); result.Replace('+', "%20"); return result; }
/*---------------------------------------------------------------------- | PLT_DeviceData::SetURLBase +---------------------------------------------------------------------*/ NPT_Result PLT_DeviceData::SetURLBase(NPT_HttpUrl& url) { // we're assuming param passed to be relative (Host/port not different than description) m_URLBasePath = url.GetPath(); // remove trailing file according to RFC 2396 if (!m_URLBasePath.EndsWith("/")) { int index = m_URLBasePath.ReverseFind('/'); if (index < 0) return NPT_FAILURE; m_URLBasePath.SetLength(index+1); } return NPT_SUCCESS; }
bool CStreamCtrl::RecvHeaderData(NPT_HttpUrl url,NPT_DataBuffer& buffer) { NPT_HttpClient client; NPT_String rdUrl=url.ToString(); // first request NPT_HttpRequest request(url, NPT_HTTP_METHOD_GET, NPT_HTTP_PROTOCOL_1_1); NPT_HttpResponse* response = NULL; client.SendRequest(request, response); NPT_HttpEntity* entity = NULL; if (response && (entity = response->GetEntity())) { if (NPT_FAILED(entity->Load(buffer))) return false; } else return false; return true; }
bool CStreamCtrl::RecvMediaData(NPT_HttpUrl url,int in_nStartPos, int in_nEndPos,NPT_DataBuffer& buffer) { NPT_HttpClient client; NPT_String rdUrl=url.ToString(); // first request NPT_HttpRequest request(url, NPT_HTTP_METHOD_GET, NPT_HTTP_PROTOCOL_1_1); char range[100]={0}; sprintf(range," bytes=%d-%d",in_nStartPos,in_nEndPos-1); request.GetHeaders().SetHeader(NPT_HTTP_HEADER_RANGE,range); NPT_HttpResponse* response = NULL; client.SendRequest(request, response); NPT_HttpEntity* entity = NULL; if (response && (entity = response->GetEntity())) { if (NPT_FAILED(entity->Load(buffer))) return false; } else return false; return true; }
/*---------------------------------------------------------------------- | 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; }