Skip to content

Commit d8933bd

Browse files
Added requirement to match Alpaca API parameters and form data
1 parent 734cf65 commit d8933bd

3 files changed

Lines changed: 130 additions & 20 deletions

File tree

ASCOM.Alpaca.Simulators/Controllers/BaseController.cs

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,38 @@ namespace ASCOM.Alpaca.Simulators
1212
{
1313
public class ProcessBaseController : Controller
1414
{
15+
internal bool BadRequestAlpacaProtocol(out BadRequestObjectResult Result)
16+
{
17+
18+
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
19+
{
20+
Result = BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
21+
Logging.Log.LogError($"Error on request {HttpContext.Request.Path} with details: {Result.Value?.ToString()}");
22+
return true;
23+
}
24+
25+
if (HttpContext.Request.HasFormContentType)
26+
{
27+
if (HttpContext.Request.Form.Keys.Any(key => !ValidAlpacaKeys.ValidFormKeys.Contains(key)))
28+
{
29+
var keys = HttpContext.Request.Form.Keys.Where(key => !ValidAlpacaKeys.ValidFormKeys.Contains(key));
30+
Result = BadRequest(Strings.FormCapitalizationDescription + string.Join(", ", keys));
31+
Logging.Log.LogError($"Error on request {HttpContext.Request.Path} with details: {Result.Value?.ToString()}");
32+
return true;
33+
}
34+
}
35+
36+
if (HttpContext.Request.Query.Keys.Any(key => !ValidAlpacaKeys.ValidParameterKeys.Contains(key)))
37+
{
38+
var keys = HttpContext.Request.Query.Keys.Where(key => !ValidAlpacaKeys.ValidParameterKeys.Contains(key));
39+
Result = BadRequest(Strings.QueryCapitalizationDescription + string.Join(", ", keys));
40+
Logging.Log.LogError($"Error on request {HttpContext.Request.Path} with details: {Result.Value?.ToString()}");
41+
return true;
42+
}
43+
Result = null;
44+
return false;
45+
}
46+
1547
/// <summary>
1648
/// This function logs the incoming API call then executes the passed function
1749
/// By executing the function this can catch any errors
@@ -33,9 +65,9 @@ internal ActionResult<BoolResponse> ProcessRequest(Func<bool> Operation, uint Tr
3365

3466
if (ServerSettings.RequireStrictURLCase)
3567
{
36-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
68+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
3769
{
38-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
70+
return result;
3971
}
4072
}
4173

@@ -64,9 +96,9 @@ internal ActionResult<DriveRatesResponse> ProcessRequest(Func<ITrackingRates> Re
6496

6597
if (ServerSettings.RequireStrictURLCase)
6698
{
67-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
99+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
68100
{
69-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
101+
return result;
70102
}
71103
}
72104

@@ -104,9 +136,9 @@ internal ActionResult<DoubleResponse> ProcessRequest(Func<double> Request, uint
104136

105137
if (ServerSettings.RequireStrictURLCase)
106138
{
107-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
139+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
108140
{
109-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
141+
return result;
110142
}
111143
}
112144

@@ -135,9 +167,9 @@ internal ActionResult<AxisRatesResponse> ProcessRequest(Func<IAxisRates> Request
135167

136168
if (ServerSettings.RequireStrictURLCase)
137169
{
138-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
170+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
139171
{
140-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
172+
return result;
141173
}
142174
}
143175

@@ -175,9 +207,9 @@ internal ActionResult<IntArray2DResponse> ProcessRequest(Func<int[,]> Request, u
175207

176208
if (ServerSettings.RequireStrictURLCase)
177209
{
178-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
210+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
179211
{
180-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
212+
return result;
181213
}
182214
}
183215

@@ -206,9 +238,9 @@ internal ActionResult<StringListResponse> ProcessRequest(Func<IList<string>> Req
206238

207239
if (ServerSettings.RequireStrictURLCase)
208240
{
209-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
241+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
210242
{
211-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
243+
return result;
212244
}
213245
}
214246

@@ -237,9 +269,9 @@ internal ActionResult<IntListResponse> ProcessRequest(Func<IList<int>> Request,
237269

238270
if (ServerSettings.RequireStrictURLCase)
239271
{
240-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
272+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
241273
{
242-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
274+
return result;
243275
}
244276
}
245277

@@ -268,9 +300,9 @@ internal ActionResult<IntResponse> ProcessRequest(Func<int> Request, uint Transa
268300

269301
if (ServerSettings.RequireStrictURLCase)
270302
{
271-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
303+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
272304
{
273-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
305+
return result;
274306
}
275307
}
276308

@@ -299,9 +331,9 @@ internal ActionResult<StringResponse> ProcessRequest(Func<string> Request, uint
299331

300332
if (ServerSettings.RequireStrictURLCase)
301333
{
302-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
334+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
303335
{
304-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
336+
return result;
305337
}
306338
}
307339

@@ -330,9 +362,9 @@ internal ActionResult<Response> ProcessRequest(Action Request, uint TransactionI
330362

331363
if (ServerSettings.RequireStrictURLCase)
332364
{
333-
if (HttpContext.Request.Path.ToString().Any(char.IsUpper))
365+
if (BadRequestAlpacaProtocol(out BadRequestObjectResult result))
334366
{
335-
return BadRequest(Strings.URLCapitalizationDescription + HttpContext.Request.Path.ToString());
367+
return result;
336368
}
337369
}
338370

ASCOM.Alpaca.Simulators/Documentation/Strings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,7 @@ public class Strings
88
public const string ClientIDDescription = @"Client's unique ID. (A uint32 with a range of 0 to 4294967295). The client should choose a value at start-up, e.g. a random value between 0 and 65535, and send this value on every transaction to help associate entries in device logs with this particular client.";
99

1010
public const string URLCapitalizationDescription = @"The API URL is required to be lowercase. Supplied URL: ";
11+
public const string FormCapitalizationDescription = @"The API Form is required to match the Alpaca Specification. Unknown Form Key(s): ";
12+
public const string QueryCapitalizationDescription = @"The API Query is required to match the Alpaca Specification. Unknown Query Key(s): ";
1113
}
1214
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
using System.Collections.Generic;
2+
3+
namespace ASCOM.Alpaca.Simulators
4+
{
5+
internal class ValidAlpacaKeys
6+
{
7+
internal static List<string> ValidParameterKeys = new List<string>{
8+
"ClientID" ,
9+
"ClientTransactionID",
10+
"RightAscension",
11+
"Declination",
12+
"ID",
13+
"SensorName",
14+
"Axis"
15+
};
16+
17+
internal static List<string> ValidFormKeys = new List<string> {
18+
"ClientID",
19+
"ClientTransactionID",
20+
"BinX",
21+
"BinY",
22+
"CoolerOn",
23+
"FastReadout",
24+
"Gain",
25+
"NumX",
26+
"NumY",
27+
"Offset",
28+
"ReadoutMode",
29+
"SetCCDTemperature",
30+
"StartX",
31+
"StartY",
32+
"SubExposureDuration",
33+
"Direction",
34+
"Duration",
35+
"Light",
36+
"Action",
37+
"Parameters",
38+
"Command",
39+
"Raw",
40+
"Connected",
41+
"Brightness",
42+
"Slaved",
43+
"Altitude",
44+
"Azimuth",
45+
"Position",
46+
"TempComp",
47+
"AveragePeriod",
48+
"Reverse",
49+
"ID",
50+
"State",
51+
"Name",
52+
"Value",
53+
"Axis",
54+
"DeclinationRate",
55+
"RightAscension",
56+
"Declination",
57+
"DoesRefraction",
58+
"GuideRateDeclination",
59+
"GuideRateRightAscension",
60+
"Axis",
61+
"Rate",
62+
"RightAscensionRate",
63+
"SideOfPier",
64+
"SiteElevation",
65+
"SiteLatitude",
66+
"SiteLongitude",
67+
"SlewSettleTime",
68+
"TargetDeclination",
69+
"TargetRightAscension",
70+
"Tracking",
71+
"TrackingRate",
72+
"UTCDate",
73+
74+
};
75+
}
76+
}

0 commit comments

Comments
 (0)