PageRenderTime 37ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 0ms

/indra/newview/llurldispatcher.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 323 lines | 200 code | 42 blank | 81 comment | 15 complexity | d082f86906df8f74442e3dbfaa65e6ff MD5 | raw file
Possible License(s): LGPL-2.1
  1. /**
  2. * @file llurldispatcher.cpp
  3. * @brief Central registry for all URL handlers
  4. *
  5. * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  6. * Second Life Viewer Source Code
  7. * Copyright (C) 2010, Linden Research, Inc.
  8. *
  9. * This library is free software; you can redistribute it and/or
  10. * modify it under the terms of the GNU Lesser General Public
  11. * License as published by the Free Software Foundation;
  12. * version 2.1 of the License only.
  13. *
  14. * This library is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  17. * Lesser General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Lesser General Public
  20. * License along with this library; if not, write to the Free Software
  21. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  22. *
  23. * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
  24. * $/LicenseInfo$
  25. */
  26. #include "llviewerprecompiledheaders.h"
  27. #include "llurldispatcher.h"
  28. // viewer includes
  29. #include "llagent.h" // teleportViaLocation()
  30. #include "llcommandhandler.h"
  31. #include "llfloaterhelpbrowser.h"
  32. #include "llfloaterreg.h"
  33. #include "llfloatersidepanelcontainer.h"
  34. #include "llfloaterworldmap.h"
  35. #include "llpanellogin.h"
  36. #include "llregionhandle.h"
  37. #include "llslurl.h"
  38. #include "llstartup.h" // gStartupState
  39. #include "llweb.h"
  40. #include "llworldmapmessage.h"
  41. #include "llurldispatcherlistener.h"
  42. #include "llviewernetwork.h"
  43. // library includes
  44. #include "llnotificationsutil.h"
  45. #include "llsd.h"
  46. static LLURLDispatcherListener sURLDispatcherListener;
  47. class LLURLDispatcherImpl
  48. {
  49. public:
  50. static bool dispatch(const LLSLURL& slurl,
  51. const std::string& nav_type,
  52. LLMediaCtrl* web,
  53. bool trusted_browser);
  54. // returns true if handled or explicitly blocked.
  55. static bool dispatchRightClick(const LLSLURL& slurl);
  56. private:
  57. static bool dispatchCore(const LLSLURL& slurl,
  58. const std::string& nav_type,
  59. bool right_mouse,
  60. LLMediaCtrl* web,
  61. bool trusted_browser);
  62. // handles both left and right click
  63. static bool dispatchHelp(const LLSLURL& slurl, bool right_mouse);
  64. // Handles sl://app.floater.html.help by showing Help floater.
  65. // Returns true if handled.
  66. static bool dispatchApp(const LLSLURL& slurl,
  67. const std::string& nav_type,
  68. bool right_mouse,
  69. LLMediaCtrl* web,
  70. bool trusted_browser);
  71. // Handles secondlife:///app/agent/<agent_id>/about and similar
  72. // by showing panel in Search floater.
  73. // Returns true if handled or explicitly blocked.
  74. static bool dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse);
  75. // handles secondlife://Ahern/123/45/67/
  76. // Returns true if handled.
  77. static void regionHandleCallback(U64 handle, const LLSLURL& slurl,
  78. const LLUUID& snapshot_id, bool teleport);
  79. // Called by LLWorldMap when a location has been resolved to a
  80. // region name
  81. static void regionNameCallback(U64 handle, const LLSLURL& slurl,
  82. const LLUUID& snapshot_id, bool teleport);
  83. // Called by LLWorldMap when a region name has been resolved to a
  84. // location in-world, used by places-panel display.
  85. friend class LLTeleportHandler;
  86. };
  87. // static
  88. bool LLURLDispatcherImpl::dispatchCore(const LLSLURL& slurl,
  89. const std::string& nav_type,
  90. bool right_mouse,
  91. LLMediaCtrl* web,
  92. bool trusted_browser)
  93. {
  94. //if (dispatchHelp(slurl, right_mouse)) return true;
  95. switch(slurl.getType())
  96. {
  97. case LLSLURL::APP:
  98. return dispatchApp(slurl, nav_type, right_mouse, web, trusted_browser);
  99. case LLSLURL::LOCATION:
  100. return dispatchRegion(slurl, nav_type, right_mouse);
  101. default:
  102. return false;
  103. }
  104. /*
  105. // Inform the user we can't handle this
  106. std::map<std::string, std::string> args;
  107. args["SLURL"] = slurl;
  108. r;
  109. */
  110. }
  111. // static
  112. bool LLURLDispatcherImpl::dispatch(const LLSLURL& slurl,
  113. const std::string& nav_type,
  114. LLMediaCtrl* web,
  115. bool trusted_browser)
  116. {
  117. const bool right_click = false;
  118. return dispatchCore(slurl, nav_type, right_click, web, trusted_browser);
  119. }
  120. // static
  121. bool LLURLDispatcherImpl::dispatchRightClick(const LLSLURL& slurl)
  122. {
  123. const bool right_click = true;
  124. LLMediaCtrl* web = NULL;
  125. const bool trusted_browser = false;
  126. return dispatchCore(slurl, "clicked", right_click, web, trusted_browser);
  127. }
  128. // static
  129. bool LLURLDispatcherImpl::dispatchApp(const LLSLURL& slurl,
  130. const std::string& nav_type,
  131. bool right_mouse,
  132. LLMediaCtrl* web,
  133. bool trusted_browser)
  134. {
  135. llinfos << "cmd: " << slurl.getAppCmd() << " path: " << slurl.getAppPath() << " query: " << slurl.getAppQuery() << llendl;
  136. const LLSD& query_map = LLURI::queryMap(slurl.getAppQuery());
  137. bool handled = LLCommandDispatcher::dispatch(
  138. slurl.getAppCmd(), slurl.getAppPath(), query_map, web, nav_type, trusted_browser);
  139. // alert if we didn't handle this secondlife:///app/ SLURL
  140. // (but still return true because it is a valid app SLURL)
  141. if (! handled)
  142. {
  143. LLNotificationsUtil::add("UnsupportedCommandSLURL");
  144. }
  145. return true;
  146. }
  147. // static
  148. bool LLURLDispatcherImpl::dispatchRegion(const LLSLURL& slurl, const std::string& nav_type, bool right_mouse)
  149. {
  150. if(slurl.getType() != LLSLURL::LOCATION)
  151. {
  152. return false;
  153. }
  154. // Before we're logged in, need to update the startup screen
  155. // to tell the user where they are going.
  156. if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
  157. {
  158. // We're at the login screen, so make sure user can see
  159. // the login location box to know where they are going.
  160. LLPanelLogin::setLocation(slurl);
  161. return true;
  162. }
  163. // Request a region handle by name
  164. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(slurl.getRegion(),
  165. LLURLDispatcherImpl::regionNameCallback,
  166. slurl.getSLURLString(),
  167. LLUI::sSettingGroups["config"]->getBOOL("SLURLTeleportDirectly")); // don't teleport
  168. return true;
  169. }
  170. /*static*/
  171. void LLURLDispatcherImpl::regionNameCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
  172. {
  173. if(slurl.getType() == LLSLURL::LOCATION)
  174. {
  175. regionHandleCallback(region_handle, slurl, snapshot_id, teleport);
  176. }
  177. }
  178. /* static */
  179. void LLURLDispatcherImpl::regionHandleCallback(U64 region_handle, const LLSLURL& slurl, const LLUUID& snapshot_id, bool teleport)
  180. {
  181. // we can't teleport cross grid at this point
  182. if((!LLGridManager::getInstance()->isSystemGrid(slurl.getGrid()) || !LLGridManager::getInstance()->isSystemGrid()) &&
  183. (slurl.getGrid() != LLGridManager::getInstance()->getGrid()))
  184. {
  185. LLSD args;
  186. args["SLURL"] = slurl.getLocationString();
  187. args["CURRENT_GRID"] = LLGridManager::getInstance()->getGridLabel();
  188. LLSD grid_info;
  189. LLGridManager::getInstance()->getGridInfo(slurl.getGrid(), grid_info);
  190. if(grid_info.has(GRID_LABEL_VALUE))
  191. {
  192. args["GRID"] = grid_info[GRID_LABEL_VALUE].asString();
  193. }
  194. else
  195. {
  196. args["GRID"] = slurl.getGrid();
  197. }
  198. LLNotificationsUtil::add("CantTeleportToGrid", args);
  199. return;
  200. }
  201. LLVector3d global_pos = from_region_handle(region_handle);
  202. global_pos += LLVector3d(slurl.getPosition());
  203. if (teleport)
  204. {
  205. gAgent.teleportViaLocation(global_pos);
  206. LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
  207. if(instance)
  208. {
  209. instance->trackLocation(global_pos);
  210. }
  211. }
  212. else
  213. {
  214. LLSD key;
  215. key["type"] = "remote_place";
  216. key["x"] = global_pos.mdV[VX];
  217. key["y"] = global_pos.mdV[VY];
  218. key["z"] = global_pos.mdV[VZ];
  219. LLFloaterSidePanelContainer::showPanel("places", key);
  220. }
  221. }
  222. //---------------------------------------------------------------------------
  223. // Teleportation links are handled here because they are tightly coupled
  224. // to SLURL parsing and sim-fragment parsing
  225. class LLTeleportHandler : public LLCommandHandler
  226. {
  227. public:
  228. // Teleport requests *must* come from a trusted browser
  229. // inside the app, otherwise a malicious web page could
  230. // cause a constant teleport loop. JC
  231. LLTeleportHandler() : LLCommandHandler("teleport", UNTRUSTED_BLOCK) { }
  232. bool handle(const LLSD& tokens, const LLSD& query_map,
  233. LLMediaCtrl* web)
  234. {
  235. // construct a "normal" SLURL, resolve the region to
  236. // a global position, and teleport to it
  237. if (tokens.size() < 1) return false;
  238. LLVector3 coords(128, 128, 0);
  239. if (tokens.size() <= 4)
  240. {
  241. coords = LLVector3(tokens[1].asReal(),
  242. tokens[2].asReal(),
  243. tokens[3].asReal());
  244. }
  245. // Region names may be %20 escaped.
  246. std::string region_name = LLURI::unescape(tokens[0]);
  247. LLWorldMapMessage::getInstance()->sendNamedRegionRequest(region_name,
  248. LLURLDispatcherImpl::regionHandleCallback,
  249. LLSLURL(region_name, coords).getSLURLString(),
  250. true); // teleport
  251. return true;
  252. }
  253. };
  254. LLTeleportHandler gTeleportHandler;
  255. //---------------------------------------------------------------------------
  256. // static
  257. bool LLURLDispatcher::dispatch(const std::string& slurl,
  258. const std::string& nav_type,
  259. LLMediaCtrl* web,
  260. bool trusted_browser)
  261. {
  262. return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), nav_type, web, trusted_browser);
  263. }
  264. // static
  265. bool LLURLDispatcher::dispatchRightClick(const std::string& slurl)
  266. {
  267. return LLURLDispatcherImpl::dispatchRightClick(LLSLURL(slurl));
  268. }
  269. // static
  270. bool LLURLDispatcher::dispatchFromTextEditor(const std::string& slurl)
  271. {
  272. // *NOTE: Text editors are considered sources of trusted URLs
  273. // in order to make avatar profile links in chat history work.
  274. // While a malicious resident could chat an app SLURL, the
  275. // receiving resident will see it and must affirmatively
  276. // click on it.
  277. // *TODO: Make this trust model more refined. JC
  278. const bool trusted_browser = true;
  279. LLMediaCtrl* web = NULL;
  280. return LLURLDispatcherImpl::dispatch(LLSLURL(slurl), "clicked", web, trusted_browser);
  281. }