source: binary-improvements2/WebServer/src/UrlHandlers/ApiHandler.cs@ 400

Last change on this file since 400 was 399, checked in by alloc, 2 years ago

Updated logging strings

File size: 3.1 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Reflection;
5using Webserver.WebAPI;
6
7namespace Webserver.UrlHandlers {
8 public class ApiHandler : AbsHandler {
9 private readonly Dictionary<string, AbsWebAPI> apis = new CaseInsensitiveStringDictionary<AbsWebAPI> ();
10
11 public ApiHandler () : base (null) {
12
13 }
14
15 public override void SetBasePathAndParent (Web _parent, string _relativePath) {
16 base.SetBasePathAndParent (_parent, _relativePath);
17
18 Type[] apiWithParentCtorTypes = { typeof (Web) };
19 object[] apiWithParentCtorArgs = { _parent };
20
21 Type[] apiEmptyCtorTypes = { };
22 object[] apiEmptyCtorArgs = { };
23
24
25 ReflectionHelpers.FindTypesImplementingBase (typeof (AbsWebAPI), _type => {
26 ConstructorInfo ctor = _type.GetConstructor (apiWithParentCtorTypes);
27 if (ctor != null) {
28 AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiWithParentCtorArgs);
29 addApi (apiInstance);
30 return;
31 }
32
33 ctor = _type.GetConstructor (apiEmptyCtorTypes);
34 if (ctor != null) {
35 AbsWebAPI apiInstance = (AbsWebAPI) ctor.Invoke (apiEmptyCtorArgs);
36 addApi (apiInstance);
37 }
38 });
39
40 // Permissions that don't map to a real API
41 addApi (new Null ("viewallclaims"));
42 addApi (new Null ("viewallplayers"));
43 }
44
45 private void addApi (AbsWebAPI _api) {
46 apis.Add (_api.Name, _api);
47 WebPermissions.Instance.AddKnownModule ("webapi." + _api.Name, _api.DefaultPermissionLevel ());
48 }
49
50 private static readonly UnityEngine.Profiling.CustomSampler apiHandlerSampler = UnityEngine.Profiling.CustomSampler.Create ("API_Handler");
51
52 public override void HandleRequest (RequestContext _context) {
53
54 string apiName;
55 string subPath = null;
56
57 int pathSeparatorIndex = _context.RequestPath.IndexOf ('/', urlBasePath.Length);
58 if (pathSeparatorIndex >= 0) {
59 apiName = _context.RequestPath.Substring (urlBasePath.Length, pathSeparatorIndex - urlBasePath.Length);
60 subPath = _context.RequestPath.Substring (pathSeparatorIndex + 1);
61 } else {
62 apiName = _context.RequestPath.Substring (urlBasePath.Length);
63 }
64
65 if (!apis.TryGetValue (apiName, out AbsWebAPI api)) {
66 Log.Warning ($"[Web] In {nameof(ApiHandler)}.HandleRequest(): No handler found for API \"{apiName}\"");
67 _context.Response.StatusCode = (int) HttpStatusCode.NotFound;
68 return;
69 }
70
71 if (!IsAuthorizedForApi (apiName, _context.PermissionLevel)) {
72 _context.Response.StatusCode = (int) HttpStatusCode.Forbidden;
73 if (_context.Connection != null) {
74 //Log.Out ($"{nameof(ApiHandler)}: user '{user.SteamID}' not allowed to execute '{apiName}'");
75 }
76
77 return;
78 }
79
80 _context.RequestPath = subPath;
81
82 try {
83 apiHandlerSampler.Begin ();
84 api.HandleRequest (_context);
85 apiHandlerSampler.End ();
86 } catch (Exception e) {
87 Log.Error ($"[Web] In {nameof(ApiHandler)}.HandleRequest(): Handler {api.Name} threw an exception:");
88 Log.Exception (e);
89 _context.Response.StatusCode = (int) HttpStatusCode.InternalServerError;
90 }
91 }
92
93 private bool IsAuthorizedForApi (string _apiName, int _permissionLevel) {
94 return WebPermissions.Instance.ModuleAllowedWithLevel ("webapi." + _apiName, _permissionLevel);
95 }
96 }
97}
Note: See TracBrowser for help on using the repository browser.