WWW class: setting authorization headers not working on iOS?

(also on Unity Answers: http://answers.unity3d.com/questions/607935/www-class-setting-authorization-headers-not-workin.html)

I am using the WWW class to GET a JSON file from a server. An authorization header is required from the server.

Hashtable headers = new Hashtable();
headers["Authorization"] = "Basic " + System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes( myAccessKey + ":" + mySecretKey));
 
WWW www = new WWW(URL, null, headers);
yield return www;
 
Debug.Log (www.text);

This works fine in the Unity editor, desktop builds, and on Android devices, but this does not work on iOS. The authorization fails on iOS and nothing is returned. Has anyone seen anything similar to this?

Just for kicks, try using UTF8:

System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes( myAccessKey + ":" + mySecretKey));

It shouldn’t make a difference and technically only ASCII characters are allowed… but worth a try.

Hmm it didn’t work, still getting a 403 forbidden error. Thanks for the suggestion though! :slight_smile:

If you don’t mind me asking, is this a third party service you’re trying to connect to or is it your own in house endpoint you’re connecting to?

It’s an in-house endpoint.

IIS or Apache?

I don’t think it’s IIS. I am pretty sure it’s not the web server though. The authorization header doesn’t appear on the incoming request when coming from an iOS device, but it does appear when coming from the unity editor or android.

The problem seems to be with setting the header on GET on iOS, not reading it.

That’s what I was looking to get at… trying to find out if the header was even being passed. Could be the Hashtable implementation is not working correctly in iOS.

Instead of:

headers["Authorization"] = "Basic " + System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes( myAccessKey + ":" + mySecretKey));

Try:

headers.Add("Authorization", "Basic " + System.Convert.ToBase64String(System.Text.Encoding.ASCII.GetBytes( myAccessKey + ":" + mySecretKey)));

Just given this a try and still the same result. Hmm puzzled. I found this (Google Code Archive - Long-term storage for Google Code Project Hosting.) which looks like a possible solution to replace the WWW class for iOS.

for 4.3.3 we have pushed the total rewrite of WWW backend, so now GET headers should be handled properly. Can you please bug report with small repro project so we can check it? (just in case 4.3.3 is not yet released)

theBrandonWu: Tested in 4.3.2, you have to do a WWW POST not a WWW GET to have the Authorization header come over to the server.

Alexey: Testing in 4.3.3… IOS WWW seems to be completely broken now. Going back to 4.3.2 for the time being.

Also, on IOS in 4.3.3, 4.3.2 the STATUS response header is missing!

-c

Thanks @Chris HG! I don’t have any problem with using WWW GET to set the Authorization header (other than on iOS/Webplayer) on 4.3.1. Haven’t tested on 4.3.2 or 4.3.3 yet but will do so soon.

I’ve posted the plugin / service I’ve been working on on this thread - the plugin can be downloaded on GitHub if anyone’s interested in taking a look.

You are correct, this seems to be isolated AFAIK.

Sorry for hijacking the thread,
WWW works fine in 4.3.3. I was checking www.error==null instead of IsNullOrEmpty(www.error).
Still no HTTP HEADER on response.

god, thanks for the update - you got me totally panicking :wink:

you mean status?

it is handled a bit differently (as in - ios handles it differently: it is removed from headers)
so first of all we DO handle it internally. Secondly - now you can totally tweak it if you want: check WWWConnection.mm in trampoline
look for

  • (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)response

you can totally hijack your own processing if you need/want
(i would advise to subclass UnityWWWConnectionDelegate but you can do whatever, just make sure you dont break unity side ;-))

Thanks Alexey.

That explains a lot. Let me look at trampoline…

-c

Yup this is totally working on 4.3.3 now. Great timing, thanks! :wink:

checking www.error with IsNullOrEmpty is a must in 4.3.3f
as in player it works by comparing www.error==null but on IOS it does not. Hope nobody spend so much time as I did on this.

@Alexey,

We are still limited to GET and POST out of the box correct? Will this change?

-c