UnityMol  0.9.6-875
UnityMol viewer / In developement
BackendManager.cs
Go to the documentation of this file.
1 /*
2  * Adapted from https://github.com/eamonwoortman/django-unity3d-example
3  */
4 
5 using UnityEngine;
6 using System.Collections;
7 using System.Collections.Generic;
8 using System.Xml;
9 using System.IO;
10 using System;
11 using System.Security.Cryptography;
12 using System.Linq;
13 using SimpleJSON;
14 
15 using UI;
16 using System.Net;
17 using System.Globalization;
18 using System.Text;
19 
20 public enum ResponseType {
21  Success,
24  ParseError,
27 }
28 
29 public partial class BackendManager : MonoBehaviour {
30  //---- Public Delegates ----//
37  public delegate void RequestResponseDelegate(ResponseType responseType, JSONNode jsonResponse, string callee);
38 
39 
40  //---- URLS ----//
41  [SerializeField]
42  public bool UseProduction = true;
43  [SerializeField]
44  public string ProductionUrl = "https://hirerna.galaxy.ibpc.fr/api/";
45  [SerializeField]
46  public string DevelopmentUrl = "http://localhost:8000/api/";
47 
48 
49  //---- Private Properties ----//
50  string hostUrl {
51  get {
52  return UseProduction ? ProductionUrl : DevelopmentUrl;
53  }
54  }
55 
56 
57  //---- Private Methods ----//
63  public void PerformRequest(string command, Dictionary<string, object> fields = null, RequestResponseDelegate onResponse = null, string authToken = "") {
64  string url = hostUrl + command;
65  WWW request;
66  WWWForm wwwForm = new WWWForm();
67  Dictionary<string, string> headers = new Dictionary<string, string>();
68 
69  //make sure we get a json response
70  headers.Add("Accept", "application/json");
71  //also, add the authentication token, if we have one
72  if (authToken != "") {
73  //for more information about token authentication, see: http://www.django-rest-framework.org/api-guide/authentication/#tokenauthentication
74  headers.Add("Authorization", "Token " + authToken);
75  }
76 
77  if (fields != null) {
78  foreach (KeyValuePair<string, object> pair in fields) {
79  wwwForm.AddField(pair.Key, pair.Value.ToString());
80  }
81  request = new WWW(url, wwwForm.data, headers);
82  } else {
83  request = new WWW(url, null , headers);
84  }
85 
86  System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace();
87  string callee = stackTrace.GetFrame(1).GetMethod().Name;
88  StartCoroutine(HandleRequest(request, onResponse, callee));
89  }
90 
96  public void PerformFormRequest(string command, WWWForm wwwForm, string filename, string fileData, RequestResponseDelegate onResponse = null, string authToken = "") {
97  HttpWebRequest request = (HttpWebRequest)WebRequest.Create(hostUrl + command);
98 
99  request.Headers.Add("Authorization", "Token " + authToken);
100  request.Method = "POST";
101  request.Accept = "application/json";
102  request.Headers["Accept-Encoding"] = "identity";
103  request.UserAgent = "UnityMol " + UnityMolMain.getVersionString();
104 
105  string boundary = DateTime.Now.Ticks.ToString("x", NumberFormatInfo.InvariantInfo);
106  request.ContentType = "multipart/form-data; boundary=" + boundary;
107 
108  string postData = "--" + boundary + "\r\nContent-Type: text/plain\r\n";
109  postData += "Content-Disposition: form-data; name=\"filename\"; filename=\"" + filename + "\"\r\n\r\n";
110  postData += fileData;
111  postData += "\r\n--" + boundary + "--\r\n";
112  byte[] data = Encoding.UTF8.GetBytes(postData);
113 
114  request.ContentLength = data.Length;
115 
116  using (Stream stream = request.GetRequestStream())
117  {
118  stream.Write(data, 0, data.Length);
119  }
120 
121  HttpWebResponse response;
122  try {
123  response = (HttpWebResponse)request.GetResponse();
124  StartCoroutine(HandleResponse(response, onResponse, ""));
125  } catch(WebException e) {
126  StartCoroutine(HandleResponse((HttpWebResponse)e.Response, onResponse, ""));
127  }
128  }
129 
130  IEnumerator HandleResponse(HttpWebResponse response, RequestResponseDelegate onResponse, string callee) {
131  HttpStatusCode statusCode = response.StatusCode;
132  Debug.Log("Http Status Code: " + response.StatusCode);
133  //if any other error occurred(probably 4xx range), see http://www.django-rest-framework.org/api-guide/status-codes/
134  bool responseSuccessful = (statusCode >= HttpStatusCode.OK && statusCode <= HttpStatusCode.PartialContent);
135  Debug.Log("response successful: " + responseSuccessful);
136  JSONNode responseObj = null;
137 
138  // Get the stream associated with the response.
139  Stream receiveStream = response.GetResponseStream ();
140 
141  // Pipes the stream to a higher level stream reader with the required encoding format.
142  StreamReader readStream = new StreamReader (receiveStream, Encoding.UTF8);
143 
144  Debug.Log("Got stream");
145  Debug.Log(readStream.ReadToEnd());
146 
147  try {
148  responseObj = JSON.Parse(readStream.ReadToEnd());
149  } catch (Exception ex) {
150  if (onResponse != null) {
151  if (!responseSuccessful) {
152  Debug.Log("Could not parse the response, request.text=" + readStream.ReadToEnd());
153  Debug.Log("Exception=" + ex.ToString());
154  onResponse(ResponseType.ParseError, null, callee);
155  } else {
156  if (readStream.ReadToEnd() == "") {
157  onResponse(ResponseType.Success, null, callee);
158  } else {
159  Debug.Log("Could not parse the response, request.text=" + readStream.ReadToEnd());
160  Debug.Log("Exception=" + ex.ToString());
161  onResponse(ResponseType.ParseError, null, callee);
162  }
163  }
164  }
165  yield break;
166  }
167 
168  if (!responseSuccessful) {
169  if (onResponse != null) {
170  onResponse(ResponseType.ErrorFromServer, responseObj, callee);
171  }
172  yield break;
173  }
174 
175  //deal with successful responses
176  if (onResponse != null) {
177  onResponse(ResponseType.Success, responseObj, callee);
178  }
179  }
180 
181  IEnumerator HandleRequest(WWW request, RequestResponseDelegate onResponse, string callee) {
182  //Wait till request is done
183  while (true) {
184  if (request.isDone) {
185  break;
186  }
187  yield return new WaitForEndOfFrame();
188  }
189 
190  //catch proper client errors(eg. can't reach the server)
191  if (!String.IsNullOrEmpty(request.error)) {
192  if (onResponse != null) {
193  onResponse(ResponseType.RequestError, null, callee);
194  }
195  yield break;
196  }
197  int statusCode = 200;
198 
199  if (request.responseHeaders.ContainsKey("REAL_STATUS")) {
200  string status = request.responseHeaders["REAL_STATUS"];
201  statusCode = int.Parse(status.Split(' ')[0]);
202  }
203  //if any other error occurred(probably 4xx range), see http://www.django-rest-framework.org/api-guide/status-codes/
204  bool responseSuccessful = (statusCode >= 200 && statusCode <= 206);
205  JSONNode responseObj = null;
206 
207  try {
208  responseObj = JSON.Parse(request.text);
209  } catch (Exception ex) {
210  if (onResponse != null) {
211  if (!responseSuccessful) {
212  Debug.Log("Could not parse the response, request.text=" + request.text);
213  Debug.Log("Exception=" + ex.ToString());
214  onResponse(ResponseType.ParseError, null, callee);
215  } else {
216  if (request.text == "") {
217  onResponse(ResponseType.Success, null, callee);
218  } else {
219  Debug.Log("Could not parse the response, request.text=" + request.text);
220  Debug.Log("Exception=" + ex.ToString());
221  onResponse(ResponseType.ParseError, null, callee);
222  }
223  }
224  }
225  yield break;
226  }
227 
228  if (!responseSuccessful) {
229  if (onResponse != null) {
230  onResponse(ResponseType.ErrorFromServer, responseObj, callee);
231  }
232  yield break;
233  }
234 
235  //deal with successful responses
236  if (onResponse != null) {
237  onResponse(ResponseType.Success, responseObj, callee);
238  }
239  }
240 }
string ProductionUrl
void PerformRequest(string command, Dictionary< string, object > fields=null, RequestResponseDelegate onResponse=null, string authToken="")
Performs a request to the backend.
IEnumerator HandleResponse(HttpWebResponse response, RequestResponseDelegate onResponse, string callee)
static string getVersionString()
Definition: UnityMolMain.cs:19
static JSONNode Parse(string aJSON)
Definition: SimpleJSON.cs:1065
string DevelopmentUrl
void PerformFormRequest(string command, WWWForm wwwForm, string filename, string fileData, RequestResponseDelegate onResponse=null, string authToken="")
Performs a request to the backend.
delegate void RequestResponseDelegate(ResponseType responseType, JSONNode jsonResponse, string callee)
The response delegate
IEnumerator HandleRequest(WWW request, RequestResponseDelegate onResponse, string callee)
Definition: GUIDisplay.cs:66
ResponseType