Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by jesses.co.tt · Apr 02, 2016 at 04:55 AM · androidiosnetworkingwww class

UnityWebRequest and/or HttpWebRequest give 403 on Android with PUT

I am trying to post an image captured through my game to Facebook through their SDK, and as it requires a URI, I wrote a simple AWS Lambda function to take a byte array and upload it to an AWS bucket. The AWS function takes a call and then returns a URL to call PUT to with the image data... So the idea is, if the response is 200, use that URL to post to FB.

But - using Unity 5.2.x to 5.3.4, and Android 4.4 - 6.1 - it always gives me a 403 response, while working fine on iOS.

So, I have a method that takes a byte[] then does this:

     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
             }
     }

Pretty simple, right? On iOS, yes it is. But Android it continually gives me a 403 response on the PUT operation.

So, I've taken to wrapping this in an iOS-specific #ifdef and trying something more natively C-Sharp-ish for Android... Eg.:

     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
     }


... but that also gives me a 403. I've tried a few different options, as you can see from the commented-out code, but no love. For the record, here are the SSL Policy functions that are used as the ServerCertificateValidationCallbacks:

 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;
 }

This is the actual StackTrace:

 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)

At this point, I'm totally stuck... my only thought is to maybe write a native plugin... but would love to NOT have to do that...

Thoughts ???

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Is there a way to fix uploadprogress on mobile? 1 Answer

Smartphone multiplayer - NAT problem? 2 Answers

UnityWebRequest and/or HttpWebRequest gives 403 on PUT 0 Answers

Get the WiFi IP address of the device 1 Answer

Background Networking Activity and Unity Run Loop 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges