Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DnsOverHttpsResource.cs
1using System;
2using System.Threading.Tasks;
3using Waher.Content;
7
9{
14 {
18 public const string ContentType = "application/dns-message";
19
24 : this("/dns-query")
25 {
26 }
27
33 : base(ResourceName)
34 {
35 }
36
40 public override bool HandlesSubPaths => false;
41
45 public override bool UserSessions => false;
46
50 public bool AllowsGET => true;
51
55 public bool AllowsPOST => true;
56
63 public async Task GET(HttpRequest Request, HttpResponse Response)
64 {
65 try
66 {
67 if (!Request.Header.TryGetQueryParameter("dns", out string s))
68 await Response.SendResponse(new BadRequestException("Request lacking dns query parameter."));
69 else if (Request.Header.Accept is null || Request.Header.Accept.IsAcceptable(ContentType))
70 {
71 byte[] Bin = Base64Url.Decode(s);
72 await this.Process(Bin, Response, true);
73 }
74 else
75 await Response.SendResponse(new NotAcceptableException("Only acceptable encoding is DNS encoding."));
76 }
77 catch (Exception)
78 {
79 await Response.SendResponse(new BadRequestException("Invalid request."));
80 }
81 }
82
89 public async Task POST(HttpRequest Request, HttpResponse Response)
90 {
91 try
92 {
93 if (!Request.HasData || string.Compare(Request.Header.ContentType?.Type, ContentType, true) != 0)
94 await Response.SendResponse(new UnsupportedMediaTypeException("DNS encoded content expected."));
95 else if (string.Compare(Request.Header.UriScheme, "http", true) == 0)
96 await Response.SendResponse(new BadRequestException("Unencrypted transport not permitted."));
97 else
98 {
99 byte[] Bin = await Request.DataStream.ReadAllAsync();
100 await this.Process(Bin, Response, false);
101 }
102 }
103 catch (Exception)
104 {
105 await Response.SendResponse(new BadRequestException("Invalid request."));
106 }
107 }
108
109 private async Task Process(byte[] ReqBin, HttpResponse Response, bool Cache)
110 {
111 DnsMessage Msg = new DnsMessage(ReqBin);
112
113 foreach (Question Question in Msg.Questions)
114 {
116 if (DnsResponse is null)
117 await Response.SendResponse(new BadRequestException("Unable to resolve query."));
118 else
119 {
120 byte[] RespBin = (byte[])DnsResponse.Raw.Clone();
121
122 RespBin[0] = ReqBin[0]; // Use same ID as in request.
123 RespBin[1] = ReqBin[1];
124
125 Response.StatusCode = 200;
126 Response.StatusMessage = "OK";
127 Response.ContentType = ContentType;
128
129 if (Cache)
130 {
131 int Seconds = (int)Math.Ceiling((DnsResponse.Expires - DateTime.Now).TotalSeconds);
132 if (Seconds > 0)
133 Response.SetHeader("Cache-Control", "max-age=" + Seconds.ToString());
134 }
135
136 await Response.Write(true, RespBin);
137 }
138 return;
139 }
140
141 await Response.SendResponse(new BadRequestException("Request lacking dns query parameter."));
142 }
143
144 }
145}
Static class that does BASE64URL encoding (using URL and filename safe alphabet), as defined in RFC46...
Definition: Base64Url.cs:11
static byte[] Decode(string Base64Url)
Converts a Base64URL-encoded string to its binary representation.
Definition: Base64Url.cs:17
Question[] Questions
Question section
Definition: DnsMessage.cs:120
Contains information about a DNS Question
Definition: Question.cs:9
DNS resolver, as defined in:
Definition: DnsResolver.cs:32
static Task< DnsResponse > TryQuery(string Name, QTYPE TYPE, QCLASS CLASS)
Tries to query a DNS name.
Definition: DnsResolver.cs:424
async Task POST(HttpRequest Request, HttpResponse Response)
Executes the POST method on the resource.
override bool UserSessions
If the resource uses user sessions.
async Task GET(HttpRequest Request, HttpResponse Response)
Executes the GET method on the resource.
override bool HandlesSubPaths
If the resource handles sub-paths.
const string ContentType
application/dns-message
bool AllowsPOST
If the POST method is allowed.
DnsOverHttpsResource(string ResourceName)
DNS over HTTPS resource.
The request could not be understood by the server due to malformed syntax. The client SHOULD NOT repe...
HttpFieldContentType ContentType
Content-Type HTTP Field header. (RFC 2616, §14.17)
Definition: HttpHeader.cs:285
HttpFieldAccept Accept
Accept HTTP Field header. (RFC 2616, §14.1)
bool TryGetQueryParameter(string QueryParameter, out string Value)
Tries to get the value of an individual query parameter, if available.
Represents an HTTP request.
Definition: HttpRequest.cs:22
Stream DataStream
Data stream, if data is available, or null if data is not available.
Definition: HttpRequest.cs:187
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:182
bool HasData
If the request has data.
Definition: HttpRequest.cs:113
string ResourceName
Name of resource.
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:23
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
Task Write(byte[] Data)
Returns binary data in the response.
void SetHeader(string FieldName, string Value)
Sets a custom header field value.
Base class for all synchronous HTTP resources. A synchronous resource responds within the method hand...
The resource identified by the request is only capable of generating response entities which have con...
The server is refusing to service the request because the entity of the request is in a format not su...
GET Interface for HTTP resources.
POST Interface for HTTP resources.