/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; if(args.PathAndFile.Equals("/AircraftList.json", StringComparison.OrdinalIgnoreCase)) result = HandleAircraftListJson(args, BaseStationAircraftList, false); else if(args.PathAndFile.Equals("/FlightSimList.json", StringComparison.OrdinalIgnoreCase)) result = HandleAircraftListJson(args, FlightSimulatorAircraftList, true); return result; }
/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; if(args.PathAndFile.Equals("/favicon.ico", StringComparison.OrdinalIgnoreCase)) { result = true; Responder.SendBinary(args.Response, _Icon, MimeType.IconImage); args.Classification = ContentClassification.Other; } return result; }
/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; if(!args.IsInternetRequest || _InternetClientCanRequestAudio) { if(args.PathAndFile.Equals("/Audio", StringComparison.OrdinalIgnoreCase)) { string command = (string)args.QueryString["cmd"]; if(command != null && command.Equals("say", StringComparison.OrdinalIgnoreCase)) { var text = args.QueryString["line"]; if(text != null) { result = true; IAudio audio = Factory.Singleton.Resolve<IAudio>(); Responder.SendAudio(args.Response, audio.SpeechToWavBytes(text), MimeType.WaveAudio); args.Classification = ContentClassification.Audio; } } } } return result; }
public void RequestReceivedEventArgs_Constructor_Builds_Properties_From_Request_Correctly() { ExcelWorksheetData worksheet = new ExcelWorksheetData(TestContext); var request = new Mock<IRequest>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var response = new Mock<IResponse>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var headers = new NameValueCollection(); var endPoint = new IPEndPoint(IPAddress.Parse(worksheet.String("ResponseAddress")), 45678); request.Setup(r => r.RemoteEndPoint).Returns(endPoint); request.Setup(r => r.Url).Returns(new Uri(worksheet.EString("Url"))); request.Setup(r => r.RawUrl).Returns(worksheet.EString("RawUrl")); request.Setup(r => r.Headers).Returns(headers); var xForwardedFor = worksheet.EString("XForwardedFor"); if(xForwardedFor != null) headers.Add("X-Forwarded-For", xForwardedFor); var args = new RequestReceivedEventArgs(request.Object, response.Object, worksheet.EString("Root")); Assert.AreEqual(worksheet.EString("WebSite"), args.WebSite); Assert.AreEqual(worksheet.EString("PathAndFile"), args.PathAndFile); Assert.AreEqual(worksheet.EString("File"), args.File); Assert.AreEqual(worksheet.EString("ProxyAddress"), args.ProxyAddress); Assert.AreEqual(worksheet.EString("ClientAddress"), args.ClientAddress); Assert.AreEqual(worksheet.Bool("IsInternetRequest"), args.IsInternetRequest); Assert.AreEqual(worksheet.Int("PathCount"), args.PathParts.Count); Assert.AreEqual(worksheet.Int("QueryCount"), args.QueryString.Count); for(var i = 0;i < args.PathParts.Count;++i) { Assert.AreEqual(worksheet.EString(String.Format("Path{0}", i)), args.PathParts[i]); } for(var i = 0;i < args.QueryString.Count;++i) { var expectedName = worksheet.String(String.Format("QueryName{0}", i)); var expectedValue = worksheet.String(String.Format("QueryValue{0}", i)); Assert.AreEqual(expectedValue, args.QueryString[expectedName]); } }
public void RequestReceivedEventArgs_Constructor_Initialises_To_Known_State() { var request = new Mock<IRequest>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var response = new Mock<IResponse>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var endPoint = new IPEndPoint(new IPAddress(0x0100007f), 80); request.Setup(r => r.RemoteEndPoint).Returns(endPoint); RequestReceivedEventArgs args = new RequestReceivedEventArgs(request.Object, response.Object, "/Root"); Assert.AreSame(request.Object, args.Request); Assert.AreSame(response.Object, args.Response); Assert.AreEqual("/Root", args.Root); Assert.AreEqual(0, args.QueryString.Count); Assert.IsNull(args.ProxyAddress); Assert.AreEqual("127.0.0.1", args.ClientAddress); Assert.AreEqual(false, args.IsIPad); Assert.AreEqual(false, args.IsIPhone); Assert.AreEqual(false, args.IsAndroid); Assert.AreEqual(false, args.IsIPod); TestUtilities.TestProperty(args, "Handled", false); TestUtilities.TestProperty(args, "Classification", ContentClassification.Other, ContentClassification.Image); }
/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; var key = args.PathAndFile.ToUpper(); if(key == "/") { switch(args.Request.Url.Scheme) { case "http": case "https": int defaultPort = args.Request.Url.Scheme == "http" ? 80 : 443; string redirectUrl = String.Format("{0}{1}{2}", args.Request.Url.AbsoluteUri, args.Request.Url.AbsoluteUri.EndsWith("/") ? "" : "/", args.IsAndroid || args.IsIPad || args.IsIPhone || args.IsIPod ? "iPhoneMap.htm" : "GoogleMap.htm"); result = true; args.Response.Redirect(redirectUrl); break; default: break; } } else { Content content; result = _PathAndFileToContentMap.TryGetValue(key, out content); if(result) { string text = content.Text; if(key == "/SERVERCONFIG.JS") { text = text.Replace("__IS_LOCAL_ADDRESS", args.IsInternetRequest ? "false" : "true"); } Responder.SendText(args.Response, text, Encoding.UTF8, content.MimeType); args.Classification = ContentClassification.Html; } } return result; }
private void TranscribeDatabaseRecordsToJson(List<BaseStationFlight> dbFlights, List<ReportFlightJson> jsonFlights, List<ReportAircraftJson> jsonAircraft, List<ReportAirportJson> jsonAirports, List<ReportRouteJson> jsonRoutes, RequestReceivedEventArgs args, Parameters parameters) { var aircraftIdMap = new Dictionary<int, int>(); var airportMap = new Dictionary<string, int>(); var routeMap = new Dictionary<string, int>(); int rowNumber = parameters.FromRow < 1 ? 1 : parameters.FromRow; foreach(var dbFlight in dbFlights) { var jsonFlight = AddReportFlightJson(dbFlight, jsonFlights, ref rowNumber); if(jsonAircraft != null) { var dbAircraft = dbFlight.Aircraft; if(dbAircraft == null) { jsonFlight.AircraftIndex = jsonAircraft.Count; jsonAircraft.Add(new ReportAircraftJson() { IsUnknown = true }); } else { int aircraftIndex; if(!aircraftIdMap.TryGetValue(dbAircraft.AircraftID, out aircraftIndex)) { aircraftIndex = jsonAircraft.Count; aircraftIdMap.Add(dbAircraft.AircraftID, aircraftIndex); jsonAircraft.Add(CreateReportAircraftJson(dbAircraft, args)); } jsonFlight.AircraftIndex = aircraftIndex; } } int routeIndex = -1; if(!String.IsNullOrEmpty(dbFlight.Callsign) && !routeMap.TryGetValue(dbFlight.Callsign, out routeIndex)) { var sdmRoute = StandingDataManager.FindRoute(dbFlight.Callsign); if(sdmRoute == null) routeIndex = -1; else { var jsonRoute = new ReportRouteJson() { FromIndex = BuildAirportJson(sdmRoute.From, airportMap, jsonAirports), ToIndex = BuildAirportJson(sdmRoute.To, airportMap, jsonAirports), }; foreach(var stopover in sdmRoute.Stopovers) { int index = BuildAirportJson(stopover, airportMap, jsonAirports); if(index != -1) jsonRoute.StopoversIndex.Add(index); } routeIndex = jsonRoutes.Count; jsonRoutes.Add(jsonRoute); routeMap.Add(dbFlight.Callsign, routeIndex); } } jsonFlight.RouteIndex = routeIndex; } }
/// <summary> /// Raised by the provider when a new request is received from the user. /// </summary> /// <param name="asyncResult"></param> private void GetContextHandler(IAsyncResult asyncResult) { if(Provider.IsListening) { bool providerIsStable = true; IContext context = null; try { context = Provider.EndGetContext(asyncResult); } catch(HttpListenerException ex) { // These are just discarded, they're usually disconnections by the user made before we can process the request Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); } catch(ObjectDisposedException ex) { // These are usually thrown during program shutdown, after the provider has gone away but while requests are outstanding Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); providerIsStable = false; } catch(Exception ex) { Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); OnExceptionCaught(new EventArgs<Exception>(ex)); providerIsStable = false; } try { if(providerIsStable) Provider.BeginGetContext(GetContextHandler); } catch(HttpListenerException ex) { // These can be thrown if the server is taken offline between the EndGetContext above and this BeginGetContext Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); context = null; } catch(ObjectDisposedException ex) { // These are usually thrown during program shutdown for the same reasons that EndGetContext can throw them Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); context = null; } catch(InvalidOperationException ex) { // These are thrown when the provider is taken offline between the check above for Provider.IsListening and // the call to BeginGetContext Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); context = null; } catch(Exception ex) { Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); OnExceptionCaught(new EventArgs<Exception>(ex)); context = null; } if(context != null) { try { var requestArgs = new RequestReceivedEventArgs(context.Request, context.Response, Root); if(Authenticated(context)) { var startTime = Provider.UtcNow; OnBeforeRequestReceived(requestArgs); OnRequestReceived(requestArgs); OnAfterRequestReceived(requestArgs); if(!requestArgs.Handled) context.Response.StatusCode = HttpStatusCode.NotFound; var fullClientAddress = String.Format("{0}:{1}", requestArgs.ClientAddress, context.Request.RemoteEndPoint.Port); var responseArgs = new ResponseSentEventArgs(requestArgs.PathAndFile, fullClientAddress, requestArgs.ClientAddress, context.Response.ContentLength, requestArgs.Classification, context.Request, (int)context.Response.StatusCode, (int)(Provider.UtcNow - startTime).TotalMilliseconds); OnResponseSent(responseArgs); } } catch(HttpListenerException ex) { // These are usually thrown when the browser disconnects while the event handler tries to send data to it. You can get a lot // of these, we just discard them to prevent them spamming logs or the display with messages we can't do anything about. Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); } catch(Exception ex) { Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); OnExceptionCaught(new EventArgs<Exception>(ex)); } try { context.Response.OutputStream.Close(); } catch(Exception ex) { // We can get a lot of exceptions from closing the stream if the client browser has disconnected, it's exception spam. Debug.WriteLine(String.Format("WebServer.GetContextHandler caught exception {0}", ex.ToString())); } } } }
/// <summary> /// Returns the type of JSON that the report implies should be returned. The function tries /// not to throw any exceptions. /// </summary> /// <param name="args"></param> /// <returns></returns> private Type ExpectedJsonType(RequestReceivedEventArgs args) { Type result = typeof(AircraftReportJson); var reportType = args.QueryString["rep"]; if(!String.IsNullOrEmpty(reportType)) { switch(reportType.ToUpper()) { case "DATE": result = typeof(FlightReportJson); break; } } return result; }
/// <summary> /// Extracts the parameters from the query string portion of the URL. /// </summary> /// <param name="args"></param> /// <returns></returns> private Parameters ExtractParameters(RequestReceivedEventArgs args) { var result = new Parameters() { ReportType = QueryString(args, "rep", true), FromRow = QueryInt(args, "fromrow", -1), ToRow = QueryInt(args, "torow", -1), SortField1 = QueryString(args, "sort1", false), SortField2 = QueryString(args, "sort2", false), SortAscending1 = QueryString(args, "sort1dir", true) != "DESC", SortAscending2 = QueryString(args, "sort2dir", true) != "DESC", Callsign = QueryString(args, "callsign", true), Country = QueryString(args, "country", false), FromDate = QueryDate(args, "fromdate", DateTime.MinValue, false, true), Icao = QueryString(args, "icao", true), IsEmergency = QueryBool(args, "isemergency", false), Operator = QueryString(args, "operator", false), Registration = QueryString(args, "reg", true), ToDate = QueryDate(args, "todate", DateTime.MaxValue, false, true), IsMilitary = QueryBool(args, "isMilitary", false), WakeTurbulenceCategory = QueryNEnum<WakeTurbulenceCategory>(args, "wtc"), Species = QueryNEnum<Species>(args, "species"), }; if(result.ToDate < result.FromDate) { var fromDate = result.FromDate; result.FromDate = result.ToDate; result.ToDate = fromDate; } return result; }
/// <summary> /// Extracts information about the required image from the URL. /// </summary> /// <param name="args"></param> /// <returns></returns> private ImageRequest ExtractImageRequest(RequestReceivedEventArgs args) { bool isValid = true; ImageRequest result = new ImageRequest() { ImageName = Path.GetFileNameWithoutExtension(args.File).ToUpper(), }; switch(Path.GetExtension(args.File).ToUpper()) { case ".PNG": result.ImageFormat = ImageFormat.Png; break; case ".GIF": result.ImageFormat = ImageFormat.Gif; break; case ".BMP": result.ImageFormat = ImageFormat.Bmp; break; default: isValid = false; break; } foreach(var pathPart in args.PathParts) { var caselessPart = pathPart.ToUpper(); if(caselessPart.StartsWith("ALT-")) result.ShowAltitudeStalk = true; if(caselessPart.StartsWith("ROTATE-")) result.RotateDegrees = ParseDouble(pathPart.Substring(7), 0.0, 359.99); else if(caselessPart.StartsWith("HGHT-")) result.Height = ParseInt(pathPart.Substring(5), 0, 4096); else if(caselessPart.StartsWith("WDTH-")) result.Width = ParseInt(pathPart.Substring(5), 0, 4096); else if(caselessPart.StartsWith("CENX-")) result.CentreX = ParseInt(pathPart.Substring(5), 0, 4096); else if(caselessPart.StartsWith("FILE-")) result.File = pathPart.Substring(5).Replace("\\", ""); else if(caselessPart.StartsWith("SIZE-")) result.Size = ParseStandardSize(pathPart.Substring(5)); else if(caselessPart.StartsWith("PL1-")) result.TextLines[0] = pathPart.Substring(4); else if(caselessPart.StartsWith("PL2-")) result.TextLines[1] = pathPart.Substring(4); else if(caselessPart.StartsWith("PL3-")) result.TextLines[2] = pathPart.Substring(4); } switch(result.ImageName) { case "AIRPLANE": case "AIRPLANESELECTED": result.CentreImageVertically = false; break; } return isValid ? result : null; }
/// <summary> /// Creates the JSON for a report that describes a single aircraft and the flights it has undertaken. /// </summary> /// <param name="args"></param> /// <param name="parameters"></param> /// <param name="findByIcao"></param> /// <returns></returns> private AircraftReportJson CreateSingleAircraftReport(RequestReceivedEventArgs args, Parameters parameters, bool findByIcao) { AircraftReportJson json = new AircraftReportJson() { CountRows = 0, GroupBy = "", }; var aircraftIdentifier = findByIcao ? parameters.Icao : parameters.Registration; if(!String.IsNullOrEmpty(aircraftIdentifier)) { var aircraft = findByIcao ? BaseStationDatabase.GetAircraftByCode(aircraftIdentifier) : BaseStationDatabase.GetAircraftByRegistration(aircraftIdentifier); if(aircraft != null) { // Remove all criteria that is used to identify an aircraft parameters.Icao = null; parameters.Registration = null; parameters.Operator = null; parameters.Country = null; json.Aircraft = CreateReportAircraftJson(aircraft, args); json.CountRows = BaseStationDatabase.GetCountOfFlightsForAircraft(aircraft, parameters); var dbFlights = BaseStationDatabase.GetFlightsForAircraft(aircraft, parameters, parameters.FromRow, parameters.ToRow, parameters.SortField1, parameters.SortAscending1, parameters.SortField2, parameters.SortAscending2); TranscribeDatabaseRecordsToJson(dbFlights, json.Flights, null, json.Airports, json.Routes, args, parameters); } } if(json.Aircraft == null) { json.Aircraft = new ReportAircraftJson() { IsUnknown = true, }; } return json; }
public void RequestReceivedEventArgs_Can_Interpret_User_Agent_Correctly() { var worksheet = new ExcelWorksheetData(TestContext); var request = new Mock<IRequest>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var response = new Mock<IResponse>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); request.Setup(r => r.RemoteEndPoint).Returns(new IPEndPoint(IPAddress.Parse("1.2.3.4"), 80)); request.Setup(r => r.Url).Returns(new Uri("http://127.0.0.1/Root/Whatever")); request.Setup(r => r.RawUrl).Returns("/Root/Whatever"); request.Setup(r => r.UserAgent).Returns(worksheet.String("UserAgent")); var args = new RequestReceivedEventArgs(request.Object, response.Object, "/Root"); Assert.AreEqual(worksheet.Bool("IsAndroid"), args.IsAndroid); Assert.AreEqual(worksheet.Bool("IsIpad"), args.IsIPad); Assert.AreEqual(worksheet.Bool("IsIPhone"), args.IsIPhone); Assert.AreEqual(worksheet.Bool("IsIPod"), args.IsIPod); }
/// <summary> /// Raises <see cref="RequestReceived"/>. /// </summary> /// <param name="args"></param> private void OnRequestReceived(RequestReceivedEventArgs args) { if(RequestReceived != null) RequestReceived(this, args); }
/// <summary> /// Creates an object that holds all of the aircraft list arguments that were extracted from the request. /// </summary> /// <param name="args"></param> /// <param name="aircraftList"></param> /// <param name="isFlightSimulator"></param> /// <returns></returns> private AircraftListJsonBuilderArgs ConstructBuildArgs(RequestReceivedEventArgs args, IAircraftList aircraftList, bool isFlightSimulator) { var result = new AircraftListJsonBuilderArgs() { AircraftList = aircraftList, BrowserLatitude = QueryNDouble(args, "lat"), BrowserLongitude = QueryNDouble(args, "lng"), Filter = isFlightSimulator ? null : ConstructFilter(args), IsFlightSimulatorList = isFlightSimulator, IsInternetClient = args.IsInternetRequest, PreviousDataVersion = QueryLong(args, "ldv", -1), ResendTrails = QueryString(args, "refreshTrails", false) == "1", ShowShortTrail = QueryString(args, "trFmt", true) == "S", }; for(int sortColumnCount = 0;sortColumnCount < 2;++sortColumnCount) { var sortColumn = QueryString(args, String.Format("sortBy{0}", sortColumnCount + 1), true); var sortOrder = QueryString(args, String.Format("sortOrder{0}", sortColumnCount + 1), true); if(String.IsNullOrEmpty(sortColumn) || String.IsNullOrEmpty(sortOrder)) break; result.SortBy.Add(new KeyValuePair<string,bool>(sortColumn, sortOrder == "ASC")); } if(result.SortBy.Count == 0) result.SortBy.Add(new KeyValuePair<string,bool>(AircraftComparerColumn.FirstSeen, false)); var previousAircraftIds = args.Request.Headers["X-VirtualRadarServer-AircraftIds"]; if(!String.IsNullOrEmpty(previousAircraftIds)) { var decodedPreviousAircraftIds = HttpUtility.UrlDecode(previousAircraftIds); foreach(var chunk in decodedPreviousAircraftIds.Split(',')) { int id; if(int.TryParse(chunk, out id)) result.PreviousAircraft.Add(id); } } return result; }
/// <summary> /// Handles the request for content by a server. /// </summary> /// <param name="sender"></param> /// <param name="args"></param> private void Server_RequestReceived(object sender, RequestReceivedEventArgs args) { foreach(var page in _Pages) { page.HandleRequest(sender, args); } }
public void RequestReceivedEventArgs_Is_Case_Insensitive_When_Looking_For_Reverse_Proxy_Headers() { var request = new Mock<IRequest>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var response = new Mock<IResponse>() { DefaultValue = DefaultValue.Mock }.SetupAllProperties(); var headers = new NameValueCollection(); request.Setup(r => r.RemoteEndPoint).Returns(new IPEndPoint(IPAddress.Parse("192.168.0.1"), 1234)); request.Setup(r => r.Url).Returns(new Uri("http://192.168.0.2/Root/")); request.Setup(r => r.RawUrl).Returns("http://192.168.0.2/Root/"); request.Setup(r => r.Headers).Returns(headers); headers.Add("x-forwarded-for", "1.2.3.4"); var args = new RequestReceivedEventArgs(request.Object, response.Object, "/Root"); Assert.AreEqual("192.168.0.1", args.ProxyAddress); Assert.AreEqual("1.2.3.4", args.ClientAddress); Assert.AreEqual(true, args.IsInternetRequest); }
/// <summary> /// Sends the appropriate AircraftList.json content in response to the request passed across. /// </summary> /// <param name="args"></param> /// <param name="aircraftList"></param> /// <param name="isFlightSimulator"></param> /// <returns>Always returns true - this just helps to make the caller's code a little more compact.</returns> private bool HandleAircraftListJson(RequestReceivedEventArgs args, IAircraftList aircraftList, bool isFlightSimulator) { if(_Builder == null) _Builder = new AircraftListJsonBuilder(Provider); if(aircraftList == null) args.Response.StatusCode = HttpStatusCode.InternalServerError; else { var buildArgs = ConstructBuildArgs(args, aircraftList, isFlightSimulator); var json = _Builder.Build(buildArgs); Responder.SendJson(args.Response, json, args.QueryString["callback"]); args.Classification = ContentClassification.Json; } return true; }
/// <summary> /// Extract the filter arguments from the request and returns them collected into an object. /// </summary> /// <param name="args"></param> /// <returns></returns> private AircraftListJsonBuilderFilter ConstructFilter(RequestReceivedEventArgs args) { var result = new AircraftListJsonBuilderFilter() { AltitudeLower = QueryNInt(args, "fAltL"), AltitudeUpper = QueryNInt(args, "fAltU"), CallsignContains = QueryString(args, "fCall", true), DistanceLower = QueryNDouble(args, "fDstL"), DistanceUpper = QueryNDouble(args, "fDstU"), EngineTypeEquals = QueryNEnum<EngineType>(args, "fEgt"), Icao24CountryContains = QueryString(args, "fCou", true), IsInterestingEquals = QueryNBool(args, "fInt"), IsMilitaryEquals = QueryNBool(args, "fMil"), MustTransmitPosition = QueryNBool(args, "fNoPos") ?? false, OperatorContains = QueryString(args, "fOp", true), RegistrationContains = QueryString(args, "fReg", true), SpeciesEquals = QueryNEnum<Species>(args, "fSpc"), SquawkLower = QueryNInt(args, "fSqkL"), SquawkUpper = QueryNInt(args, "fSqkU"), TypeStartsWith = QueryString(args, "fTyp", true), WakeTurbulenceCategoryEquals = QueryNEnum<WakeTurbulenceCategory>(args, "fWtc"), }; double? northBounds = QueryNDouble(args, "fNBnd"); double? eastBounds = QueryNDouble(args, "fEBnd"); double? southBounds = QueryNDouble(args, "fSBnd"); double? westBounds = QueryNDouble(args, "fWBnd"); if(northBounds != null && southBounds != null && westBounds != null && eastBounds != null) { result.PositionWithin = new Pair<Coordinate>( new Coordinate((float)northBounds, (float)westBounds), new Coordinate((float)southBounds, (float)eastBounds) ); } return result; }
/// <summary> /// Raises <see cref="AfterRequestReceived"/>. /// </summary> /// <param name="args"></param> private void OnAfterRequestReceived(RequestReceivedEventArgs args) { if(AfterRequestReceived != null) AfterRequestReceived(this, args); }
/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; if(args.PathAndFile.StartsWith("/Images/", StringComparison.OrdinalIgnoreCase)) { var imageRequest = ExtractImageRequest(args); result = imageRequest != null; // Stock image is an image from the resource file. We don't need to dispose of it, it can be reused // Temp image is an image we have either built from scratch or built by modifying a stock image. It is only // good for this request and needs to be disposed of when we're done with it. Image stockImage = null; Image tempImage = null; if(result) { if(_ForceSingleThreadAccess) Monitor.Enter(_ForceSingleThreadAccessLock); try { result = BuildInitialImage(imageRequest, args, ref stockImage, ref tempImage); if(result) { var addTextLines = imageRequest.HasTextLines && (!args.IsInternetRequest || _InternetClientCanShowText); if(imageRequest.RotateDegrees > 0.0) tempImage = UseImage(tempImage, RotateImage(tempImage ?? stockImage, imageRequest.RotateDegrees.Value)); if(imageRequest.Width != null) tempImage = UseImage(tempImage, WidenImage(tempImage ?? stockImage, imageRequest.Width.Value, imageRequest.CentreImageHorizontally)); if(imageRequest.ShowAltitudeStalk) tempImage = UseImage(tempImage, AddAltitudeStalk(tempImage ?? stockImage, imageRequest.Height.GetValueOrDefault(), imageRequest.CentreX.GetValueOrDefault())); else if(imageRequest.Height != null) tempImage = UseImage(tempImage, HeightenImage(tempImage ?? stockImage, imageRequest.Height.Value, imageRequest.CentreImageVertically)); if(addTextLines) tempImage = UseImage(tempImage, AddTextLines(tempImage ?? stockImage, imageRequest.TextLines, true)); } if(result) { Responder.SendImage(args.Response, tempImage ?? stockImage, imageRequest.ImageFormat); args.Classification = ContentClassification.Image; } } finally { if(tempImage != null) tempImage.Dispose(); if(_ForceSingleThreadAccess) Monitor.Exit(_ForceSingleThreadAccessLock); } } } return result; }
/// <summary> /// Raises <see cref="BeforeRequestReceived"/>. /// </summary> /// <param name="args"></param> private void OnBeforeRequestReceived(RequestReceivedEventArgs args) { if(BeforeRequestReceived != null) BeforeRequestReceived(this, args); }
/// <summary> /// Creates the JSON representation of an aircraft. /// </summary> /// <param name="aircraft"></param> /// <param name="args"></param> /// <returns></returns> private ReportAircraftJson CreateReportAircraftJson(BaseStationAircraft aircraft, RequestReceivedEventArgs args) { var result = new ReportAircraftJson() { AircraftClass = aircraft.AircraftClass, AircraftId = aircraft.AircraftID, CofACategory = aircraft.CofACategory, CofAExpiry = aircraft.CofAExpiry, Country = aircraft.Country, CurrentRegDate = aircraft.CurrentRegDate, DeRegDate = aircraft.DeRegDate, FirstRegDate = aircraft.FirstRegDate, GenericName = aircraft.GenericName, IcaoTypeCode = aircraft.ICAOTypeCode, InfoUrl = aircraft.InfoUrl, Manufacturer = aircraft.Manufacturer, Icao = aircraft.ModeS, ModeSCountry = aircraft.ModeSCountry, MTOW = aircraft.MTOW, OperatorFlagCode = aircraft.OperatorFlagCode, OwnershipStatus = aircraft.OwnershipStatus, PictureUrl1 = aircraft.PictureUrl1, PictureUrl2 = aircraft.PictureUrl2, PictureUrl3 = aircraft.PictureUrl3, PopularName = aircraft.PopularName, PreviousId = aircraft.PreviousID, Registration = aircraft.Registration, RegisteredOwners = aircraft.RegisteredOwners, SerialNumber = aircraft.SerialNo, Status = aircraft.Status, TotalHours = aircraft.TotalHours, Type = aircraft.Type, Notes = aircraft.UserNotes, YearBuilt = aircraft.YearBuilt, HasPicture = args.IsInternetRequest && !_InternetClientCanSeePictures ? false : _PictureManager.FindPicture(_PictureFolderCache, aircraft.ModeS, aircraft.Registration) != null, }; var aircraftType = String.IsNullOrEmpty(aircraft.ICAOTypeCode) ? null : StandingDataManager.FindAircraftType(aircraft.ICAOTypeCode); if(aircraftType != null) { result.WakeTurbulenceCategory = (int)aircraftType.WakeTurbulenceCategory; result.Engines = aircraftType.Engines; result.EngineType = (int)aircraftType.EngineType; result.Species = (int)aircraftType.Species; } var codeBlock = String.IsNullOrEmpty(aircraft.ModeS) ? null : StandingDataManager.FindCodeBlock(aircraft.ModeS); if(codeBlock != null) result.Military = codeBlock.IsMilitary; return result; }
/// <summary> /// Builds up rows for a report that wants information on flights for many aircraft simultaneously. /// </summary> /// <param name="args"></param> /// <param name="parameters"></param> /// <returns></returns> private FlightReportJson CreateManyAircraftReport(RequestReceivedEventArgs args, Parameters parameters) { FlightReportJson json = new FlightReportJson(); json.FromDate = FormatReportDate(parameters.FromDate); json.ToDate = FormatReportDate(parameters.ToDate); bool hasNonDatabaseCriteria = parameters.IsMilitary || parameters.WakeTurbulenceCategory != null || parameters.Species != null; if(!hasNonDatabaseCriteria) json.CountRows = BaseStationDatabase.GetCountOfFlights(parameters); var dbFlights = BaseStationDatabase.GetFlights( parameters, hasNonDatabaseCriteria ? -1 : parameters.FromRow, hasNonDatabaseCriteria ? -1 : parameters.ToRow, parameters.SortField1, parameters.SortAscending1, parameters.SortField2, parameters.SortAscending2); if(hasNonDatabaseCriteria) { dbFlights = dbFlights.Where(f => { bool matches = f.Aircraft != null; if(matches) { if(parameters.IsMilitary) { var codeBlock = StandingDataManager.FindCodeBlock(f.Aircraft.ModeS); matches = matches && codeBlock != null && codeBlock.IsMilitary; } if(parameters.Species != null || parameters.WakeTurbulenceCategory != null) { var aircraftType = StandingDataManager.FindAircraftType(f.Aircraft.ICAOTypeCode); if(parameters.Species != null) matches = matches && aircraftType != null && aircraftType.Species == parameters.Species; if(parameters.WakeTurbulenceCategory != null) matches = matches && aircraftType != null && aircraftType.WakeTurbulenceCategory == parameters.WakeTurbulenceCategory; } } return matches; }).ToList(); json.CountRows = dbFlights.Count; int limit = parameters.ToRow == -1 || parameters.ToRow < parameters.FromRow ? int.MaxValue : (parameters.ToRow - Math.Max(0, parameters.FromRow)) + 1; int offset = parameters.FromRow < 0 ? 0 : parameters.FromRow; dbFlights = dbFlights.Skip(offset).Take(limit).ToList(); } TranscribeDatabaseRecordsToJson(dbFlights, json.Flights, json.Aircraft, json.Airports, json.Routes, args, parameters); return json; }
/// <summary> /// Fills either of the stock image or temporary image parameters with the initial image to use (before any alterations are made). /// </summary> /// <param name="imageRequest"></param> /// <param name="args"></param> /// <param name="stockImage"></param> /// <param name="tempImage"></param> /// <returns></returns> private bool BuildInitialImage(ImageRequest imageRequest, RequestReceivedEventArgs args, ref Image stockImage, ref Image tempImage) { bool result = true; switch(imageRequest.ImageName) { case "AIRPLANE": stockImage = Images.Marker_Airplane; break; case "AIRPLANESELECTED": stockImage = Images.Marker_AirplaneSelected; break; case "BLANK": tempImage = CreateBlankImage(imageRequest.Width.GetValueOrDefault(), imageRequest.Height.GetValueOrDefault()); break; case "CHEVRONBLUECIRCLE": stockImage = Images.ChevronBlueCircle; break; case "CHEVRONGREENCIRCLE": stockImage = Images.ChevronGreenCircle; break; case "CHEVRONREDCIRCLE": stockImage = Images.ChevronRedCircle; break; case "CLOSESLIDER": stockImage = Images.CloseSlider; break; case "COMPASS": stockImage = Images.Compass; break; case "CORNER-TL": stockImage = Images.Corner_TopLeft; break; case "CORNER-TR": stockImage = Images.Corner_TopRight; break; case "CORNER-BL": stockImage = Images.Corner_BottomLeft; break; case "CORNER-BR": stockImage = Images.Corner_BottomRight; break; case "CROSSHAIR": stockImage = Images.Crosshair; break; case "GOTOCURRENTLOCATION": stockImage = Images.GotoCurrentLocation; break; case "HEADING": stockImage = Images.SmallPlaneNorth; break; case "HIDELIST": stockImage = Images.HideList; break; case "IPHONEBACKBUTTON": stockImage = Images.IPhoneBackButton; break; case "IPHONEBLUEBUTTON": stockImage = Images.IPhoneBlueButton; break; case "IPHONECHEVRON": stockImage = Images.IPhoneChevron; break; case "IPHONEGRAYBUTTON": stockImage = Images.IPhoneGrayButton; break; case "IPHONEICON": stockImage = Images.IPhoneIcon; break; case "IPHONELISTGROUP": stockImage = Images.IPhoneListGroup; break; case "IPHONEONOFF": stockImage = Images.IPhoneOnOff; break; case "IPHONEPINSTRIPES": stockImage = Images.IPhonePinstripes; break; case "IPHONESELECTEDTICK": stockImage = Images.IPhoneSelectedTick; break; case "IPHONESELECTION": stockImage = Images.IPhoneSelection; break; case "IPHONESPLASH": tempImage = CreateIPhoneSplash(args.WebSite, args.IsIPad, args.PathParts); break; case "IPHONETOOLBAR": stockImage = Images.IPhoneToolbar; break; case "IPHONETOOLBUTTON": stockImage = Images.IPhoneToolButton; break; case "IPHONEWHITEBUTTON": stockImage = Images.IPhoneWhiteButton; break; case "MINUS": stockImage = Images.Collapse; break; case "MOVINGMAPCHECKED": stockImage = Images.MovingMapChecked; break; case "MOVINGMAPUNCHECKED": stockImage = Images.MovingMapUnchecked; break; case "OPENSLIDER": stockImage = Images.OpenSlider; break; case "OPFLAG": tempImage = CreateLogoImage(imageRequest.File, _OperatorFlagFolder); break; case "PICTURE": tempImage = CreateAirplanePicture(imageRequest.File, imageRequest.Size, args.IsInternetRequest); break; case "PLUS": stockImage = Images.Expand; break; case "ROWHEADER": stockImage = Images.RowHeader; break; case "ROWHEADERSELECTED": stockImage = Images.RowHeaderSelected; break; case "SHOWLIST": stockImage = Images.ShowList; break; case "TESTSQUARE": stockImage = Images.TestSquare;break; case "TRANSPARENT-25": stockImage = Images.Transparent_25; break; case "TRANSPARENT-50": stockImage = Images.Transparent_50; break; case "TYPE": tempImage = CreateLogoImage(imageRequest.File, _SilhouetteFolder); break; case "VOLUME0": stockImage = Images.Volume0; break; case "VOLUME25": stockImage = Images.Volume25; break; case "VOLUME50": stockImage = Images.Volume50; break; case "VOLUME75": stockImage = Images.Volume75; break; case "VOLUME100": stockImage = Images.Volume100; break; case "VOLUMEDOWN": stockImage = Images.VolumeDown; break; case "VOLUMEMUTE": stockImage = Images.VolumeMute; break; case "VOLUMEUP": stockImage = Images.VolumeUp; break; case "YOUAREHERE": stockImage = Images.BlueBall; break; default: result = false; break; } if(result) result = stockImage != null || tempImage != null; return result; }
// Events subscribed private void WebServer_BeforeRequestReceived(object sender, RequestReceivedEventArgs args) { if(_Enabled) { System.Diagnostics.Debug.WriteLine(String.Format("Browser requested {0}", args.Request.RawUrl)); ++_CountRequests; UpdateStatus(); } }
/// <summary> /// See base class. /// </summary> /// <param name="server"></param> /// <param name="args"></param> /// <returns></returns> protected override bool DoHandleRequest(IWebServer server, RequestReceivedEventArgs args) { bool result = false; if(args.PathAndFile.Equals("/ReportRows.json", StringComparison.OrdinalIgnoreCase) && (_InternetClientCanRunReports || !args.IsInternetRequest)) { result = true; ReportRowsJson json = null; var startTime = Provider.UtcNow; Type expectedJsonType = ExpectedJsonType(args); try { var parameters = ExtractParameters(args); LimitDatesWhenNoStrongCriteriaPresent(parameters, args.IsInternetRequest); if(parameters.ToDate.Year != 9999) parameters.ToDate = parameters.ToDate.AddDays(1).AddMilliseconds(-1); switch(parameters.ReportType) { case "DATE": json = CreateManyAircraftReport(args, parameters); break; case "ICAO": json = CreateSingleAircraftReport(args, parameters, true); break; case "REG": json = CreateSingleAircraftReport(args, parameters, false); break; default: throw new NotImplementedException(); } if(json != null) json.GroupBy = parameters.SortField1 ?? parameters.SortField2 ?? ""; } catch(Exception ex) { Debug.WriteLine(String.Format("ReportRowsJsonPage.DoHandleRequest caught exception {0}", ex.ToString())); ILog log = Factory.Singleton.Resolve<ILog>().Singleton; log.WriteLine("An exception was encountered during the processing of a report: {0}", ex.ToString()); if(json == null) json = (ReportRowsJson)Activator.CreateInstance(expectedJsonType); json.ErrorText = String.Format("An exception was encounted during the processing of the report, see log for full details: {0}", ex.Message); } if(json == null) json = (ReportRowsJson)Activator.CreateInstance(expectedJsonType); json.ProcessingTime = String.Format("{0:N3}", (Provider.UtcNow - startTime).TotalSeconds); json.OperatorFlagsAvailable = _ShowOperatorFlags; json.SilhouettesAvailable = _ShowSilhouettes; Responder.SendJson(args.Response, json, null); args.Classification = ContentClassification.Json; } return result; }