Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        /// <exception cref="IOException"></exception>
        public async Task <AttachmentV3UploadAttributes> GetAttachmentV3UploadAttributesAsync()
        {
            WebSocketRequestMessage requestMessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.GetSecretBytes(sizeof(long)), 0),
                Verb = "GET",
                Path = "/v3/attachments/form/upload"
            };

            var sendTask          = (await websocket.SendRequest(requestMessage)).Task;
            var timerCancelSource = new CancellationTokenSource();

            if (await Task.WhenAny(sendTask, Task.Delay(TimeSpan.FromSeconds(10), timerCancelSource.Token)) == sendTask)
            {
                timerCancelSource.Cancel();
                var(status, body) = sendTask.Result;
                if (status < 200 || status >= 300)
                {
                    throw new IOException($"Non-successful response: {status}");
                }

                return(JsonUtil.FromJson <AttachmentV3UploadAttributes>(body));
            }
            else
            {
                throw new IOException("Timeout reached while waiting for attachment upload attributes.");
            }
        }
        public void ReadBlocking(MessagePipeCallback callback)
        {
            LinkedList <WebSocketRequestMessage> requests = Websocket.readRequests();
            int amount = requests.Count;

            SignalServiceEnvelope[]    envelopes = new SignalServiceEnvelope[amount];
            WebSocketResponseMessage[] responses = new WebSocketResponseMessage[amount];
            for (int i = 0; i < amount; i++)
            {
                WebSocketRequestMessage msg = requests.First.Value;
                requests.RemoveFirst();
                if (isSignalServiceEnvelope(msg))
                {
                    envelopes[i] = new SignalServiceEnvelope(msg.Body.ToByteArray(), CredentialsProvider.GetSignalingKey());
                }
                responses[i] = createWebSocketResponse(msg);
            }
            try
            {
                callback.onMessages(envelopes);
            }
            finally
            {
                foreach (WebSocketResponseMessage response in responses)
                {
                    Websocket.SendResponse(response);
                }
            }
        }
Example #3
0
        /// <summary>
        /// Sends a message through the pipe. Blocks until delivery is confirmed or throws an IOException if a timeout occurs.
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        public async Task <SendMessageResponse> Send(OutgoingPushMessageList list)
        {
            Logger.LogTrace("Send()");
            WebSocketRequestMessage requestmessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.GetSecretBytes(sizeof(long)), 0),
                Verb = "PUT",
                Path = $"/v1/messages/{list.Destination}",
                Body = ByteString.CopyFrom(Encoding.UTF8.GetBytes(JsonUtil.ToJson(list)))
            };

            requestmessage.Headers.Add("content-type:application/json");
            var sendTask          = (await Websocket.SendRequest(requestmessage)).Task;
            var timerCancelSource = new CancellationTokenSource();

            if (await Task.WhenAny(sendTask, Task.Delay(10 * 1000, timerCancelSource.Token)) == sendTask)
            {
                timerCancelSource.Cancel();
                var(Status, Body) = sendTask.Result;
                if (Status < 200 || Status >= 300)
                {
                    throw new IOException("non-successfull response: " + Status);
                }
                if (Util.IsEmpty(Body))
                {
                    return(new SendMessageResponse(false));
                }
                return(JsonUtil.FromJson <SendMessageResponse>(Body));
            }
            else
            {
                Logger.LogError("Sending message {0} failed: timeout", requestmessage.Id);
                throw new IOException("timeout reached while waiting for confirmation");
            }
        }
        public SendMessageResponse Send(OutgoingPushMessageList list)
        {
            WebSocketRequestMessage requestmessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.getSecretBytes(sizeof(long)), 0),
                Verb = "PUT",
                Path = $"/v1/messages/{list.getDestination()}",
                Body = ByteString.CopyFrom(Encoding.UTF8.GetBytes(JsonUtil.toJson(list)))
            };

            requestmessage.Headers.Add("content-type:application/json");
            var t = Websocket.SendRequest(requestmessage);

            t.Wait();
            if (t.IsCompleted)
            {
                var response = t.Result;
                if (response.Item1 < 200 || response.Item1 >= 300)
                {
                    throw new IOException("non-successfull response: " + response.Item1 + " " + response.Item2);
                }
                return(JsonUtil.fromJson <SendMessageResponse>(response.Item2));
            }
            else
            {
                throw new IOException("timeout reached while waiting for confirmation");
            }
        }
Example #5
0
        /// <summary>
        /// Fetches a profile from the server. Blocks until the response arrives or a timeout occurs.
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public async Task <SignalServiceProfile> GetProfile(SignalServiceAddress address)
        {
            Logger.LogTrace("GetProfile()");
            WebSocketRequestMessage requestMessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.GetSecretBytes(sizeof(long)), 0),
                Verb = "GET",
                Path = $"/v1/profile/{address.E164number}"
            };

            var sendTask          = (await Websocket.SendRequest(requestMessage)).Task;
            var timerCancelSource = new CancellationTokenSource();

            if (await Task.WhenAny(sendTask, Task.Delay(10 * 1000, timerCancelSource.Token)) == sendTask)
            {
                timerCancelSource.Cancel();
                var(Status, Body) = sendTask.Result;
                if (Status < 200 || Status >= 300)
                {
                    throw new IOException("non-successfull response: " + Status);
                }
                return(JsonUtil.FromJson <SignalServiceProfile>(Body));
            }
            else
            {
                throw new IOException("timeout reached while waiting for profile");
            }
        }
Example #6
0
        /// <summary>
        /// Blocks until a message was received, calls the IMessagePipeCallback and confirms the message to the server, unless the pipe's token is cancelled.
        /// </summary>
        /// <param name="callback"></param>
        public async Task ReadBlocking(IMessagePipeCallback callback)
        {
            Logger.LogTrace("ReadBlocking()");
            WebSocketRequestMessage request = Websocket.ReadRequestBlocking();

            if (IsSignalServiceEnvelope(request))
            {
                SignalServiceMessagePipeMessage message  = new SignalServiceEnvelope(request.Body.ToByteArray(), CredentialsProvider.SignalingKey);
                WebSocketResponseMessage        response = CreateWebSocketResponse(request);
                try
                {
                    Logger.LogDebug("Calling callback with message {0}", request.Id);
                    await callback.OnMessage(message);
                }
                finally
                {
                    if (!Token.IsCancellationRequested)
                    {
                        Logger.LogDebug("Confirming message {0}", request.Id);
                        Websocket.SendResponse(response);
                    }
                }
            }
            else if (IsPipeEmptyMessage(request))
            {
                Logger.LogInformation("Calling callback with SignalServiceMessagePipeEmptyMessage");
                await callback.OnMessage(new SignalServiceMessagePipeEmptyMessage());
            }
            else
            {
                Logger.LogWarning("Unknown request: {0} {1}", request.Verb, request.Path);
            }
        }
        public SignalServiceProfile GetProfile(SignalServiceAddress address)
        {
            WebSocketRequestMessage requestMessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.getSecretBytes(sizeof(long)), 0),
                Verb = "GET",
                Path = $"/v1/profile/{address.getNumber()}"
            };

            var t = Websocket.SendRequest(requestMessage);

            t.Wait();
            if (t.IsCompleted)
            {
                var response = t.Result;
                if (response.Item1 < 200 || response.Item1 >= 300)
                {
                    throw new IOException("non-successfull response: " + response.Item1 + " " + response.Item2);
                }
                return(JsonUtil.fromJson <SignalServiceProfile>(response.Item2));
            }
            else
            {
                throw new IOException("timeout reached while waiting for profile");
            }
        }
 private void sendKeepAlive(object state)
 {
     Debug.WriteLine("keepAlive");
     sendMessage(WebSocketMessage.CreateBuilder()
                 .SetType(WebSocketMessage.Types.Type.REQUEST)
                 .SetRequest(WebSocketRequestMessage.CreateBuilder()
                             .SetId(KeyHelper.getTime())
                             .SetPath("/v1/keepalive")
                             .SetVerb("GET")
                             .Build()).Build());
 }
Example #9
0
        /*internal async Task sendMessage(WebSocketMessage message)
         * {
         *  if (socket == null)
         *  {
         *      throw new Exception("Connection closed!");
         *  }
         *
         *  messageWriter.WriteBytes(message.ToByteArray());
         *  await messageWriter.StoreAsync();
         * }
         *
         * internal async Task sendResponse(WebSocketResponseMessage response)
         * {
         *  if (socket == null)
         *  {
         *      throw new Exception("Connection closed!");
         *  }
         *
         *  WebSocketMessage message = WebSocketMessage.CreateBuilder()
         *                                     .SetType(WebSocketMessage.Types.Type.RESPONSE)
         *                                     .SetResponse(response)
         *                                     .Build();
         *
         *  messageWriter.WriteBytes(message.ToByteArray());
         *  await messageWriter.StoreAsync();
         * }*/

        private void sendKeepAlive(object state)
        {
            if (socket != null)
            {
                Debug.WriteLine("keepAlive");
                byte[] message = WebSocketMessage.CreateBuilder()
                                 .SetType(WebSocketMessage.Types.Type.REQUEST)
                                 .SetRequest(WebSocketRequestMessage.CreateBuilder()
                                             .SetId(KeyHelper.getTime())
                                             .SetPath("/v1/keepalive")
                                             .SetVerb("GET")
                                             .Build()).Build()
                                 .ToByteArray();
                messageWriter.WriteBytes(message);
                messageWriter.StoreAsync();
            }
        }
 private WebSocketResponseMessage createWebSocketResponse(WebSocketRequestMessage request)
 {
     if (isSignalServiceEnvelope(request))
     {
         return(WebSocketResponseMessage.CreateBuilder()
                .SetId(request.Id)
                .SetStatus(200)
                .SetMessage("OK")
                .Build());
     }
     else
     {
         return(WebSocketResponseMessage.CreateBuilder()
                .SetId(request.Id)
                .SetStatus(400)
                .SetMessage("Unknown")
                .Build());
     }
 }
 private WebSocketResponseMessage createWebSocketResponse(WebSocketRequestMessage request)
 {
     if (isSignalServiceEnvelope(request))
     {
         return(new WebSocketResponseMessage
         {
             Id = request.Id,
             Status = 200,
             Message = "OK"
         });
     }
     else
     {
         return(new WebSocketResponseMessage
         {
             Id = request.Id,
             Status = 400,
             Message = "Unknown"
         });
     }
 }
Example #12
0
        /*public  WebSocketRequestMessage readRequest(ulong timeoutMillis)
         * {
         *  if (client == null)
         *  {
         *      throw new Exception("Connection closed!");
         *  }
         *
         *  ulong startTime = KeyHelper.getTime();
         *
         *  while (client != null && incomingRequests.Count == 0 && elapsedTime(startTime) < timeoutMillis)
         *  {
         *      //Util.wait(this, Math.Max(1, timeoutMillis - elapsedTime(startTime)));
         *  }
         *
         *  if (incomingRequests.Count == 0 && client == null) throw new Exception("Connection closed!");
         *  else if (incomingRequests.Count == 0) throw new TimeoutException("Timeout exceeded");
         *  else
         *  {
         *      WebSocketRequestMessage message = incomingRequests.First();
         *      incomingRequests.RemoveFirst();
         *      return message;
         *  }
         * }*/

        internal async Task <Tuple <int, string> > sendRequest(WebSocketRequestMessage request)
        {
            if (socket == null || !connected)
            {
                throw new IOException("No connection!");
            }

            WebSocketMessage message = WebSocketMessage.CreateBuilder()
                                       .SetType(WebSocketMessage.Types.Type.REQUEST)
                                       .SetRequest(request)
                                       .Build();

            Tuple <int, string> empty = new Tuple <int, string>(0, string.Empty);

            outgoingRequests.Add((long)request.Id, empty);

            messageWriter.WriteBytes(message.ToByteArray());
            await messageWriter.StoreAsync();

            return(empty);
        }
        private void OnMessageReceived(WebSocketConnection sender, WebSocketRequestMessage request)
        {
            WebSocketResponseMessage response = createWebSocketResponse(request);

            Debug.WriteLine($"Verb: {request.Verb}, Path {request.Path}, Body({request.Body.Length}): {request.Body}, Id: {request.Id}");

            try
            {
                if (isTextSecureEnvelope(request))
                {
                    TextSecureEnvelope envelope = new TextSecureEnvelope(request.Body.ToByteArray(),
                                                                         credentialsProvider.GetSignalingKey());

                    MessageReceived(this, envelope);
                }
            }
            //catch (Exception e) { } // ignore for now
            finally
            {
                websocket.sendResponse(response);
            }
        }
        private void OnMessageReceived(WebSocketConnection sender, WebSocketRequestMessage request)
        {
            WebSocketResponseMessage response = createWebSocketResponse(request);

            Debug.WriteLine($"Verb: {request.Verb}, Path {request.Path}, Body({request.Body.Length}): {request.Body}, Id: {request.Id}");

            try
            {
                if (isSignalServiceEnvelope(request))
                {
                    SignalServiceEnvelope envelope = new SignalServiceEnvelope(request.Body.ToByteArray(),
                                                                               credentialsProvider.GetSignalingKey());

                    MessageReceived(this, envelope);
                }
            }
            //catch (Exception e) { } // ignore for now
            finally
            {
                websocket.sendResponse(response);
            }
        }
Example #15
0
        /// <summary>
        /// Fetches a profile from the server. Blocks until the response arrives or a timeout occurs.
        /// </summary>
        /// <param name="address"></param>
        /// <param name="unidentifiedAccess"></param>
        /// <returns></returns>
        public async Task <SignalServiceProfile> GetProfileAsync(SignalServiceAddress address, UnidentifiedAccess?unidentifiedAccess)
        {
            logger.LogTrace("GetProfile()");
            var headers = new List <string>()
            {
                "content-type:application/json"
            };

            if (unidentifiedAccess != null)
            {
                headers.Add("Unidentified-Access-Key:" + Base64.EncodeBytes(unidentifiedAccess.UnidentifiedAccessKey));
            }
            WebSocketRequestMessage requestMessage = new WebSocketRequestMessage()
            {
                Id   = BitConverter.ToUInt64(Util.GetSecretBytes(sizeof(long)), 0),
                Verb = "GET",
                Path = $"/v1/profile/{address.GetIdentifier()}"
            };

            var sendTask          = (await websocket.SendRequest(requestMessage)).Task;
            var timerCancelSource = new CancellationTokenSource();

            if (await Task.WhenAny(sendTask, Task.Delay(TimeSpan.FromSeconds(10), timerCancelSource.Token)) == sendTask)
            {
                timerCancelSource.Cancel();
                var(Status, Body) = sendTask.Result;
                if (Status < 200 || Status >= 300)
                {
                    throw new IOException("non-successful response: " + Status);
                }
                return(JsonUtil.FromJson <SignalServiceProfile>(Body));
            }
            else
            {
                throw new IOException("timeout reached while waiting for profile");
            }
        }
Example #16
0
        /// <summary>
        /// Blocks until a message was received, calls the IMessagePipeCallback and confirms the message to the server, unless the pipe's token is canceled.
        /// </summary>
        /// <param name="callback"></param>
        public async Task ReadBlockingAsync(IMessagePipeCallback callback)
        {
            logger.LogTrace("ReadBlocking()");
            if (credentialsProvider == null)
            {
                throw new ArgumentException("You can't read messages if you haven't specified credentials");
            }
            WebSocketRequestMessage request = websocket.ReadRequestBlocking();

            if (IsSignalServiceEnvelope(request))
            {
                SignalServiceMessagePipeMessage message  = new SignalServiceEnvelope(request.Body.ToByteArray());
                WebSocketResponseMessage        response = CreateWebSocketResponse(request);
                try
                {
                    logger.LogDebug("Calling callback with message {0}", request.Id);
                    await callback.OnMessageAsync(message);
                }
                finally
                {
                    if (!token.IsCancellationRequested)
                    {
                        logger.LogDebug("Confirming message {0}", request.Id);
                        websocket.SendResponse(response);
                    }
                }
            }
            else if (IsPipeEmptyMessage(request))
            {
                logger.LogInformation("Calling callback with SignalServiceMessagePipeEmptyMessage");
                await callback.OnMessageAsync(new SignalServiceMessagePipeEmptyMessage());
            }
            else
            {
                logger.LogWarning("Unknown request: {0} {1}", request.Verb, request.Path);
            }
        }
Example #17
0
 private bool IsPipeEmptyMessage(WebSocketRequestMessage message)
 {
     return(message.Verb == "PUT" && message.Path == "/api/v1/queue/empty");
 }
 private bool isTextSecureEnvelope(WebSocketRequestMessage message)
 {
     return "PUT".Equals(message.Verb) && "/api/v1/message".Equals(message.Path);
 }
 private bool isSignalServiceEnvelope(WebSocketRequestMessage message)
 {
     return("PUT".Equals(message.Verb) && "/api/v1/message".Equals(message.Path));
 }
Example #20
0
 private bool isTextSecureEnvelope(WebSocketRequestMessage message)
 {
     return("PUT".Equals(message.Verb) && "/api/v1/message".Equals(message.Path));
 }
 private WebSocketResponseMessage createWebSocketResponse(WebSocketRequestMessage request)
 {
     if (isTextSecureEnvelope(request))
     {
         return WebSocketResponseMessage.CreateBuilder()
                                        .SetId(request.Id)
                                        .SetStatus(200)
                                        .SetMessage("OK")
                                        .Build();
     }
     else
     {
         return WebSocketResponseMessage.CreateBuilder()
                                        .SetId(request.Id)
                                        .SetStatus(400)
                                        .SetMessage("Unknown")
                                        .Build();
     }
 }
Example #22
0
 private bool IsSignalServiceEnvelope(WebSocketRequestMessage message)
 {
     return(message.Verb == "PUT" && message.Path == "/api/v1/message");
 }