I'm using UnityHTTP (https://github.com/andyburke/UnityHTTP) to call a REST API ( KiiCloud http://www.kii.com ) and it works great but I want to get rid of the 3rd party library if possible and use Unity's WWW and WWWForm to achieve the same.
Here's the code that uses UnityHTTP that works fine:
public static void RunServerExtension (string appId, string appKey, string endpoint, string kii_access_token, string msg)
{
Hashtable data = new Hashtable();
// Add json fields with values here (use as dictionary)
data.Add("message", msg);
// When you pass a Hashtable as the third argument, we assume you want it send as JSON-encoded
// data. We'll encode it to JSON for you and set the Content-Type header to application/json
HTTP.Request myRequest = new HTTP.Request( "post", "https://api.kii.com/api/apps/" + appId + "/server-code/versions/current/" + endpoint, data);
myRequest.AddHeader("x-kii-appid", appId);
myRequest.AddHeader("x-kii-appkey", appKey);
if(kii_access_token != null)
theRequest.AddHeader("Authorization", "Bearer " + kii_access_token);
myRequest.Send( ( request ) => {
// we provide Object and Array convenience methods that attempt to parse the response as JSON
// if the response cannot be parsed, we will return null
// note that if you want to send json that isn't either an object ({...}) or an array ([...])
// that you should use JSON.JsonDecode directly on the response.Text, Object and Array are
// only provided for convenience
Hashtable result = request.response.Object;
if ( result == null )
{
Debug.LogWarning( "Could not parse JSON response!" );
return;
}
Debug.Log ("Got response");
Debug.Log(request.response.Text);
});
}
So the above works just fine but when I switch to WWWForm in this way:
public static WWW RunServerExtension (string appId, string appKey, string endpoint, string kii_access_token, string msg)
{
WWWForm form = new WWWForm();
Hashtable headers = form.headers;
headers["Content-Type"] = "application/json";
headers["x-kii-appid"] = appId;
headers["x-kii-appkey"] = appKey;
if(kii_access_token != null)
headers["Authorization"] = "Bearer " + kii_access_token;
form.AddField("message", msg);
return new WWW("https://api.kii.com/api/apps/" + appId + "/server-code/versions/current/" + endpoint, form.data, headers);
}
private IEnumerator WaitForRequest(WWW www)
{
yield return www;
// check for errors
if (www.error == null)
{
Debug.Log("WWW Ok!: " + www.text);
} else {
Debug.Log("WWW Error: "+ www.error);
}
}
I get a BAD REQUEST on the server side (meaning the request is malformed, not what the server was expecting). Note that the headers must be passed as parameter otherwise the server complains about missing headers.
I suspected this might be related to the fact that the server expects JSON data so I converted the message to JSON using UnityHTTP JSON class (you can use just that isolated class for JSON encoding/decoding) https://github.com/andyburke/UnityHTTP/blob/master/external/JSON.cs so this method passes {"message":"This is echoed!!"} as data:
public static WWW RunServerExtension (string appId, string appKey, string endpoint, string kii_access_token, string msg)
{
WWWForm form = new WWWForm();
Hashtable headers = form.headers;
headers["Content-Type"] = "application/json";
headers["x-kii-appid"] = appId;
headers["x-kii-appkey"] = appKey;
if(kii_access_token != null)
headers["Authorization"] = "Bearer " + kii_access_token;
Hashtable data = new Hashtable();
data["message"] = msg;
byte[] bytes = GetBytes(JSON.JsonEncode(data));
return new WWW("https://api.kii.com/api/apps/" + appId + "/server-code/versions/current/" + endpoint, bytes, headers);
}
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
But still the same BAD REQUEST. Do you see why this could be failing? Why UnityHTTP works?