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")
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 int c = (int)Request.DataStream.Length;
100 byte[] Bin = new byte[c];
101 await Request.DataStream.ReadAllAsync(Bin, 0, c);
102
103 await this.Process(Bin, Response, false);
104 }
105 }
106 catch (Exception)
107 {
108 await Response.SendResponse(new BadRequestException("Invalid request."));
109 }
110 }
111
112 private async Task Process(byte[] ReqBin, HttpResponse Response, bool Cache)
113 {
114 DnsMessage Msg = new DnsMessage(ReqBin);
115
116 foreach (Question Question in Msg.Questions)
117 {
119 if (DnsResponse is null)
120 await Response.SendResponse(new BadRequestException("Unable to resolve query."));
121 else
122 {
123 byte[] RespBin = (byte[])DnsResponse.Raw.Clone();
124
125 RespBin[0] = ReqBin[0]; // Use same ID as in request.
126 RespBin[1] = ReqBin[1];
127
128 Response.StatusCode = 200;
129 Response.ContentType = ContentType;
130
131 if (Cache)
132 {
133 int Seconds = (int)Math.Ceiling((DnsResponse.Expires - DateTime.Now).TotalSeconds);
134 if (Seconds > 0)
135 Response.SetHeader("Cache-Control", "max-age=" + Seconds.ToString());
136 }
137
138 await Response.Write(RespBin);
139 }
140 return;
141 }
142
143 await Response.SendResponse(new BadRequestException("Request lacking dns query parameter."));
144 }
145
146 }
147}
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:122
Contains information about a DNS Question
Definition: Question.cs:12
DNS resolver, as defined in:
Definition: DnsResolver.cs:32
static Task< DnsResponse > Query(string Name, QTYPE TYPE, QCLASS CLASS)
Resolves a DNS name.
Definition: DnsResolver.cs:329
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:265
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:18
Stream DataStream
Data stream, if data is available, or null if data is not available.
Definition: HttpRequest.cs:139
HttpRequestHeader Header
Request header.
Definition: HttpRequest.cs:134
bool HasData
If the request has data.
Definition: HttpRequest.cs:74
string ResourceName
Name of resource.
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:21
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
void SetHeader(string FieldName, string Value)
Sets a custom header field value.
async Task Write(byte[] Data)
Returns binary data in the response.
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.