Skip to content

Instantly share code, notes, and snippets.

@lacostej
Created June 30, 2015 11:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lacostej/17bb57e96a1698269ad4 to your computer and use it in GitHub Desktop.
Save lacostej/17bb57e96a1698269ad4 to your computer and use it in GitHub Desktop.
Unity PageData pattern
namespace WWTK.Server {
namespace Util {
// Immutable struct to represent a WWW GET/POST page result
public struct PageData {
private int m_StatusCode;
private string m_Text;
private Dictionary<string, string> m_Headers;
public int StatusCode { get { return m_StatusCode; } }
public string Text { get { return m_Text; } }
public Dictionary<string, string> Headers { get { return m_Headers; } }
public PageData(int _statusCode, string _text) {
m_StatusCode = _statusCode;
m_Text = _text;
m_Headers = new Dictionary<string,string>();
}
public PageData(int _statusCode, string _text, Dictionary<string,string> _headers) {
m_StatusCode = _statusCode;
m_Text = _text;
m_Headers = _headers;
}
public static PageData FromWWW(WWW _www) {
#if !UNITY_EDITOR
Dump(_www);
#endif
PageData Result;
// ideally we should use the WWW.error field,
// but this one isn't even set properly. E.g. on Unity Editor a 409 error doesn't set error on Unity 4.3.0b5
int StatusCode;
string Text;
string StatusKey = FindHTTPStatusKey(_www);
if (StatusKey != null) {
// this might not work cross-platform. Unity spec is pretty shallow here
// trying some heuristics..
string status = _www.responseHeaders[StatusKey];
string[] R = status.Split(' ');
try {
StatusCode = System.Int32.Parse(R[0]);
Text = R[1];
} catch (System.FormatException) {
try {
StatusCode = System.Int32.Parse(R[1]);
if (R.Length > 2)
Text = R[2];
else
Text = "";
} catch (System.FormatException e2) {
Debug.LogException(e2);
StatusCode = -1;
Text = status;
}
}
if (StatusCode == 200)
Text = _www.text;
} else {
if (!string.IsNullOrEmpty(_www.error)) {
if (_www.error.StartsWith("401: ")) { // Uity 4.6.5f1, IOS-8
StatusCode = 401;
Text = _www.error;
} else {
StatusCode = -1;
Text = _www.error;
}
} else {
StatusCode = 200;
Text = _www.text;
}
}
Result = new PageData(StatusCode, Text, _www.responseHeaders);
#if UNITY_EDITOR
Debug.Log ("EDITOR_ONLY: PageData: " + Result.ToString());
#endif
return Result;
}
// heuristic to find the keys for HTTP Status in responseHeaders
private static string FindHTTPStatusKey(WWW _www) {
string[] Keys = {"STATUS" /* at least 4.3.0b5 Android */,
"NULL" /* at least 4.3.3f1 Android */}; // reported as #596529
foreach (string key in Keys) {
if (_www.responseHeaders.ContainsKey(key)) return key;
}
return null;
}
private static void Dump(WWW _www) {
Debug.Log ("ERROR:" + _www.error);
Debug.Log ("isDone:" + _www.isDone);
Debug.Log ("bytes:" + _www.bytes);
if (_www.responseHeaders != null) {
Debug.Log ("responseHeaders:" + _www.responseHeaders.Count);
foreach(string key in _www.responseHeaders.Keys)
Debug.Log ("responseHeaders[" + key + "]:" + _www.responseHeaders[key]);
}
Debug.Log ("TEXT:" + _www.text);
}
public override string ToString() {
StringBuilder Builder = new StringBuilder("PageData");
Builder.Append("Status=").Append(m_StatusCode);
Builder.Append("Text=").Append(m_Text);
return Builder.ToString();
}
}
interface IHttpClient {
// a wrapper around WWW that returns a PageData object
IEnumerator RequestData(string _Uri, Dictionary<string, string> _ExtraHeaders, byte[] _PostData = null);
}
public class DefaultHttpClient : IHttpClient {
/* Get/Post the specified requestData to the specified uri. The Coroutine will return a PageData object */
public IEnumerator RequestData(string _Uri, Dictionary<string, string> _ExtraHeaders, byte[] _PostData = null) {
var postHeader = AsHeaders(_ExtraHeaders);
byte[] bytes = _PostData;
if (bytes != null)
postHeader.Add("Content-Length", bytes.Length.ToString());
string url = _Uri;
WWW www = new WWW(url, bytes, postHeader);
yield return www;
yield return PageData.FromWWW(www);
}
private static System.Collections.Generic.Dictionary<string, string> AsHeaders(Dictionary<string, string> _ExtraHeaders) {
System.Collections.Generic.Dictionary<string, string> postHeader = new System.Collections.Generic.Dictionary<string, string>();
foreach(var header in _ExtraHeaders)
{
postHeader.Add (header.Key, header.Value);
}
foreach(string key in postHeader.Keys) {
//Debug.Log ("requestHeaders[" + key + "]:" + postHeader[key]);
}
return postHeader;
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment