Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# UnityWebRequest和/或HttpWebRequest在Android上提供403和PUT_C#_Android_Unity3d_Network Programming_Put - Fatal编程技术网

C# UnityWebRequest和/或HttpWebRequest在Android上提供403和PUT

C# UnityWebRequest和/或HttpWebRequest在Android上提供403和PUT,c#,android,unity3d,network-programming,put,C#,Android,Unity3d,Network Programming,Put,我也在Unity Answers和GameDev上发布了这篇文章,但如果任何C网络负责人能够指出我的HttpWebRequest代码中的任何明显错误,我会在这里发布x-posting 我正试图通过他们的SDK将通过游戏捕获的图像发布到Facebook上,因为它需要一个URI,我编写了一个简单的AWS Lambda函数来获取字节数组并将其上传到AWS bucket。AWS函数接受一个调用,然后返回一个URL以调用图像数据。。。 因此,我们的想法是,如果响应是200,使用该URL发布到FB 但是,使

我也在Unity Answers和GameDev上发布了这篇文章,但如果任何C网络负责人能够指出我的HttpWebRequest代码中的任何明显错误,我会在这里发布x-posting

我正试图通过他们的SDK将通过游戏捕获的图像发布到Facebook上,因为它需要一个URI,我编写了一个简单的AWS Lambda函数来获取字节数组并将其上传到AWS bucket。AWS函数接受一个调用,然后返回一个URL以调用图像数据。。。 因此,我们的想法是,如果响应是200,使用该URL发布到FB

但是,使用Unity 5.2.x到5.3.4,以及Android 4.4到6.1,它总是给我403的响应,同时在iOS上运行良好

因此,我有一个方法,它接受一个字节[],然后执行以下操作:

    WWW w = new WWW("https://my-amazon-function-to-call");
    yield return w;
    if (!string.IsNullOrEmpty(w.error)) {
        Debug.LogError(w.error);
    }
    else 
    {
             var dict = Json.Deserialize(w.text) as Dictionary<string,object>;
             string oneTimeUploadUrl = (string)dict["oneTimeUploadUrl"]; // Private URL
             string resultUrl = (string)dict["resultUrl"]; // Public URL

            UnityWebRequest aws = UnityWebRequest.Put(oneTimeUploadUrl, bytes);
            yield return aws.Send();
            if(aws.isError) 
            {
                Debug.LogError("AWS ERROR: " + aws.error);
            }
            if(aws.responseCode == 200)
            {
                FeedShare(new Uri(resultUrl), _cachedMessage);    // FB call
            }
    }
很简单,对吧? 在iOS上,是的。但Android it不断地给我一个关于PUT操作的403响应

所以,我已经开始用iOS特有的ifdef来包装它,并尝试在安卓系统上使用更自然的C-Sharp-ish。。。例如:

    WWW w = new WWW("https://my-amazon-function-to-call"); // tried pure old Http too
    yield return w;
    if (!string.IsNullOrEmpty(w.error)) {
        Debug.LogError(w.error);
    }
    else {
        var dict = Json.Deserialize(w.text) as Dictionary<string,object>;
        string oneTimeUploadUrl = (string)dict["oneTimeUploadUrl"];
        string resultUrl = (string)dict["resultUrl"];

    #if UNITY_IPHONE
        UnityWebRequest aws = UnityWebRequest.Put(oneTimeUploadUrl, bytes);
        yield return aws.Send();
        if(aws.isError) 
        {
            Debug.LogError("AWS ERROR: " + aws.error);
        }
        if(aws.responseCode == 200)
        {
            FeedShare(new Uri(resultUrl), _cachedMessage);    
        }
    #else             

    // Various Security Callback Tests
        //ServicePointManager.ServerCertificateValidationCallback = (p1, p2, p3, p4) => true;
        //ServicePointManager.ServerCertificateValidationCallback = MyRemoteCertificateValidationCallback;
        ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(AcceptAllCertifications);


        HttpWebRequest wreq = (HttpWebRequest)WebRequest.Create(oneTimeUploadUrl);
        //wreq.AuthenticationLevel = System.Net.Security.AuthenticationLevel.None;
        //wreq.PreAuthenticate = false;
        wreq.Method = "PUT";
        wreq.ContentType = "image/png";
        wreq.ContentLength = bytes.Length;

        Stream newStream = wreq.GetRequestStream();
        newStream.Write(bytes, 0, bytes.Length);
        newStream.Close();

        HttpWebResponse response = (HttpWebResponse)wreq.GetResponse();
        if((int)response.StatusCode == 200)
        {
            FeedShare(new Uri(resultUrl), _cachedMessage);
        }
     #endif
    }
。。。但这也给了我403分。我尝试了一些不同的选择,正如你从注释掉的代码中看到的,但是没有爱。以下是用作ServerCertificateValidationCallbacks的SSL策略函数:

public bool AcceptAllCertifications(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certification, System.Security.Cryptography.X509Certificates.X509Chain chain, System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

public bool MyRemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors) {
    bool isOk = true;
    if (sslPolicyErrors != SslPolicyErrors.None) {
        for (int i=0; i<chain.ChainStatus.Length; i++) {
            if (chain.ChainStatus [i].Status != X509ChainStatusFlags.RevocationStatusUnknown) {
                chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain;
                chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
                chain.ChainPolicy.UrlRetrievalTimeout = new TimeSpan (0, 1, 0);
                chain.ChainPolicy.VerificationFlags = X509VerificationFlags.AllFlags;
                bool chainIsValid = chain.Build ((X509Certificate2)certificate);
                if (!chainIsValid) {
                    isOk = false;
                }
            }
        }
    }
    print("MyRemoteCertificateValidationCallback: " + isOk);
    return isOk;
}
这是实际的堆栈跟踪:

04-01 11:14:57.325: I/Unity(22979):  
04-01 11:14:57.325: I/Unity(22979): (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 37)
04-01 11:14:57.825: I/Unity(22979): WebException: The remote server returned an error: (403) Forbidden.
04-01 11:14:57.825: I/Unity(22979):   at System.Net.HttpWebRequest.CheckFinalStatus (System.Net.WebAsyncResult result) [0x00000] in <filename unknown>:0 
04-01 11:14:57.825: I/Unity(22979):   at System.Net.HttpWebRequest.SetResponseData (System.Net.WebConnectionData data) [0x00000] in <filename unknown>:0 
04-01 11:14:57.825: I/Unity(22979):  
04-01 11:14:57.825: I/Unity(22979): (Filename:  Line: -1)
在这一点上,我完全被卡住了。。。我唯一的想法是写一个本地插件。。。但我不想这样做


想法???

我面临着类似的问题,我总是得到403分。然后我发现我的服务器正在检查标题中的内容类型和用户代理。在我把它们放好之后,它就起作用了。我的代码是:

UnityWebRequest www = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
byte[] body = new System.Text.UTF8Encoding().GetBytes(json_string);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(body);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader("Content-Type", "application/json");
www.SetRequestHeader("User-Agent", "DefaultBrowser");
www.SetRequestHeader("Cookie", string.Format("DummyCookie"));
www.chunkedTransfer = false;
yield return www.Send();

我面临着类似的问题,我总是得到403分。然后我发现我的服务器正在检查标题中的内容类型和用户代理。在我把它们放好之后,它就起作用了。我的代码是:

UnityWebRequest www = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST);
byte[] body = new System.Text.UTF8Encoding().GetBytes(json_string);
www.uploadHandler = (UploadHandler)new UploadHandlerRaw(body);
www.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
www.SetRequestHeader("Content-Type", "application/json");
www.SetRequestHeader("User-Agent", "DefaultBrowser");
www.SetRequestHeader("Cookie", string.Format("DummyCookie"));
www.chunkedTransfer = false;
yield return www.Send();

将您的最低API级别更改为2.3.1。真的吗???我现在的是4.2。。。我真的不想支持API 9。。。你有什么证据吗?我不知道你的目标。如果您的目标是5.xx,那么这可能就是问题所在。我今天通过将API更改为4.1解决了这样的问题。既然您提到了您的API,这可能不是问题所在,但不妨尝试一下。更改为4.1而不是2.3.1。好的,我会尝试一下,也可以使用5.x告诉我是否可以将您的最低API级别更改为2.3.1。真的吗???我现在的是4.2。。。我真的不想支持API 9。。。你有什么证据吗?我不知道你的目标。如果您的目标是5.xx,那么这可能就是问题所在。我今天通过将API更改为4.1解决了这样的问题。既然您提到了您的API,这可能不是问题所在,但不妨尝试一下。更改为4.1而不是2.3.1Okay,将尝试使用5.x。请让我知道在指定浏览器名称时My UnityWebRequest是否有效。例如:request.SetRequestHeaderUser-Agent、Mozilla/5.0 Windows NT 10.0;Win64;x64;rv:69.0 Gecko/20100101 Firefox/69.0对我来说,它修复了这个问题,即使没有使用普通名称填充用户代理值,它也可以使用空字符串。thanksMy UnityWebRequest在我指定浏览器名称时起作用。例如:request.SetRequestHeaderUser-Agent、Mozilla/5.0 Windows NT 10.0;Win64;x64;rv:69.0 Gecko/20100101 Firefox/69.0对我来说,它修复了这个问题,即使没有使用普通名称填充用户代理值,它也可以使用空字符串。谢谢