Beispiel #1
0
        public void a_server_can_accept_repeated_calls()
        {
            using (var subject = new DirectServer(@"C:\Temp\WrappedSites\1_rolling")) // a published site
            {
                var request = new SerialisableRequest {
                    Method     = "GET",
                    RequestUri = "/values",
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    },
                    Content = null
                };

                // The big start-up overhead is in `new DirectServer`. Each `DirectCall` is pretty quick
                var result1 = subject.DirectCall(request);
                var result2 = subject.DirectCall(request);
                var result3 = subject.DirectCall(request);
                var result4 = subject.DirectCall(request);
                var result5 = subject.DirectCall(request);
                var result6 = subject.DirectCall(request);


                Assert.That(result1, Is.Not.Null);
                var resultString = Encoding.UTF8.GetString(result6.Content);
                Assert.That(result6.StatusCode, Is.EqualTo(200), "Unexpected code:" + result6.StatusCode + ". Body = " + resultString);
                Console.WriteLine(resultString);
            }
        }
Beispiel #2
0
        static void Main()
        {
            using (var subject = new DirectServer(@"C:\Temp\WrappedSites_Disabled\no_appins")) // a published site
            {
                var request = new SerialisableRequest {
                    Method     = "GET",
                    RequestUri = "/values",
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    },
                    Content = null
                };

                // Make a whole load of calls for profiling
                int i;
                var dispatcher = Dispatch <SerialisableRequest> .CreateDefaultMultithreaded("LoadTest", 4);

                dispatcher.AddConsumer(rq =>
                {
                    // ReSharper disable once AccessToDisposedClosure
                    var result = subject.DirectCall(request);
                    if (rq.CommandControl != null)
                    {
                        var resultString = Encoding.UTF8.GetString(result?.Content ?? new byte[0]);
                        Console.Write(rq.CommandControl);
                        Console.WriteLine(resultString);
                    }
                });

                var sw = new Stopwatch();
                sw.Start();
                dispatcher.Start();

                for (i = 0; i < 10000; i++)
                {
                    if (i % 100 == 0)
                    {
                        var traceRequest = request.Clone();
                        traceRequest.CommandControl = i.ToString();
                        dispatcher.AddWork(traceRequest);
                    }
                    else
                    {
                        dispatcher.AddWork(request);
                    }
                }
                dispatcher.WaitForEmptyQueueAndStop();  // only call this if you're not filling the queue from elsewhere


                sw.Stop();
                var rate = i / sw.Elapsed.TotalSeconds;
                Console.WriteLine("calls per second: " + rate);



                Console.WriteLine("[Done]");
                Console.ReadLine();
            }
        }
Beispiel #3
0
        /// <summary>
        /// Convert a ASP.Net or HTTP Listener request to a serialisable one
        /// </summary>
        public static SerialisableRequest ConvertToSerialisable(IRequest request)
        {
            var newRq = new SerialisableRequest
            {
                IsSecureConnection = request.IsSecureConnection,
                Content            = GetBytes(request.InputStream),
                Method             = request.HttpMethod,
                RequestUri         = request.Url.PathAndQuery,
                Headers            = MapHeadersToDict(request.Headers)
            };

            return(newRq);
        }
Beispiel #4
0
        public void ViewStatusTest()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src";

            using (var server = new DirectServer(path))
            {
                var request = new SerialisableRequest
                {
                    Method     = "GET",
                    RequestUri = "/metadata",
                    Content    = null
                };
                var result = server.DirectCall(request);
                Assert.That(result.StatusCode, Is.EqualTo(200));
            }
        }
Beispiel #5
0
        /// <summary>
        /// Handle an incoming request using the hosted site
        /// </summary>
        public SerialisableResponse Request(SerialisableRequest request)
        {
            Interlocked.Increment(ref _callCount);
            var response = HostedSite.DirectCall(request);

            if (response.StatusCode > 499)
            {
                Interlocked.Increment(ref _failureCount);
                FailureHistory.Record();
            }
            else
            {
                SuccessHistory.Record();
            }

            return(response);
        }
Beispiel #6
0
        public void can_pass_null_headers()
        {
            using (var subject = new DirectServer(@"C:\Temp\WrappedSites\1_rolling")) // a published site
            {
                var request = new SerialisableRequest {
                    Method     = "GET",
                    RequestUri = "/values",
                    Headers    = null,
                    Content    = null
                };
                var result = subject.DirectCall(request);


                Assert.That(result, Is.Not.Null);
                var resultString = Encoding.UTF8.GetString(result.Content);
                Assert.That(result.StatusCode, Is.EqualTo(200), "Unexpected code:" + result.StatusCode + ". Body = " + resultString);
                Console.WriteLine(resultString);
            }
        }
Beispiel #7
0
        public void FileTreeStatusCodeTest()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src";

            using (var server = new DirectServer(path))
            {
                var request = new SerialisableRequest
                {
                    Method     = "POST",
                    RequestUri = "/loadfiletree",
                    Content    = null,
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    }
                };

                var result = server.DirectCall(request);
                Assert.That(result.StatusCode, Is.EqualTo(200));
            }
        }
Beispiel #8
0
        private void WarmAndTest()
        {
            // Give the site an initial kick, so it's warm when it goes into the version table
            var healthRequest = new SerialisableRequest
            {
                Headers = new Dictionary <string, string> {
                    { "Accept", "text/plain,application/json" }
                },
                Method     = "GET",
                RequestUri = "/health"
            };
            var result = HostedSite.DirectCall(healthRequest);

            if (result.StatusCode > 499)
            {
                // We don't care about 'bad request' or 'file not found', in case the health endpoint is not implemented
                // However, if the site fails we will entirely reject this version
                HostedSite.Dispose();
                throw new WarmupCallException("Version wake-up failed: v" + MajorVersion + " at " + TargetPath + "; " + result.StatusCode + " " + result.StatusMessage);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Create a connection for a single serialised request
        /// </summary>
        public MemoryConnection(SerialisableRequest request)
        {
            _request = request;
            if (_request.Headers == null)
            {
                _request.Headers = new Dictionary <string, string>();
            }

            _headersRead = false;

            Id       = Guid.Empty;
            LocalIP  = UnknownLocalIP;
            RemoteIP = UnknownRemoteIP;

            _resultBody = new MemoryStream();
            _result     = new SerialisableResponse {
                Headers       = new Dictionary <string, string[]>(),
                StatusCode    = 200,
                StatusMessage = DefaultStatusMessage
            };
        }
        public void FileTreeDataTest()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src";

            using (var server = new DirectServer(path))
            {
                var request = new SerialisableRequest
                {
                    Method     = "POST",
                    RequestUri = "/viewer/loadfiletree",
                    Content    = null,
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    }
                };

                var     result       = server.DirectCall(request);
                var     resultString = Encoding.UTF8.GetString(result.Content);
                dynamic data         = JsonConvert.DeserializeObject(resultString);
                Assert.IsTrue(data.Count == 0);
            }
        }
Beispiel #11
0
        public void FileTreeStatusCodeTest()
        {
            string path = AppDomain.CurrentDomain.BaseDirectory + "/../../../src";

            using (var server = new DirectServer(path))
            {
                PostedDataEntity requestData = new PostedDataEntity();
                requestData.path = "";

                var request = new SerialisableRequest
                {
                    Method     = "POST",
                    RequestUri = "/editor/loadfiletree",
                    Content    = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(requestData)),
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" },
                        { "Content-Length", JsonConvert.SerializeObject(requestData).Length.ToString() }
                    }
                };

                var result = server.DirectCall(request);
                Assert.That(result.StatusCode, Is.EqualTo(200));
            }
        }
Beispiel #12
0
 /// <summary>
 /// Wrap a request object
 /// </summary>
 public SerialisableRequestWrapper(SerialisableRequest request)
 {
     _request = request;
     Headers  = new DictionaryHeaderWrapper(request.Headers);
 }
Beispiel #13
0
        private static void SendApiSpecForVersion(IContext context, VersionTable <SiteHost> versions, string requestedVersion)
        {
            var result = versions.GetExactVersion(requestedVersion);
            var sb     = new StringBuilder(1024);

            if (result.IsFailure)
            {
                // Craft a special response
                AppendSwaggerErrorMessage(sb, result.FailureCause?.Message ?? "Unknown error");
                SendStringBuilder(context, sb);
                return;
            }
            var major = requestedVersion.Split('-').FirstOrDefault() ?? "0";

            // get a host setting to inject in the swagger
            var redirUri      = new Uri(MainRequestHandler.ExternalEndpoint, UriKind.Absolute);
            var selfAuthority = new Uri(MainRequestHandler.ExternalEndpoint, UriKind.Absolute).Authority;

            if (MainRequestHandler.UpgradeHttp && redirUri.Scheme == "http")
            {
                selfAuthority = redirUri.Host; // configured address would get bounced, to try guess a better uri
            }

            var proxy  = result.ResultData;
            var routes = new[] { "/swagger/docs/v1", "/swagger/v1/swagger.json", "/swagger/docs/v" + major, "/swagger/v" + major + "/swagger.json" }; // we expect the raw swagger JSON to be in one of these paths

            foreach (var route in routes)
            {
                var rq = new SerialisableRequest {
                    Method     = "GET",
                    RequestUri = route,
                    Headers    = new Dictionary <string, string>()
                };
                var tx = proxy.Request(rq);
                if (tx.StatusCode < 299) // found it
                {
                    var spec = Json.DefrostDynamic(Encoding.UTF8.GetString(tx.Content));

                    spec.host         = selfAuthority;
                    spec.info.version = requestedVersion;

                    if (MainRequestHandler.UpgradeHttp)
                    {
                        spec.schemes = new[] { "https" };
                    }
                    else if (MainRequestHandler.HttpsAvailable)
                    {
                        spec.schemes = new[] { "http", "https" };
                    }
                    else
                    {
                        spec.schemes = new[] { "http" };
                    }

                    spec.securityDefinitions = new Dictionary <string, object> {
                        { "Bearer Token", new { type = "apiKey", name = "Authorization", @in = "header" } }
                    };

                    spec.security = new[] {
                        new Dictionary <string, object> {
                            { "Bearer Token", new object[0] }
                        }
                    };

                    sb.Append(Json.Freeze(spec));

                    SendStringBuilder(context, sb);
                    return;
                }
            }

            AppendSwaggerErrorMessage(sb, "Failed to find a JSON endpoint in the hosted API. Make sure that hosted APIs respond to one of:<br/>" + string.Join("<br/>", routes));
            SendStringBuilder(context, sb);
        }
Beispiel #14
0
        /// <summary>
        /// Create a new context for an incoming serialisable request
        /// </summary>
        public SerialisableContext(SerialisableRequest request)
        {
            Request = new SerialisableRequestWrapper(request);

            Response = new SerialisableResponseWrapper(SerialisableResponse.CreateEmpty());
        }
Beispiel #15
0
        public static void HandleHttpRequestCallback(
            #region params
            IntPtr conn,
            [MarshalAs(UnmanagedType.LPStr)] string verb,
            [MarshalAs(UnmanagedType.LPStr)] string query,
            [MarshalAs(UnmanagedType.LPStr)] string pathInfo,
            [MarshalAs(UnmanagedType.LPStr)] string pathTranslated,
            [MarshalAs(UnmanagedType.LPStr)] string contentType,

            Int32 bytesDeclared,
            Int32 bytesAvailable, // if available < declared, you need to run `readClient` to get more
            IntPtr data,          // first blush of data, if any

            GetServerVariableDelegate getServerVariable, WriteClientDelegate writeClient, ReadClientDelegate readClient, IntPtr serverSupport)
        #endregion
        {
            try
            {
                if (_proxy == null)
                {
                    _proxy = new DirectServer("C:\\Temp\\WrappedSites\\1_rolling");
                }
                var headerString = TryGetHeaders(conn, getServerVariable);

                var physicalPath = TryGetPhysPath(conn, getServerVariable);

                var head = T.g("head")[T.g("title")[".Net Output"]];

                var body = T.g("body")[
                    T.g("h1")["Hello"],
                    T.g("p")[".Net here!"],
                    T.g("p")["You called me with these properties:"],

                    T.g("dl")[
                        Def("Verb", verb),
                        Def("Query string", query),
                        Def("URL path", pathInfo),
                        Def("Equivalent file path", pathTranslated),
                        Def("App physical path", physicalPath),
                        Def("Requested content type", contentType)
                    ],

                    T.g("p")["Request headers: ",
                             T.g("pre")[headerString]
                    ],

                    T.g("p")["Client supplied " + bytesAvailable + " bytes out of an expected " + bytesDeclared + " bytes"]
                           ];

                var rq = new SerialisableRequest();
                rq.Headers    = SplitToDict(headerString);
                rq.Method     = verb;
                rq.RequestUri = pathInfo;
                if (!string.IsNullOrWhiteSpace(query))
                {
                    rq.RequestUri += "?" + query;
                }
                rq.Content = ReadAllContent(conn, bytesAvailable, bytesDeclared, data, readClient);

                var tx = _proxy.DirectCall(rq);


                // spit out the Huygens response
                if (tx != null)
                {
                    body.Add(T.g("hr/"));

                    var responseHeaderList = T.g("dl");
                    foreach (var header in tx.Headers)
                    {
                        responseHeaderList.Add(Def(header.Key, string.Join(",", header.Value)));
                    }
                    body.Add(
                        T.g("h2")["Huygen proxy response:"],
                        T.g("p")["Headers:"],
                        responseHeaderList,
                        T.g("p")["Status: ", tx.StatusCode + " ", tx.StatusMessage],
                        T.g("p")["Response data (as utf8 string):"],
                        T.g("pre")[Encoding.UTF8.GetString(tx.Content)]
                        );
                }

                var page = T.g("html")[head, body];

                var ms = new MemoryStream();
                page.StreamTo(ms, Encoding.UTF8);
                ms.WriteByte(0);
                ms.Seek(0, SeekOrigin.Begin);
                var msg = ms.ToArray();
                int len = msg.Length;

                TryWriteHeaders(conn, serverSupport);
                writeClient(conn, msg, ref len, 0);
            }
            catch (Exception ex)
            {
                var ms    = new MemoryStream();
                var bytes = Encoding.UTF8.GetBytes("<pre>" + ex + "</pre>");
                ms.Write(bytes, 0, bytes.Length);
                ms.WriteByte(0);
                ms.Seek(0, SeekOrigin.Begin);
                var msg = ms.ToArray();
                int len = msg.Length;

                TryWriteHeaders(conn, serverSupport);
                writeClient(conn, msg, ref len, 0);
            }
        }