FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
NpapiBrowserHost.cpp
1 /**********************************************************\
2 Original Author: Richard Bateman (taxilian)
3 
4 Created: Oct 15, 2009
5 License: Dual license model; choose one of two:
6  New BSD License
7  http://www.opensource.org/licenses/bsd-license.php
8  - or -
9  GNU Lesser General Public License, version 2.1
10  http://www.gnu.org/licenses/lgpl-2.1.html
11 
12 Copyright 2009 Richard Bateman, Firebreath development team
13 \**********************************************************/
14 
15 #include <memory>
16 #include <boost/config.hpp>
17 #include <boost/algorithm/string.hpp>
18 
19 #include "NpapiTypes.h"
20 #include "APITypes.h"
21 #include "NpapiPluginModule.h"
22 #include "NPJavascriptObject.h"
23 #include "NPObjectAPI.h"
24 #include "DOM/Document.h"
25 #include "DOM/Window.h"
26 #include "variant_list.h"
27 
28 #include "NpapiStream.h"
29 #include "NpapiBrowserHost.h"
30 #include "BrowserStreamRequest.h"
31 #include "precompiled_headers.h" // On windows, everything above this line in PCH
32 
33 #include "NPVariantUtil.h"
34 #include "URI.h"
35 
36 using namespace FB::Npapi;
37 
38 using boost::algorithm::split;
39 using boost::algorithm::is_any_of;
40 using boost::algorithm::istarts_with;
41 using std::vector;
42 using std::string;
43 using std::map;
44 
45 namespace
46 {
47  struct MethodCallReq
48  {
49  //FB::variant
50  };
51 
52  template<class T>
53  NPVariantBuilderMap::value_type makeBuilderEntry()
54  {
55  return NPVariantBuilderMap::value_type(&typeid(T), select_npvariant_builder::select<T>());
56  }
57 
58  NPVariantBuilderMap makeNPVariantBuilderMap()
59  {
60  NPVariantBuilderMap tdm;
61  tdm.insert(makeBuilderEntry<bool>());
62  tdm.insert(makeBuilderEntry<char>());
63  tdm.insert(makeBuilderEntry<unsigned char>());
64  tdm.insert(makeBuilderEntry<short>());
65  tdm.insert(makeBuilderEntry<unsigned short>());
66  tdm.insert(makeBuilderEntry<int>());
67  tdm.insert(makeBuilderEntry<unsigned int>());
68  tdm.insert(makeBuilderEntry<long>());
69  tdm.insert(makeBuilderEntry<unsigned long>());
70 
71 #ifndef BOOST_NO_LONG_LONG
72  tdm.insert(makeBuilderEntry<long long>());
73  tdm.insert(makeBuilderEntry<unsigned long long>());
74 #endif
75 
76  tdm.insert(makeBuilderEntry<float>());
77  tdm.insert(makeBuilderEntry<double>());
78 
79  tdm.insert(makeBuilderEntry<std::string>());
80  tdm.insert(makeBuilderEntry<std::wstring>());
81 
82  tdm.insert(makeBuilderEntry<FB::FBNull>());
83  tdm.insert(makeBuilderEntry<FB::FBVoid>());
84  //tdm.insert(makeBuilderEntry<FB::FBDateString>());
85  tdm.insert(makeBuilderEntry<FB::VariantList>());
86  tdm.insert(makeBuilderEntry<FB::VariantMap>());
87  tdm.insert(makeBuilderEntry<FB::JSAPIPtr>());
88  tdm.insert(makeBuilderEntry<FB::JSAPIWeakPtr>());
89  tdm.insert(makeBuilderEntry<FB::JSObjectPtr>());
90 
91  return tdm;
92  }
93 
94  const NPVariantBuilderMap& getNPVariantBuilderMap()
95  {
96  static const NPVariantBuilderMap tdm = makeNPVariantBuilderMap();
97  return tdm;
98  }
99 }
100 
101 NpapiBrowserHost::NpapiBrowserHost(NpapiPluginModule *module, NPP npp)
102  : module(module), m_npp(npp)
103 {
104  assert(module != NULL);
105  // Initialize NPNFuncs to NULL values
106  memset(&NPNFuncs, 0, sizeof(NPNetscapeFuncs));
107 }
108 
109 NpapiBrowserHost::~NpapiBrowserHost(void)
110 {
111 }
112 
114  memset(&NPNFuncs, 0, sizeof(NPNetscapeFuncs));
116 
117  // Release these now as the BrowserHost will be expired when the they go out of scope in the destructor.
118  m_htmlWin.reset();
119  m_htmlElement.reset();
120  m_htmlDoc.reset();
121 }
122 
123 bool NpapiBrowserHost::_scheduleAsyncCall(void (*func)(void *), void *userData) const
124 {
125  if (isShutDown())
126  return false;
127  PluginThreadAsyncCall(func, userData);
128  return true;
129 }
130 
131 void NpapiBrowserHost::setBrowserFuncs(NPNetscapeFuncs *pFuncs)
132 {
133  copyNPBrowserFuncs(&NPNFuncs, pFuncs, m_npp);
134 
135  NPObject *window(NULL);
136  NPObject *element(NULL);
137  try {
138  GetValue(NPNVWindowNPObject, (void**)&window);
139  GetValue(NPNVPluginElementNPObject, (void**)&element);
140 
141  m_htmlWin = NPObjectAPIPtr(new FB::Npapi::NPObjectAPI(window, ptr_cast<NpapiBrowserHost>(shared_from_this())));
142  m_htmlElement = NPObjectAPIPtr(new FB::Npapi::NPObjectAPI(element, ptr_cast<NpapiBrowserHost>(shared_from_this())));
143  ReleaseObject(window);
144  ReleaseObject(element);
145  } catch (...) {
146  if (window && !m_htmlWin)
147  ReleaseObject(window);
148  if (element && !m_htmlElement)
149  ReleaseObject(element);
150  }
151  if (m_htmlWin) {
152  m_htmlDoc = ptr_cast<NPObjectAPI>(m_htmlWin->GetProperty("document").cast<FB::JSObjectPtr>());
153  }
154 }
155 
157 {
158  if (!m_htmlDoc)
159  throw std::runtime_error("Cannot find HTML document");
160 
161  return FB::DOM::Document::create(m_htmlDoc);
162 }
163 
165 {
166  if (!m_htmlWin)
167  throw std::runtime_error("Cannot find HTML window");
168 
169  return FB::DOM::Window::create(m_htmlWin);
170 }
171 
173 {
174  if (!m_htmlElement)
175  throw std::runtime_error("Cannot find HTML window");
176 
177  return FB::DOM::Element::create(m_htmlElement);
178 }
179 
180 void FB::Npapi::NpapiBrowserHost::deferred_release( NPObject* obj )
181 {
182  m_deferredObjects.push(obj);
183  if (isMainThread()) {
184  DoDeferredRelease();
185  }
186 }
187 
188 bool isExpired(std::pair<void*, FB::Npapi::NPObjectWeakRef> cur) {
189  return cur.second.expired();
190 }
191 
193 {
194  assertMainThread();
195  NPObject* cur(NULL);
196  while (m_deferredObjects.try_pop(cur)) {
197  ReleaseObject(cur);
198  }
199  // Also remove any expired IDispatch WeakReferences
200  NPObjectRefMap::iterator iter = m_cachedNPObject.begin();
201  NPObjectRefMap::iterator endIter = m_cachedNPObject.end();
202  while (iter != endIter) {
203  if (isExpired(*iter))
204  m_cachedNPObject.erase(iter++);
205  else
206  ++iter;
207  }
208 }
209 
210 void NpapiBrowserHost::evaluateJavaScript(const std::string &script)
211 {
213  NPVariant retVal;
214  NPVariant tmp;
215 
216  this->getNPVariant(&tmp, FB::variant(script));
217 
218  if (!m_htmlWin)
219  throw std::runtime_error("Cannot find HTML window");
220 
221 
222  if (this->Evaluate(m_htmlWin->getNPObject(),
223  &tmp.value.stringValue, &retVal)) {
224  this->ReleaseVariantValue(&retVal);
225  /* Throw away returned variant. NPN_Evaluate supports returning
226  stuff from JS, but ActiveX IHTMLWindow2::execScript does not */
227  return;
228  } else {
229  throw script_error("Error executing JavaScript code");
230  }
231 }
232 
233 FB::variant NpapiBrowserHost::getVariant(const NPVariant *npVar)
234 {
235  FB::variant retVal;
236  switch(npVar->type) {
237  case NPVariantType_Null:
238  retVal = FB::variant_detail::null();
239  break;
240 
241  case NPVariantType_Bool:
242  retVal = npVar->value.boolValue;
243  break;
244 
245  case NPVariantType_Int32:
246  retVal = npVar->value.intValue;
247  break;
248 
249  case NPVariantType_Double:
250  retVal = npVar->value.doubleValue;
251  break;
252 
253  case NPVariantType_String:
254  retVal = std::string(npVar->value.stringValue.UTF8Characters, npVar->value.stringValue.UTF8Length);
255  break;
256 
257  case NPVariantType_Object:
258  retVal = JSObjectPtr(new NPObjectAPI(npVar->value.objectValue, ptr_cast<NpapiBrowserHost>(shared_from_this())));
259  break;
260 
261  case NPVariantType_Void:
262  default:
263  // Do nothing; it's already void =]
264  break;
265  }
266 
267  return retVal;
268 }
269 
270 bool NpapiBrowserHost::isSafari() const
271 {
272  // Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-us) AppleWebKit/533.20.25 (KHTML, like Gecko) Version/5.0.4 Safari/533.20.27
273  std::string agent(UserAgent());
274  return boost::algorithm::contains(agent, "Safari") && !isChrome();
275 }
276 
277 bool NpapiBrowserHost::isFirefox() const
278 {
279  // Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0) Gecko/20100101 Firefox/4.0
280  // Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.15) Gecko/20110303 Firefox/3.6.15
281  std::string agent(UserAgent());
282  return boost::algorithm::contains(agent, "Firefox");
283 }
284 
285 bool NpapiBrowserHost::isChrome() const
286 {
287  // Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_6; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Chrome/10.0.648.204 Safari/534.16
288  std::string agent(UserAgent());
289  return boost::algorithm::contains(agent, "Chrome");
290 }
291 
292 void NpapiBrowserHost::getNPVariant(NPVariant *dst, const FB::variant &var)
293 {
295 
296  const NPVariantBuilderMap& builderMap = getNPVariantBuilderMap();
297  const std::type_info& type = var.get_type();
298  NPVariantBuilderMap::const_iterator it = builderMap.find(&type);
299 
300  if (it == builderMap.end()) {
301  // unhandled type :(
302  return;
303  }
304 
305  *dst = (it->second)(FB::ptr_cast<NpapiBrowserHost>(shared_from_this()), var);
306 }
307 
308 NPError NpapiBrowserHost::GetURLNotify(const char* url, const char* target, void* notifyData) const
309 {
311  if (NPNFuncs.geturlnotify != NULL) {
312  return NPNFuncs.geturlnotify(m_npp, url, target, notifyData);
313  } else {
314  return NPERR_GENERIC_ERROR;
315  }
316 }
317 
318 NPError NpapiBrowserHost::GetURL(const char* url, const char* target) const
319 {
321  if (NPNFuncs.geturl != NULL) {
322  return NPNFuncs.geturl(m_npp, url, target);
323  } else {
324  return NPERR_GENERIC_ERROR;
325  }
326 }
327 
328 NPError NpapiBrowserHost::PostURLNotify(const char* url, const char* target, uint32_t len,
329  const char* buf, NPBool file, void* notifyData) const
330 {
332  if (NPNFuncs.posturlnotify != NULL) {
333  return NPNFuncs.posturlnotify(m_npp, url, target, len, buf, file, notifyData);
334  } else {
335  return NPERR_GENERIC_ERROR;
336  }
337 }
338 
339 NPError NpapiBrowserHost::PostURL(const char* url, const char* target, uint32_t len,
340  const char* buf, NPBool file) const
341 {
343  if (NPNFuncs.posturl != NULL) {
344  return NPNFuncs.posturl(m_npp, url, target, len, buf, file);
345  } else {
346  return NPERR_GENERIC_ERROR;
347  }
348 }
349 
350 NPError NpapiBrowserHost::RequestRead(NPStream* stream, NPByteRange* rangeList) const
351 {
353  if (NPNFuncs.requestread != NULL) {
354  return NPNFuncs.requestread(stream, rangeList);
355  } else {
356  return NPERR_GENERIC_ERROR;
357  }
358 }
359 
360 NPError NpapiBrowserHost::NewStream(NPMIMEType type, const char* target, NPStream** stream) const
361 {
363  if (NPNFuncs.newstream != NULL) {
364  return NPNFuncs.newstream(m_npp, type, target, stream);
365  } else {
366  return NPERR_GENERIC_ERROR;
367  }
368 }
369 
370 int32_t NpapiBrowserHost::Write(NPStream* stream, int32_t len, void* buffer) const
371 {
373  if (NPNFuncs.write != NULL) {
374  return NPNFuncs.write(m_npp, stream, len, buffer);
375  } else {
376  return 0;
377  }
378 }
379 
380 NPError NpapiBrowserHost::DestroyStream(NPStream* stream, NPReason reason) const
381 {
383  if (NPNFuncs.destroystream != NULL) {
384  return NPNFuncs.destroystream(m_npp, stream, reason);
385  } else {
386  return NPERR_GENERIC_ERROR;
387  }
388 }
389 
390 void* NpapiBrowserHost::MemAlloc(uint32_t size) const
391 {
392  return module->MemAlloc(size);
393 }
394 void NpapiBrowserHost::MemFree(void* ptr) const
395 {
396  module->MemFree(ptr);
397 }
398 uint32_t NpapiBrowserHost::MemFlush(uint32_t size) const
399 {
400  return module->MemFlush(size);
401 }
402 
403 NPObject *NpapiBrowserHost::RetainObject(NPObject *npobj) const
404 {
406  return module->RetainObject(npobj);
407 }
408 void NpapiBrowserHost::ReleaseObject(NPObject *npobj) const
409 {
411  return module->ReleaseObject(npobj);
412 }
413 void NpapiBrowserHost::ReleaseVariantValue(NPVariant *variant) const
414 {
416  return module->ReleaseVariantValue(variant);
417 }
418 
419 NPIdentifier NpapiBrowserHost::GetStringIdentifier(const NPUTF8 *name) const
420 {
422  return module->GetStringIdentifier(name);
423 }
424 void NpapiBrowserHost::GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers) const
425 {
427  return module->GetStringIdentifiers(names, nameCount, identifiers);
428 }
429 NPIdentifier NpapiBrowserHost::GetIntIdentifier(int32_t intid) const
430 {
432  return module->GetIntIdentifier(intid);
433 }
434 bool NpapiBrowserHost::IdentifierIsString(NPIdentifier identifier) const
435 {
437  return module->IdentifierIsString(identifier);
438 }
439 NPUTF8 *NpapiBrowserHost::UTF8FromIdentifier(NPIdentifier identifier) const
440 {
442  return module->UTF8FromIdentifier(identifier);
443 }
444 std::string NpapiBrowserHost::StringFromIdentifier(NPIdentifier identifier) const
445 {
447  return module->StringFromIdentifier(identifier);
448 }
449 int32_t NpapiBrowserHost::IntFromIdentifier(NPIdentifier identifier) const
450 {
452  return module->IntFromIdentifier(identifier);
453 }
454 
455 
456 void NpapiBrowserHost::SetStatus(const char* message) const
457 {
459  if (NPNFuncs.status != NULL) {
460  NPNFuncs.status(m_npp, message);
461  }
462 }
463 
464 const char* NpapiBrowserHost::UserAgent() const
465 {
467  if (NPNFuncs.uagent != NULL) {
468  return NPNFuncs.uagent(m_npp);
469  } else {
470  return NULL;
471  }
472 }
473 
474 NPError NpapiBrowserHost::GetValue(NPNVariable variable, void *value) const
475 {
477  if (NPNFuncs.getvalue != NULL) {
478  return NPNFuncs.getvalue(m_npp, variable, value);
479  } else {
480  return NPERR_GENERIC_ERROR;
481  }
482 }
483 
484 NPError NpapiBrowserHost::SetValue(NPPVariable variable, void *value) const
485 {
487  if (NPNFuncs.setvalue != NULL) {
488  return NPNFuncs.setvalue(m_npp, variable, value);
489  } else {
490  return NPERR_GENERIC_ERROR;
491  }
492 }
493 
494 void NpapiBrowserHost::InvalidateRect2(const NPRect& invalidRect) const
495 {
496  NPRect rect = invalidRect;
497  return InvalidateRect(&rect);
498 }
499 
500 void NpapiBrowserHost::InvalidateRect(NPRect *invalidRect) const
501 {
503  if (NPNFuncs.invalidaterect != NULL) {
504  NPNFuncs.invalidaterect(m_npp, invalidRect);
505  }
506 }
507 
508 void NpapiBrowserHost::InvalidateRegion(NPRegion invalidRegion) const
509 {
511  if (NPNFuncs.invalidateregion != NULL) {
512  NPNFuncs.invalidateregion(m_npp, invalidRegion);
513  }
514 }
515 
516 void NpapiBrowserHost::ForceRedraw() const
517 {
519  if (NPNFuncs.forceredraw != NULL) {
520  NPNFuncs.forceredraw(m_npp);
521  }
522 }
523 
524 void NpapiBrowserHost::PushPopupsEnabledState(NPBool enabled) const
525 {
527  if (NPNFuncs.pushpopupsenabledstate != NULL) {
528  NPNFuncs.pushpopupsenabledstate(m_npp, enabled);
529  }
530 }
531 
532 void NpapiBrowserHost::PopPopupsEnabledState() const
533 {
535  if (NPNFuncs.poppopupsenabledstate != NULL) {
536  NPNFuncs.poppopupsenabledstate(m_npp);
537  }
538 }
539 
540 void NpapiBrowserHost::PluginThreadAsyncCall(void (*func) (void *), void *userData) const
541 {
542  if (NPNFuncs.pluginthreadasynccall != NULL) {
543  NPNFuncs.pluginthreadasynccall(m_npp, func, userData);
544  }
545 }
546 
547 /* npruntime.h definitions */
548 NPObject *NpapiBrowserHost::CreateObject(NPClass *aClass) const
549 {
551  if (NPNFuncs.createobject != NULL) {
552  return NPNFuncs.createobject(m_npp, aClass);
553  } else {
554  return NULL;
555  }
556 }
557 
558 bool NpapiBrowserHost::Invoke(NPObject *npobj, NPIdentifier methodName, const NPVariant *args,
559  uint32_t argCount, NPVariant *result) const
560 {
562  if (NPNFuncs.invoke != NULL) {
563  return NPNFuncs.invoke(m_npp, npobj, methodName, args, argCount, result);
564  } else {
565  return false;
566  }
567 }
568 
569 bool NpapiBrowserHost::InvokeDefault(NPObject *npobj, const NPVariant *args,
570  uint32_t argCount, NPVariant *result) const
571 {
573  if (NPNFuncs.invokeDefault != NULL) {
574  return NPNFuncs.invokeDefault(m_npp, npobj, args, argCount, result);
575  } else {
576  return false;
577  }
578 }
579 
580 bool NpapiBrowserHost::Evaluate(NPObject *npobj, NPString *script,
581  NPVariant *result) const
582 {
584  if (NPNFuncs.evaluate != NULL) {
585  return NPNFuncs.evaluate(m_npp, npobj, script, result);
586  } else {
587  return false;
588  }
589 }
590 
591 bool NpapiBrowserHost::GetProperty(NPObject *npobj, NPIdentifier propertyName,
592  NPVariant *result) const
593 {
595  if (NPNFuncs.getproperty != NULL) {
596  return NPNFuncs.getproperty(m_npp, npobj, propertyName, result);
597  } else {
598  return false;
599  }
600 }
601 
602 bool NpapiBrowserHost::SetProperty(NPObject *npobj, NPIdentifier propertyName,
603  const NPVariant *value) const
604 {
606  if (NPNFuncs.setproperty != NULL) {
607  return NPNFuncs.setproperty(m_npp, npobj, propertyName, value);
608  } else {
609  return false;
610  }
611 }
612 
613 bool NpapiBrowserHost::RemoveProperty(NPObject *npobj, NPIdentifier propertyName) const
614 {
616  if (NPNFuncs.removeproperty != NULL) {
617  return NPNFuncs.removeproperty(m_npp, npobj, propertyName);
618  } else {
619  return false;
620  }
621 }
622 
623 bool NpapiBrowserHost::HasProperty(NPObject *npobj, NPIdentifier propertyName) const
624 {
626  if (NPNFuncs.hasproperty != NULL) {
627  return NPNFuncs.hasproperty(m_npp, npobj, propertyName);
628  } else {
629  return false;
630  }
631 }
632 
633 bool NpapiBrowserHost::HasMethod(NPObject *npobj, NPIdentifier methodName) const
634 {
636  if (NPNFuncs.hasmethod != NULL) {
637  return NPNFuncs.hasmethod(m_npp, npobj, methodName);
638  } else {
639  return false;
640  }
641 }
642 
643 bool NpapiBrowserHost::Enumerate(NPObject *npobj, NPIdentifier **identifier,
644  uint32_t *count) const
645 {
647  if (NPNFuncs.enumerate != NULL) {
648  return NPNFuncs.enumerate(m_npp, npobj, identifier, count);
649  } else {
650  return false;
651  }
652 }
653 
654 bool NpapiBrowserHost::Construct(NPObject *npobj, const NPVariant *args,
655  uint32_t argCount, NPVariant *result) const
656 {
658  if (NPNFuncs.construct != NULL) {
659  return NPNFuncs.construct(m_npp, npobj, args, argCount, result);
660  } else {
661  return false;
662  }
663 }
664 
665 void NpapiBrowserHost::SetException(NPObject *npobj, const NPUTF8 *message) const
666 {
668  if (NPNFuncs.setexception != NULL) {
669  NPNFuncs.setexception(npobj, message);
670  }
671 }
672 
673 int NpapiBrowserHost::ScheduleTimer(int interval, bool repeat, void(*func)(NPP npp, uint32_t timerID)) const
674 {
675  if(NPNFuncs.scheduletimer != NULL) {
676  return NPNFuncs.scheduletimer(m_npp, interval, repeat, func);
677  } else {
678  return 0;
679  }
680 }
681 
682 void NpapiBrowserHost::UnscheduleTimer(int timerId) const
683 {
684  if(NPNFuncs.unscheduletimer != NULL) {
685  NPNFuncs.unscheduletimer(m_npp, timerId);
686  }
687 }
688 
689 NPError FB::Npapi::NpapiBrowserHost::GetValueForURL( NPNURLVariable variable, const char *url, char **value, uint32_t *len )
690 {
691  if(NPNFuncs.getvalueforurl != NULL) {
692  return NPNFuncs.getvalueforurl(m_npp, variable, url, value, len);
693  } else {
694  return NPERR_INCOMPATIBLE_VERSION_ERROR;
695  }
696 }
697 
698 NPError FB::Npapi::NpapiBrowserHost::SetValueForURL( NPNURLVariable variable, const char *url, const char *value, uint32_t len )
699 {
700  if(NPNFuncs.setvalueforurl != NULL) {
701  return NPNFuncs.setvalueforurl(m_npp, variable, url, value, len);
702  } else {
703  return NPERR_INCOMPATIBLE_VERSION_ERROR;
704  }
705 }
706 
707 NPError FB::Npapi::NpapiBrowserHost::GetAuthenticationInfo( const char *protocol,
708  const char *host, int32_t port,
709  const char *scheme, const char *realm,
710  char **username, uint32_t *ulen,
711  char **password, uint32_t *plen )
712 {
713  if(NPNFuncs.getauthenticationinfo != NULL) {
714  return NPNFuncs.getauthenticationinfo(m_npp, protocol, host, port, scheme, realm,
715  username, ulen, password, plen);
716  } else {
717  return NPERR_INCOMPATIBLE_VERSION_ERROR;
718  }
719 }
720 
721 FB::BrowserStreamPtr FB::Npapi::NpapiBrowserHost::_createStream( const BrowserStreamRequest& req ) const
722 {
723  assertMainThread();
724  std::string url(req.uri.toString());
725  NpapiStreamPtr stream( boost::make_shared<NpapiStream>( url, req.cache, req.seekable, req.internalBufferSize, FB::ptr_cast<const NpapiBrowserHost>(shared_from_this()) ) );
726  if (req.getEventSink()) {
727  stream->AttachObserver( req.getEventSink() );
728  }
729 
730  NPError err;
731  if (req.method == "GET") {
732  err = GetURLNotify(url.c_str(), 0, stream.get());
733  } else {
734  std::stringstream postOutput;
735  std::string postdata = req.getPostData();
736  std::string postheaders = req.getPostHeaders();
737  if (!postheaders.empty()) {
738  postOutput << postheaders << "\n\n";
739  } else {
740  postOutput << "Content-type: application/x-www-form-urlencoded\n";
741  postOutput << "Content-Length: " << postdata.length() << "\n\n";
742  }
743  postOutput << postdata;
744  std::string out = postOutput.str();
745  err = PostURLNotify( url.c_str(), 0, out.length(), out.c_str(), false, stream.get() );
746  }
747  if (err == NPERR_NO_ERROR) {
748  stream->setCreated();
749  StreamCreatedEvent ev(stream.get());
750  stream->SendEvent( &ev );
751  }
752  else
753  {
754  stream.reset();
755  }
756  return stream;
757 }
758 
759 FB::BrowserStreamPtr NpapiBrowserHost::_createUnsolicitedStream(const FB::BrowserStreamRequest& req) const
760 {
761  std::string url = req.uri.toString();
762  FBLOG_TRACE("NpapiBrowserStream", "Creating an unsolicited stream with url: " << url);
763  bool cache(false);
764  NpapiStreamPtr stream( boost::make_shared<NpapiStream>( url, cache, req.seekable, req.internalBufferSize, FB::ptr_cast<const NpapiBrowserHost>(shared_from_this()) ) );
765  // The observer is attached by the caller
766 
767  stream->setCreated();
768  // we're not waiting for a URLNotify call from this stream
769  stream->setNotified();
770  StreamCreatedEvent ev(stream.get());
771  stream->SendEvent( &ev );
772  return stream;
773 }
774 
775 NPJavascriptObject* FB::Npapi::NpapiBrowserHost::getJSAPIWrapper( const FB::JSAPIWeakPtr& api, bool autoRelease/* = false*/ )
776 {
777  assertMainThread(); // This should only be called on the main thread
778  typedef boost::shared_ptr<FB::ShareableReference<NPJavascriptObject> > SharedNPObjectRef;
779  NPJavascriptObject* ret(NULL);
780  FB::JSAPIPtr ptr(api.lock());
781  if (!ptr)
782  return NPJavascriptObject::NewObject(FB::ptr_cast<NpapiBrowserHost>(shared_from_this()), api, false);
783 
784  NPObjectRefMap::iterator fnd = m_cachedNPObject.find(ptr.get());
785  if (fnd != m_cachedNPObject.end()) {
786  SharedNPObjectRef ref(fnd->second.lock());
787  if (ref) {
788  // Fortunately this doesn't have to be threadsafe since this method only gets called
789  // from the main thread and the browser access happens on that thread as well!
790  ret = ref->getPtr();
791  RetainObject(ret);
792  } else {
793  m_cachedNPObject.erase(fnd);
794  }
795  }
796  if (!ret) {
797  ret = NPJavascriptObject::NewObject(FB::ptr_cast<NpapiBrowserHost>(shared_from_this()), api, autoRelease);
798  if (ret)
799  m_cachedNPObject[ptr.get()] = ret->getWeakReference();
800  }
801  return ret;
802 }
803 
804 bool FB::Npapi::NpapiBrowserHost::DetectProxySettings( std::map<std::string, std::string>& settingsMap, const std::string& URL )
805 {
806  char* retVal;
807  uint32_t len;
808  NPError err = GetValueForURL(NPNURLVProxy, URL.c_str(), &retVal, &len);
809  if (err != NPERR_NO_ERROR) {
810  // Only fall back to system proxy detection if NPAPI's API isn't supported on this browser
811  if (err == NPERR_INCOMPATIBLE_VERSION_ERROR)
812  return FB::BrowserHost::DetectProxySettings(settingsMap, URL);
813  else
814  return false;
815  }
816  std::string res(retVal, len);
817  MemFree(retVal);
818 
819  if (res == "DIRECT") {
820  return false;
821  } else {
822  settingsMap.clear();
823  vector<string> params;
824  // Chrome returns the whole proxy list string,
825  // squashing any space symbols between two consecutive proxies,
826  // thus we need semicolon as a separator also:
827  split(params, res, is_any_of(" ;"));
828  vector<string> host;
829  split(host, params[1], is_any_of(":"));
830  if (params[0] == "PROXY") {
831  FB::URI uri = FB::URI::fromString(URL);
832  settingsMap["type"] = uri.protocol;
833  } else if(params[0] == "SOCKS" ||
834  params[0] == "SOCKS5") {
835  settingsMap["type"] = "socks";
836  } else {
837  settingsMap["type"] = params[0];
838  }
839  settingsMap["hostname"] = host[0];
840  settingsMap["port"] = host[1];
841  return true;
842  }
843 }
844 
845 void FB::Npapi::NpapiBrowserHost::Navigate( const std::string& url, const std::string& target )
846 {
847  PushPopupsEnabledState(true);
848  GetURL(url.c_str(), target.c_str());
849  PopPopupsEnabledState();
850 }
851 
852 NPError NpapiBrowserHost::InitAsyncSurface(NPSize *size, NPImageFormat format, void *initData, NPAsyncSurface *surface) const
853 {
854  if (NPNFuncs.initasyncsurface) {
855  return NPNFuncs.initasyncsurface(m_npp, size, format, initData, surface);
856  }
857  return NPERR_GENERIC_ERROR;
858 }
859 
860 NPError NpapiBrowserHost::FinalizeAsyncSurface(NPAsyncSurface *surface) const
861 {
862  if (NPNFuncs.finalizeasyncsurface) {
863  return NPNFuncs.finalizeasyncsurface(m_npp, surface);
864  }
865  return NPERR_GENERIC_ERROR;
866 }
867 
868 void NpapiBrowserHost::SetCurrentAsyncSurface(NPAsyncSurface *surface, NPRect *changed) const
869 {
870  if (NPNFuncs.setcurrentasyncsurface) {
871  NPNFuncs.setcurrentasyncsurface(m_npp, surface, changed);
872  }
873 }
void Navigate(const std::string &url, const std::string &target)
Instructs the browser to navigate to the specified url in the target window.
const std::type_info & get_type() const
Gets the type of the value stored in variant.
Definition: variant.h:307
boost::shared_ptr< FB::JSObject > JSObjectPtr
Defines an alias representing a JSObject shared_ptr (you should never use a JSObject* directly) ...
Definition: APITypes.h:109
static URI fromString(const std::string &in_str)
Returns a URI object from the given string.
Definition: URI.cpp:90
Accepts any datatype, used in all interactions with javascript. Provides tools for getting back out t...
Definition: variant.h:198
boost::shared_ptr< T > ptr_cast(boost::shared_ptr< U > const &r)
Convenience function for doing a dynamic cast of one boost::shared_ptr to another.
Definition: APITypes.h:339
boost::shared_ptr< Window > WindowPtr
shared_ptr for a FB::DOM::Window
boost::shared_ptr< Document > DocumentPtr
shared_ptr for a FB::DOM::Document
boost::weak_ptr< FB::JSAPI > JSAPIWeakPtr
Defines an alias for a JSAPI weak_ptr (you should never use a JSAPI* directly)
Definition: APITypes.h:88
virtual bool DetectProxySettings(std::map< std::string, std::string > &settingsMap, const std::string &url="")
Detects the proxy settings from the browser.
Information about an HTTP request to be made.
bool isShutDown() const
returns true if the FB::BrowserHost::shutdown() method has been called on this object ...
Definition: BrowserHost.h:417
static DocumentPtr create(const FB::JSObjectPtr &api)
Creates a FB::DOM::Document object from a JSObjectPtr representing a DOM object. This will probably t...
Data structure for dealing with URI strings.
Definition: URI.h:42
boost::shared_ptr< FB::JSAPI > JSAPIPtr
Defines an alias for a JSAPI shared_ptr (you should never use a JSAPI* directly)
Definition: APITypes.h:94
FB::DOM::ElementPtr getDOMElement()
Gets a DOM::Element wrapper for the DOM/JS object tag that the plugin resides in. ...
Exception type; when thrown in a JSAPI method, a javascript exception will be thrown.
Definition: JSExceptions.h:28
static WindowPtr create(const FB::JSObjectPtr &api)
Creates a FB::DOM::Window object from a JSObjectPtr representing a DOM object. This will probably thr...
FB::DOM::WindowPtr getDOMWindow()
Gets a DOM::Window wrapper for the DOM/JS window object that the plugin resides in.
virtual void shutdown()
Notifies the browserhost object that the associated plugin object is shutting down.
Definition: BrowserHost.cpp:87
static ElementPtr create(const FB::JSObjectPtr &api)
Creates a FB::DOM::Element object from a JSObjectPtr representing a DOM object. This will probably th...
virtual void DoDeferredRelease() const
Releases any browser-specific objects that were destroyed on a thread other than the main thread...
void evaluateJavaScript(const std::string &script)
Evaluates arbitrary javascript; note that it does not return the result due to cross- browser compati...
void shutdown()
Notifies the browserhost object that the associated plugin object is shutting down.
void assertMainThread() const
When running in debug mode, asserts that the call is made on the main thread.
FB::DOM::DocumentPtr getDOMDocument()
Gets a DOM::Document wrapper for the document object that the plugin resides in.
Provides a FB::JSObject implementation that wraps a NPObject*.
Definition: NPObjectAPI.h:32
boost::shared_ptr< Element > ElementPtr
shared_ptr for a FB::DOM::Element
virtual bool DetectProxySettings(std::map< std::string, std::string > &settingsMap, const std::string &url="")
Detects the proxy settings from the browser.