/// <summary> /// Handle output from API /// </summary> /// <param name="context"></param> private async Task <bool> PerformOutput(HttpContext context) { //decide correct reponse type IOutputProvider outputProvider = null; var filter = new APIRequestParams(); //set defaults string outputType = "xml"; filter.DistanceUnit = DistanceUnit.Miles; filter.MaxResults = 100; filter.EnableCaching = true; var paramList = new NullSafeDictionary <string, string>(); foreach (var k in context.Request.Query.Keys) { paramList.Add(k.ToLower(), context.Request.Query[k]); } filter.ParseParameters(filter, paramList); if (string.IsNullOrEmpty(filter.APIKey)) { if (context.Request.Headers.ContainsKey("X-API-Key")) { filter.APIKey = context.Request.Headers["X-API-Key"]; } } //override ?v=2 etc if called via /api/v2/ or /api/v1 if (APIBehaviourVersion > 0) { filter.APIVersion = APIBehaviourVersion; } if (APIBehaviourVersion >= 2) { filter.Action = DefaultAction; } try { if ((_settings.IsCacheOnlyMode || context.Request.GetUri().Host.ToLower().StartsWith("api")) && (filter.APIVersion == null || filter.APIVersion == 1)) { //API version is mandatory for api V2 onwards via api.openchargemap.* hostname or for API mirrors operating in cached mode await OutputBadRequestMessage(context, "mandatory API Version not specified in request"); return(true); } } catch (System.UriFormatException) { _logger?.LogWarning("Failed to parse URI " + context.Request.Host.Value); } if (!String.IsNullOrEmpty(context.Request.Query["output"])) { outputType = ParseString(context.Request.Query["output"]).ToLower(); } else { //new default after API V2 is json instead of XML if (filter.APIVersion >= 2) { outputType = "json"; } } //change defaults and override settings for deprecated api features if (filter.APIVersion >= 2) { //the following output types are deprecated and will default as JSON if (outputType == "carwings" || outputType == "rss") { await OutputBadRequestMessage(context, "specified output type not supported in this API version"); return(true); } } if (_settings.IsCacheOnlyMode) { filter.AllowMirrorDB = true; filter.AllowDataStoreDB = false; } if (IsRequestByRobot(context)) { await OutputBadRequestMessage(context, "API requests by robots are temporarily disabled.", statusCode : 503); return(true); } //determine output provider switch (outputType) { case "xml": outputProvider = new XMLOutputProvider(); break; case "carwings": case "rss": outputProvider = new RSSOutputProvider(); if (outputType == "carwings") { ((RSSOutputProvider)outputProvider).EnableCarwingsMode = true; } break; case "json": outputProvider = new JSONOutputProvider(); break; case "geojson": outputProvider = new GeoJSONOutputProvider(); break; case "csv": outputProvider = new CSVOutputProvider(); break; case "kml": outputProvider = new KMLOutputProvider(KMLOutputProvider.KMLVersion.V2); break; default: outputProvider = new XMLOutputProvider(); break; } if (outputProvider != null) { context.Response.ContentType = outputProvider.ContentType; if (filter.Action == "getchargepoints" || filter.Action == "poi") { await OutputPOIList(outputProvider, context, filter); return(true); } if (filter.Action == "getcompactpoilist") { //experimental:: await OutputCompactPOIList(context, filter); return(true); } if (filter.Action == "getcorereferencedata") { await OutputCoreReferenceData(outputProvider, context, filter); return(true); } if (filter.Action == "geocode") { OutputGeocodingResult(outputProvider, context, filter); return(true); } if (filter.Action == "availability") { OutputAvailabilityResult(outputProvider, context, filter); return(true); } if (filter.Action == "profile.authenticate") { await OutputProfileSignInResult(outputProvider, context, filter); return(true); } if (filter.Action == "profile.register") { await OutputProfileRegisterResult(outputProvider, context, filter); return(true); } if (filter.Action == "refreshmirror") { try { var itemsUpdated = await OCM.Core.Data.CacheManager.RefreshCachedData(); await new JSONOutputProvider().GetOutput(context, context.Response.Body, new { POICount = itemsUpdated, Status = "OK" }, filter); return(true); } catch (Exception exp) { await new JSONOutputProvider().GetOutput(context, context.Response.Body, new { Status = "Error", Message = exp.ToString() }, filter); return(true); } } } // request did not match an existing handler return(false); }