/// <summary> /// Posts the data and returns the response. /// </summary> /// <param name="endpoint">The endpoint to post to</param> /// <param name="jsonData"></param> /// <typeparam name="T">The type to deserialze the response into</typeparam> /// <returns></returns> private static IEnumerator MakeRequest <T>(string endpoint, string jsonData, Action <ResponseData> callback) { var request = new UnityWebRequest($"{endpoint}", "POST") { timeout = 30 }; request.SetRequestHeader("content-type", "application/json"); request.uploadHandler = new UploadHandlerRaw(Encoding.UTF8.GetBytes(jsonData)); request.downloadHandler = new DownloadHandlerBuffer(); var operation = request.SendWebRequest(); while (!operation.isDone) { yield return(null); } // check if request failed if (request.responseCode != 200) { // try to parse server error json ServerErrorResponse error; try { error = JsonUtility.FromJson <ServerErrorResponse>(request.downloadHandler.text); } catch (Exception ex) { Debug.LogWarning($"Exception deserializing auth server error:\n{ex}\nBody:\n{request.downloadHandler.text}"); error = new ServerErrorResponse(ex); } callback(new ResponseData() { ErrorData = error, ResponseCode = request.responseCode }); } else { // attempt to parse response try { T responseObject = JsonUtility.FromJson <T>(request.downloadHandler.text); callback(new ResponseData(responseObject)); } catch (Exception ex) { // error parsing response Debug.LogWarning($"Exception deserializing server response:\n{ex}\nBody:\n{request.downloadHandler.text}"); callback(new ResponseData() { ErrorData = new ServerErrorResponse(ex) }); } } }
//This is just for sending an error message back after something failed server-side public void SendResponse(ConnectedPlayer client, ServerErrorResponse err, params string[] extraData) { Packet response = new Packet(ServerAction.ServerResponse); response.AddData <byte>((byte)err); switch (err) { case ServerErrorResponse.AccountPasswordStrength: for (int i = 0; i < extraData.Length; ++i) { response.AddData <string>(extraData[i]); } break; } client.SendData(response); }
private static ResponseBase ReadResponse(BinaryReader reader) { int responseSize = reader.ReadInt32(); byte[] bytes = reader.ReadBytes(responseSize); ResponseType responseType = (ResponseType)BitConverter.ToInt32(bytes, 0); switch (responseType) { case ResponseType.RegistrationResult: return(RegistrationResponse.Parse(bytes)); case ResponseType.LoginResult: return(LoginResponse.Parse(bytes)); case ResponseType.AddContact: return(AddContactResponse.Parse(bytes)); case ResponseType.GetContacts: return(GetContactsResponse.Parse(bytes)); case ResponseType.SendMessage: return(SendMessageResponse.Parse(bytes)); case ResponseType.ReceiveMessages: return(ReceiveMessagesResponse.Parse(bytes)); case ResponseType.Ok: case ResponseType.InvalidAuthToken: throw new NotImplementedException(); case ResponseType.ServerError: throw new ServerErrorException(ServerErrorResponse.Parse(bytes).ErrorMessage); default: throw new InvalidOperationException("Invalid type of response"); } }
public void Work() { var handler = server.RequestHandler; //using (var stream = new NetworkStream(client, false)) //using (var reader = new StreamReader(stream)) { var httpRequest = new HttpRequestHeader(this, client); while (IsClientConnected) { try { var httpString = httpRequest.Read(); if (string.IsNullOrEmpty(httpString)) { break; } NameValueCollection headers = null; string method = null; string path = null; string protocol = null; string version = null; bool? hasPostData = null; using (var reader = new StringReader(httpString)) { var firstLine = reader.ReadLine(); if (string.IsNullOrEmpty(firstLine)) { server.LogMessage("HTTP ERROR: Empty request"); SendInvalidRequest(null); //continue; break; } var m = Regex.Match(firstLine, @"^([a-zA-Z]+)\s+(\S+)\s+([A-Z]+)/(\d.\d)$"); if (!m.Success) { server.LogMessage("HTTP FIXME: {0}", firstLine); SendInvalidRequest(null); break; } method = m.Groups[1].Value.ToUpperInvariant(); path = m.Groups[2].Value; protocol = m.Groups[3].Value; version = m.Groups[4].Value; hasPostData = server.HasPostData(method); if (hasPostData == null) { server.LogMessage("HTTP ERROR: Unknown method {0}", method); SendInvalidRequest("Unknown HTTP method", protocol, version); break; } if (!server.IsValidProtocol(protocol, version)) { SendInvalidRequest("Unknown HTTP version", protocol, version); break; } headers = new NameValueCollection(StringComparer.OrdinalIgnoreCase); string header; while (!string.IsNullOrEmpty(header = reader.ReadLine())) { var parts = header.Split(new[] { ':' }, 2); if (parts.Length != 2) { continue; } var headerName = parts[0].Trim(); var headerValue = parts[1].TrimStart(); if (string.IsNullOrEmpty(headerName) || string.IsNullOrEmpty(headerValue)) { continue; } headers.Add(headerName, HttpUtility.UrlDecode(headerValue)); } } byte[] postData = null; var contentLengthHdr = headers["Content-Length"]; int contentLength = 0; if (!string.IsNullOrEmpty(contentLengthHdr) && int.TryParse(contentLengthHdr, NumberStyles.None, null, out contentLength) && contentLength > 0) { if (!hasPostData.Value) { server.LogMessage("{0} request cannot contain data", method); SendInvalidRequest(method + " request cannot contain data", protocol, version); break; } postData = new byte[contentLength]; //stream.Read(postData, 0, contentLength); var offset = 0; while (offset < contentLength) { var read = client.Receive(postData, offset, contentLength - offset, SocketFlags.None); offset += read; } } var request = new HttpRequest((IPEndPoint)client.RemoteEndPoint, method, path, protocol, version, headers, postData, this); HttpResponse response; try { response = handler(request); } catch (Exception ex) { server.LogError(ex); response = new ServerErrorResponse(ex); } SendResponse(response); if (response.Code >= 500) { break; } if (string.Equals(headers["Connection"], "close", StringComparison.OrdinalIgnoreCase)) { break; } if (server.IsStopping) { break; } } catch (Exception ex) { server.LogMessage("HTTP ERROR: {0}", ex.ToString()); break; } } //Server.Player.Logger.LogMessage("=== Connection {0} to be terminated ===", Thread.CurrentThread.ManagedThreadId); Close(); } }