Created
June 30, 2015 11:06
-
-
Save lacostej/17bb57e96a1698269ad4 to your computer and use it in GitHub Desktop.
Unity PageData pattern
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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