示例#1
0
        public async Task <Action <HttpClient> > DoOAuthRequestAsync(string url, string apiKey)
        {
            ThrowIfBadUrlOrApiKey(url, apiKey);
            uri = new Uri(url.ToWebSocketPath());

            using (var webSocket = new RavenClientWebSocket())
            {
                try
                {
                    Logger.Info("Trying to connect using WebSocket to {0} for authentication", uri);
                    try
                    {
                        await webSocket.ConnectAsync(uri, CancellationToken.None);
                    }
                    catch (WebSocketException webSocketException)
                    {
                        throw new InvalidOperationException($"Cannot connect using WebSocket to {uri} for authentication", webSocketException);
                    }
                    var recvRavenJObject = await Recieve(webSocket);

                    var challenge = ComputeChallenge(recvRavenJObject, apiKey);
                    await Send(webSocket, "ChallengeResponse", challenge);

                    recvRavenJObject = await Recieve(webSocket);

                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close from client", disposedToken.Token);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine(ex.ToString());
                    }
                    SetCurrentTokenFromReply(recvRavenJObject);
                    return(SetAuthorization);
                }
                catch (Exception ex)
                {
                    Logger.DebugException($"Failed to DoOAuthRequest to {url} with {apiKey}", ex);
                    throw;
                }
            }
        }
示例#2
0
        /// <summary>
        /// Connects to raven traffic event source and registers all the requests to the file defined in the config
        /// </summary>
        /// <param name="config">configuration conatining the connection, the file to write to, etc.</param>
        /// <param name="store">the store to work with</param>
        private async Task RecordRequests(TrafficToolConfiguration config, IDocumentStore store)
        {
            var id = Guid.NewGuid().ToString();

            using (var client = new RavenClientWebSocket())
            {
                var url = store.Url + "/traffic-watch/websockets";
                var uri = new Uri(url.ToWebSocketPath());

                await client.ConnectAsync(uri, CancellationToken.None)
                .ConfigureAwait(false);


                // record traffic no more then 7 days
                var day     = 24 * 60 * 60;
                var timeout = (int)config.Timeout.TotalMilliseconds / 1000;
                timeout = Math.Min(timeout, 7 * day);
                if (timeout <= 0)
                {
                    timeout = 7 * day;
                }

                try
                {
                    string resourceName   = config.ResourceName ?? "N/A";
                    var    connectMessage = new DynamicJsonValue
                    {
                        ["Id"]           = id,
                        ["ResourceName"] = resourceName,
                        ["Timeout"]      = timeout
                    };

                    var stream = new MemoryStream();

                    JsonOperationContext context;
                    using (_jsonContextPool.AllocateOperationContext(out context))
                        using (var writer = new BlittableJsonTextWriter(context, stream))
                        {
                            context.Write(writer, connectMessage);
                            writer.Flush();

                            ArraySegment <byte> bytes;
                            stream.TryGetBuffer(out bytes);
                            await client.SendAsync(bytes, WebSocketMessageType.Text, true, CancellationToken.None)
                            .ConfigureAwait(false);
                        }

                    var requestsCounter = 0;
                    using (var fileStream = File.Create(config.RecordFilePath))
                    {
                        Stream finalStream = fileStream;
                        if (config.IsCompressed)
                        {
                            finalStream = new GZipStream(fileStream, CompressionMode.Compress, leaveOpen: true);
                        }

                        using (var streamWriter = new StreamWriter(finalStream))
                        {
                            var jsonWriter = new JsonTextWriter(streamWriter)
                            {
                                Formatting = Formatting.Indented
                            };
                            jsonWriter.WriteStartArray();
                            var sp = Stopwatch.StartNew();

                            while (true)
                            {
                                using (var reader = await Receive(client, context))
                                {
                                    if (reader == null)
                                    {
                                        // server asked to close connection
                                        break;
                                    }

                                    string type;
                                    if (reader.TryGet("Type", out type))
                                    {
                                        if (type.Equals("Heartbeat"))
                                        {
                                            continue;
                                        }
                                    }

                                    string error;
                                    if (reader.TryGet("Error", out error))
                                    {
                                        throw new InvalidOperationException("Server returned error: " + error);
                                    }

                                    var notification = new TrafficWatchNotification();
                                    notification.TimeStamp           = GetDateTimeFromJson(reader, "TimeStamp");
                                    notification.RequestId           = GetIntFromJson(reader, "RequestId");
                                    notification.HttpMethod          = GetStringFromJson(reader, "HttpMethod");
                                    notification.ElapsedMilliseconds = GetIntFromJson(reader, "ElapsedMilliseconds");
                                    notification.ResponseStatusCode  = GetIntFromJson(reader, "ResponseStatusCode");
                                    notification.TenantName          = GetStringFromJson(reader, "TenantName");
                                    notification.CustomInfo          = GetStringFromJson(reader, "CustomInfo");
                                    notification.InnerRequestsCount  = GetIntFromJson(reader, "InnerRequestsCount");
                                    // notification.QueryTimings = GetRavenJObjectFromJson(reader, "QueryTimings"); // TODO (TrafficWatch) : Handle this both server and client sides

                                    if (config.PrintOutput)
                                    {
                                        Console.Write("\rRequest #{0} Stored...\t\t ", ++requestsCounter);
                                    }

                                    var jobj = RavenJObject.FromObject(notification);
                                    jobj.WriteTo(jsonWriter);

                                    if (sp.ElapsedMilliseconds > 5000)
                                    {
                                        streamWriter.Flush();
                                        sp.Restart();
                                    }
                                }
                            }
                            jsonWriter.WriteEndArray();
                            streamWriter.Flush();
                            if (config.IsCompressed)
                            {
                                finalStream.Dispose();
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("\r\n\nError while reading messages from server : " + ex);
                }
                finally
                {
                    Console.WriteLine("\r\n\nClosing connection to server...`");
                    try
                    {
                        await
                        client.CloseAsync(WebSocketCloseStatus.NormalClosure, "CLOSE_NORMAL", CancellationToken.None)
                        .ConfigureAwait(false);
                    }
                    catch
                    {
                        // ignored
                    }
                }
            }
        }
        public async Task <string> AuthenticateAsync(string url, string apiKey, JsonOperationContext context)
        {
            var uri = new Uri(url.ToWebSocketPath());

            using (var webSocket = new RavenClientWebSocket())
            {
                try
                {
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info($"Trying to connect using WebSocket to {uri} for authentication");
                    }
                    try
                    {
                        await webSocket.ConnectAsync(uri, _disposedToken.Token);
                    }
                    catch (WebSocketException webSocketException)
                    {
                        throw new InvalidOperationException($"Cannot connect using WebSocket to {uri} for authentication", webSocketException);
                    }

                    AuthenticatorChallenge authenticatorChallenge;
                    using (var result = await Recieve(webSocket, context))
                    {
                        if (result == null)
                        {
                            throw new InvalidDataException("Got null authtication challenge");
                        }
                        authenticatorChallenge = JsonDeserializationClient.AuthenticatorChallenge(result);
                    }
                    var challenge = ComputeChallenge(authenticatorChallenge, apiKey);
                    await Send(webSocket, context, "ChallengeResponse", challenge);

                    string currentToken;
                    using (var reader = await Recieve(webSocket, context))
                    {
                        string error;
                        if (reader.TryGet("Error", out error))
                        {
                            string exceptionType;
                            if (reader.TryGet("ExceptionType", out exceptionType) == false || exceptionType == "InvalidOperationException")
                            {
                                throw new InvalidOperationException("Server returned error: " + error);
                            }

                            if (exceptionType == "InvalidApiKeyException")
                            {
                                throw new InvalidApiKeyException(error);
                            }
                        }

                        string currentOauthToken;
                        if (reader.TryGet("CurrentToken", out currentOauthToken) == false || currentOauthToken == null)
                        {
                            throw new InvalidOperationException("Missing 'CurrentToken' in response message");
                        }

                        currentToken = currentOauthToken;
                    }

                    try
                    {
                        await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Close from client", _disposedToken.Token);
                    }
                    catch (Exception ex)
                    {
                        if (Logger.IsInfoEnabled)
                        {
                            Logger.Info("Failed to close the client", ex);
                        }
                    }

                    return(currentToken);
                }
                catch (Exception ex)
                {
                    if (Logger.IsInfoEnabled)
                    {
                        Logger.Info($"Failed to DoOAuthRequest to {url} with {apiKey}", ex);
                    }
                    throw;
                }
            }
        }