/*---------------------------------------------------------------------- | PLT_DeviceData::SetDescription +---------------------------------------------------------------------*/ NPT_Result PLT_DeviceData::SetDescription(PLT_DeviceDataReference& root_device, NPT_TimeInterval leasetime, NPT_HttpUrl description_url, const char* description, const NPT_HttpRequestContext& context) { NPT_XmlParser parser; NPT_XmlNode* tree = NULL; NPT_Result res; NPT_XmlElementNode* root = NULL; NPT_String URLBase; // create new device if none passed if (root_device.IsNull()) { root_device = new PLT_DeviceData(description_url, "", leasetime); } res = parser.Parse(description, tree); NPT_CHECK_LABEL_SEVERE(res, cleanup); root = tree->AsElementNode(); if (!root || root->GetTag() != "root" || !root->GetNamespace() || *root->GetNamespace() != "urn:schemas-upnp-org:device-1-0") { NPT_LOG_INFO_1("root namespace is invalid: %s", (root&&root->GetNamespace())?root->GetNamespace()->GetChars():"null"); NPT_CHECK_LABEL_SEVERE(NPT_FAILURE, cleanup); } // look for optional URLBase element if (NPT_SUCCEEDED(PLT_XmlHelper::GetChildText(root, "URLBase", URLBase))) { NPT_HttpUrl url(URLBase); // Some devices like Connect360 try to be funny - not so if (url.GetHost().ToLowercase() == "localhost" || url.GetHost().ToLowercase() == "127.0.0.1") { url.SetHost(context.GetRemoteAddress().GetIpAddress().ToString()); } root_device->SetURLBase(url); } else { // No URLBase, derive from description url root_device->SetURLBase(description_url); } // at least one root device child element is required NPT_XmlElementNode* device; if (!(device = PLT_XmlHelper::GetChild(root, "device"))) { NPT_CHECK_LABEL_SEVERE(NPT_FAILURE, cleanup); } res = SetDescriptionDevice(root_device, device, context); cleanup: // delete the tree delete tree; return res; }
/*---------------------------------------------------------------------- | 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); }
NPT_Result CHttpServer::SetupResponse(NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response) { NPT_String prefix = NPT_String::Format("PLT_HttpServer::SetupResponse %s request from %s for \"%s\"", (const char*) request.GetMethod(), (const char*) context.GetRemoteAddress().ToString(), (const char*) request.GetUrl().ToString()); NPT_List<NPT_HttpRequestHandler*> handlers = FindRequestHandlers(request); if (handlers.GetItemCount() == 0) return NPT_ERROR_NO_SUCH_ITEM; // ask the handler to setup the response NPT_Result result = (*handlers.GetFirstItem())->SetupResponse(request, context, response); // DLNA compliance UPNPMessageHelper::SetDate(response); if (request.GetHeaders().GetHeader("Accept-Language")) { response.GetHeaders().SetHeader("Content-Language", "en"); } return result; }
NPT_Result SetupResponse(NPT_HttpRequest& request, const NPT_HttpRequestContext& context, NPT_HttpResponse& response) { NPT_String msg = "<HTML>"; msg += "PATH="; msg += request.GetUrl().GetPath(); msg += "<P><B>Local Address:</B> "; msg += context.GetLocalAddress().ToString(); msg += "<P>"; msg += "<B>Remote Address:</B> "; msg += context.GetRemoteAddress().ToString(); msg += "<P><UL>"; if (request.GetUrl().HasQuery()) { NPT_UrlQuery query(request.GetUrl().GetQuery()); for (NPT_List<NPT_UrlQuery::Field>::Iterator it = query.GetFields().GetFirstItem(); it; ++it) { NPT_UrlQuery::Field& field = *it; msg += "<LI>"; msg += field.m_Name; msg += " = "; msg += field.m_Value; msg += " </LI>"; // check for a 'delay' field if (field.m_Name == "delay") { NPT_UInt32 delay = 0; field.m_Value.ToInteger(delay); NPT_Debug("DELAY: %d seconds\n", delay); NPT_System::Sleep(NPT_TimeInterval((float)delay)); } } } msg += "</UL></HTML>"; if (request.GetMethod() == NPT_HTTP_METHOD_POST) { NPT_DataBuffer request_body; request.GetEntity()->Load(request_body); NPT_Debug("REQUEST: body = %d bytes\n", request_body.GetDataSize()); NPT_Debug("REQUEST: content type = %s\n", request.GetEntity()->GetContentType().GetChars()); if (request.GetEntity()->GetContentType().StartsWith("text") || request.GetEntity()->GetContentType() == "application/x-www-form-urlencoded") { NPT_String body_string; body_string.Assign((char*)request_body.GetData(), request_body.GetDataSize()); NPT_Debug("%s", body_string.GetChars()); } } NPT_HttpEntity* entity = response.GetEntity(); entity->SetContentType("text/html"); NPT_MemoryStreamReference memory_stream( new NPT_MemoryStream((const void*)msg.GetChars(), msg.GetLength())); entity->SetInputStream(memory_stream, !m_Chunked); if (m_Chunked) { entity->SetTransferEncoding(NPT_HTTP_TRANSFER_ENCODING_CHUNKED); } return NPT_SUCCESS; }