Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ClientChunkRecord.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
4using Waher.Events;
6
8{
9 internal class ClientChunkRecord : ChunkRecord
10 {
11 internal HttpxClient client;
12 internal HttpxResponseEventArgs e;
13 internal SortedDictionary<int, Chunk> chunks = null;
14 internal HttpResponse response;
15 internal EventHandlerAsync<HttpxResponseDataEventArgs> dataCallback;
16 internal IE2eSymmetricCipher symmetricCipher;
17 internal object state;
18 internal string streamId;
19 internal string from;
20 internal string to;
21 internal string endpointReference;
22 internal int nextChunk = 0;
23 internal bool e2e;
24
25 internal ClientChunkRecord(HttpxClient Client, HttpxResponseEventArgs e, HttpResponse Response,
26 EventHandlerAsync<HttpxResponseDataEventArgs> DataCallback, object State, string StreamId, string From, string To, bool E2e,
27 string EndpointReference, IE2eSymmetricCipher SymmetricCipher)
28 : base()
29 {
30 this.client = Client;
31 this.e = e;
32 this.response = Response;
33 this.dataCallback = DataCallback;
34 this.state = State;
35 this.streamId = StreamId;
36 this.from = From;
37 this.to = To;
38 this.e2e = E2e;
39 this.endpointReference = EndpointReference;
40 this.symmetricCipher = SymmetricCipher;
41 }
42
43 internal override async Task<bool> ChunkReceived(int Nr, bool Last, byte[] Data)
44 {
45 if (Nr == this.nextChunk)
46 {
47 if (Data.Length > 0 || Last)
48 {
49 if (!await this.dataCallback.Raise(this.client, new HttpxResponseDataEventArgs(null, Data, this.streamId, Last, this.state), false))
50 {
51 await this.client.CancelTransfer(this.e.From, this.streamId);
52 return false;
53 }
54 }
55
56 this.nextChunk++;
57
58 if (Last)
59 await this.Done();
60 else
61 {
62 while (!(this.chunks is null))
63 {
64 if (this.chunks.Count == 0)
65 this.chunks = null;
66 else
67 {
68 foreach (Chunk Chunk in this.chunks.Values)
69 {
70 if (Chunk.Nr == this.nextChunk)
71 {
72 if (!await this.dataCallback.Raise(this.client, new HttpxResponseDataEventArgs(null, Chunk.Data, this.streamId, Chunk.Last, this.state), false))
73 return false;
74
75 this.nextChunk++;
76 this.chunks.Remove(Chunk.Nr);
77
78 if (Chunk.Last)
79 {
80 await this.Done();
81 this.chunks.Clear();
82 }
83
84 break;
85 }
86 else
87 return true;
88 }
89 }
90 }
91 }
92 }
93 else if (Nr > this.nextChunk)
94 {
95 if (this.chunks is null)
96 this.chunks = new SortedDictionary<int, Chunk>();
97
98 this.chunks[Nr] = new Chunk(Nr, Last, Data);
99 }
100
101 return true;
102 }
103
104 private async Task Done()
105 {
106 if (!(this.response is null))
107 {
108 try
109 {
110 await this.response.DisposeAsync();
111 }
112 catch (Exception ex)
113 {
114 Log.Exception(ex);
115 }
116 }
117 }
118
119 internal override async Task Fail(string Message)
120 {
121 if (this.response is null)
122 return;
123
124 await this.dataCallback.Raise(this.client, new HttpxResponseDataEventArgs(null, new byte[0], this.streamId, true, this.state), false);
125
126 if (!this.response.HeaderSent)
127 await this.response.SendResponse(new InternalServerErrorException(Message));
128
129 await this.client.CancelTransfer(this.e.From, this.streamId);
130
131 await this.Done();
132 }
133
134 public override async Task DisposeAsync()
135 {
136 if (!(this.response is null))
137 {
138 await this.response.DisposeAsync();
139 this.response = null;
140 }
141
142 this.chunks?.Clear();
143 this.chunks = null;
144 }
145 }
146}
Static class managing the application event log. Applications and services log events on this static ...
Definition: Log.cs:13
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
Definition: Log.cs:1647
Represets a response of an HTTP client request.
Definition: HttpResponse.cs:21
async Task DisposeAsync()
Closes the connection and disposes of all resources.
async Task SendResponse()
Sends the response back to the client. If the resource is synchronous, there's no need to call this m...
bool HeaderSent
If the header has been sent.
The server encountered an unexpected condition which prevented it from fulfilling the request.