1

我正在編寫一個小應用程序來測試和理解PNaCl。解析主機時,便攜本機客戶端權限被拒絕

該應用程序的目標是使用PNaCl框架中的HostResolver類來解析主機的IP地址。該代碼似乎正常工作,但我得到一個訪問被拒絕的錯誤(返回值-7),因爲我沒有要求訪問套接字層的權限(我猜)給用戶。問題是我不知道如何去做。我編寫了一個清單文件,但沒有發生任何事情。

注意:此應用程序必須在打開的Web上運行,並且不得要求任何安裝過程。 我不想寫一個Chrome應用程序。

我還沒有找到任何線索,所以我將不勝感激您的幫助。

hello_tuttorial.cc:

#include <stdio.h> 
#include <string.h> 
#include <sstream> 


#include "ppapi/cpp/instance.h" 
#include "ppapi/cpp/module.h" 
#include "ppapi/cpp/var.h" 
#include "ppapi/cpp/tcp_socket.h" 
#include "ppapi/cpp/host_resolver.h" 
#include "ppapi/cpp/module.h" 
#include "ppapi/cpp/tcp_socket.h" 
#include "ppapi/c/pp_errors.h" 
#include "ppapi/utility/completion_callback_factory.h" 


namespace { 
    // exptected string from the browser 
    const char * const kHelloString = "hello"; 
    // the sting sent from the nacl module to the browser 
    const char * const kReplyString ="hello from the PNaCl"; 
} 


class HelloTutorialInstance : public pp::Instance { 

    pp::CompletionCallbackFactory<HelloTutorialInstance> callback_factory_; 
    pp::TCPSocket tcp_socket_; 
    pp::HostResolver resolver_; 

public: 
    explicit HelloTutorialInstance(PP_Instance instance) : pp::Instance(instance), 
     callback_factory_(this) 
     {} 

    virtual ~HelloTutorialInstance() {} 

    virtual void HandleMessage(const pp::Var& var_message) { 
    if (!var_message.is_string()) 
     return; 

    std::string message = var_message.AsString(); 
    pp::Var var_reply; 

    test_socket_support(); 

    if(message == kHelloString){ 
     var_reply = pp::Var("So far so good"); 
     PostMessage(var_reply); 
    } 

    } 

private: 

void test_socket_support(){ 

    if (!pp::TCPSocket::IsAvailable()) { 
     PostMessage("TCPSocket not available"); 
     return; 
    } 

    tcp_socket_ = pp::TCPSocket(this); 

    if (tcp_socket_.is_null()) { 
     PostMessage("Error creating TCPSocket."); 
     return; 
    } 

    if (!pp::HostResolver::IsAvailable()) { 
    PostMessage("HostResolver not available"); 
    return; 
    } 

    resolver_ = pp::HostResolver(this); 
    if (resolver_.is_null()) { 
    PostMessage("Error creating HostResolver."); 
    return; 
    } 


    int port = 80; 
    pp::CompletionCallback callback = \ 
     callback_factory_.NewCallback(&HelloTutorialInstance::OnResolveCompletion); 
    PP_HostResolver_Hint hint = { PP_NETADDRESS_FAMILY_UNSPECIFIED, 0 }; 
    resolver_.Resolve("http://www.google.com", port, hint, callback); 
    PostMessage("Resolving ..."); 

    } 

void OnResolveCompletion(int32_t result) { 
    if (result != PP_OK) { 
    char str[100] = {0}; 
    sprintf(str, "Resolved failed %d", result); 
    PostMessage(str); 

    if(result == PP_ERROR_NOACCESS) 
     PostMessage("Access denied"); 
    return; 
    } 

    pp::NetAddress addr = resolver_.GetNetAddress(0); 
    PostMessage(std::string("Resolved: ") + 
       addr.DescribeAsString(true).AsString()); 

    } 
}; 

class HelloTutorialModule : public pp::Module { 
public: 
    HelloTutorialModule() : pp::Module() {} 
    virtual ~HelloTutorialModule() {} 

    virtual pp::Instance* CreateInstance(PP_Instance instance) { 
    return new HelloTutorialInstance(instance); 
    } 
}; 

namespace pp { 
    Module* CreateModule() { 
    return new HelloTutorialModule(); 
    } 
} // namespace pp 

的manifest.json:

{ 
    "name": "hello_tutorial", 
    "version": "31.0.1650.57", 
    "manifest_version": 2, 
    "description": "socket Example", 
    "offline_enabled": true, 
    "permissions": [ 
    { 
     "socket": [ 
      "tcp-listen:*:*", 
      "tcp-connect", 
      "resolve-host", 
      "udp-bind:*:*", 
      "udp-send-to:*:*" 
     ] 
    } 
] 
} 

的index.html:

<div id="listener"> 
    <script type="text/javascript"> 
    var listener = document.getElementById('listener'); 
    listener.addEventListener('load', moduleDidLoad, true); 
    listener.addEventListener('message', handleMessage, true); 
    </script> 

    <embed id="hello_tutorial" 
     width=0 height=0 
     src="hello_tutorial.nmf" 
     type="application/x-pnacl" /> 
</div> 

輸出:

Resolving ... 
So far so good 
Resolved failed -7 
Access denied 

回答

0

頁:: HostResolver和其他原始套接字接口只能通過Chrome應用中使用,而不是開放的網絡。見here

此外,如果您決定製作Chrome應用程序,請參閱文檔here。你不能只添加一個manifest.json文件,你還必須指定一個後臺腳本來啓動你的應用程序。

7

只有來自chrome商店的打包應用程序才能使用套接字API。

當您啓動Chrome時,您可以通過設置'--allow-nacl-socket-api=foo'標誌來訪問開發套接字。將'foo'替換爲您要從中加載應用程序的主機名。 '本地主機',如果你從本地機器加載。請注意,您應該而不是在'about:flags'上啓用'allow-nacl-socket-api'選項。這將覆蓋命令行選項,但不包括授權主機的列表,結果是沒有主機有權使用套接字API。

相關問題