/// <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);
        }
Пример #3
0
        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");
            }
        }
Пример #4
0
        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();
            }
        }