1 #Region "Microsoft.VisualBasic::a1b128ba81ddbfb72092ac075138a59e, Microsoft.VisualBasic.Core\ApplicationServices\Tools\Network\Protocol\RequestStream.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class RequestStream
35     
36     '         Properties: BufferLength, ChunkBuffer, FullRead, Protocol, ProtocolCategory
37     '                     TotalBytes, uid
38     
39     '         Constructor: (+7 OverloadsSub New
40     '         Function: (+2 Overloads) CreatePackage, CreateProtocol, GetRawStream, GetUTF8String, IsAvaliableStream
41     '                   (+2 Overloads) LoadObject, Serialize, ToString
42     '         Enum Protocols
43     
44     
45     
46     
47     '  
48     
49     '     Properties: IsPing, IsPlantText, IsSSL_PublicToken, IsSSLHandshaking, IsSSLProtocol
50     '                 TypeGetSystemProtocol
51     
52     '     Function: SystemProtocol
53     '     Operators: (+3 Overloads) <>, (+3 Overloads) =
54     
55     
56     ' /********************************************************************************/
57
58 #End Region
59
60 Imports System.Xml.Serialization
61 Imports Microsoft.VisualBasic.Language
62 Imports Microsoft.VisualBasic.Net.Http
63 Imports Microsoft.VisualBasic.Scripting.Abstract
64 Imports Microsoft.VisualBasic.Serialization.JSON
65
66 Namespace Net.Protocols
67
68     ''' <summary>
69     ''' Socket user client => Socket server data request &amp;
70     ''' Socket server => Socket user client data response package.
71     ''' (Socket客户端 => Socket服务器所发送的数据请求以及从
72     ''' Socket服务器 => Socket客户端所返回数据的数据响应包)
73     ''' </summary>
74     <Serializable> Public Class RequestStream : Inherits RawStream
75         Implements ISerializable
76
77         ''' <summary>
78         ''' This property indicates the protocol processor module for the server object.
79         ''' </summary>
80         ''' <returns></returns>
81         <XmlAttribute("Entry")>
82         Public Property ProtocolCategory As Int64
83         ''' <summary>
84         ''' This property indicates which the specifics protocol processor will be used for the incoming client request.
85         ''' (协议的头部)
86         ''' </summary>
87         ''' <returns></returns>
88         <XmlAttribute("Protocol")>
89         Public Property Protocol As Int64
90         ''' <summary>
91         ''' Buffer length of the protocol request raw stream data <see cref="ChunkBuffer"/>.(协议数据的长度)
92         ''' </summary>
93         ''' <returns></returns>
94         <XmlAttribute("bufLen")>
95         Public Property BufferLength As Int64
96         ''' <summary>
97         ''' The raw stream data of the details data request or the server response data.(协议的具体数据请求)
98         ''' </summary>
99         ''' <returns></returns>
100         <XmlAttribute("rawBuf")>
101         Public Property ChunkBuffer As Byte()
102         ''' <summary>
103         ''' 使用用户的账号信息唯一标识出来的对象,在服务器端用来查找用户证书的
104         ''' 由于在服务器上面这个哈希值是和解密的密匙唯一对应的,所以服务器上面大多数情况下是直接通过这个哈希值来决定授权的
105         ''' </summary>
106         ''' <returns></returns>
107         <XmlAttribute> Public Property uid As Long
108
109         ''' <summary>
110         ''' <see cref="ChunkBuffer"/>部分的数据是否完整?
111         ''' </summary>
112         ''' <returns></returns>
113         Public ReadOnly Property FullRead As Boolean
114             Get
115                 Return BufferLength = ChunkBuffer.Length
116             End Get
117         End Property
118
119         Sub New(ProtocolCategory As Long, Protocol As Long, buffer As Byte())
120             Me.ProtocolCategory = ProtocolCategory
121             Me.Protocol = Protocol
122             Me.BufferLength = buffer.Length
123             Me.ChunkBuffer = buffer
124         End Sub
125
126         ''' <summary>
127         ''' 构建一个无参数的网络协议对象
128         ''' </summary>
129         ''' <param name="ProtocolCategory"></param>
130         ''' <param name="Protocol"></param>
131         Sub New(ProtocolCategory As Long, Protocol As Long)
132             Call Me.New(ProtocolCategory, Protocol, New Byte() {})
133         End Sub
134
135         ''' <summary>
136         ''' The default text encoding is <see cref="System.Text.Encoding.UTF8"/>
137         ''' </summary>
138         ''' <param name="ProtocolCategory"></param>
139         ''' <param name="Protocol"></param>
140         ''' <param name="s_Data">Protocol request argument parameters</param>
141         Sub New(ProtocolCategory As Long, Protocol As Long, s_Data As String)
142             Call Me.New(ProtocolCategory, Protocol, System.Text.Encoding.UTF8.GetBytes(s_Data))
143         End Sub
144
145         Sub New(ProtocolCategory As Long, Protocol As Long, s_Data As String, encoding As System.Text.Encoding)
146             Call Me.New(ProtocolCategory, Protocol, encoding.GetBytes(s_Data))
147         End Sub
148
149         Sub New(ProtocolCategory As Long, Protocol As Long, ChunkBuffer As ISerializable)
150             Call Me.New(ProtocolCategory, Protocol, ChunkBuffer.Serialize)
151         End Sub
152
153         ''' <summary>
154         ''' 其余的协议参数都是值 <see cref="HTTP_RFC.RFC_OK"/>
155         ''' </summary>
156         ''' <param name="data"></param>
157         Sub New(data As String)
158             Call Me.New(HTTP_RFC.RFC_OK, HTTP_RFC.RFC_OK, data)
159         End Sub
160
161         ''' <summary>
162         ''' Deserialize (当还有剩余数据的时候会将数据进行剪裁)
163         ''' </summary>
164         ''' <param name="rawStream"></param>
165         Sub New(rawStream As Byte())
166             Call MyBase.New(rawStream)
167
168             Dim bitChunk As Byte() = New Byte(INT64 - 1) {}
169             Dim p As int = Scan0
170
171             Call Array.ConstrainedCopy(rawStream, ++(p + INT64), bitChunk, Scan0, INT64)
172             Me.ProtocolCategory = BitConverter.ToInt64(bitChunk, Scan0)
173
174             Call Array.ConstrainedCopy(rawStream, ++(p + INT64), bitChunk, Scan0, INT64)
175             Me.Protocol = BitConverter.ToInt64(bitChunk, Scan0)
176
177             bitChunk = New Byte(INT64 - 1) {}
178             Call Array.ConstrainedCopy(rawStream, p = (p + INT64), bitChunk, Scan0, INT64)
179             Me.BufferLength = BitConverter.ToInt64(bitChunk, Scan0)
180
181             bitChunk = New Byte(Me.BufferLength - 1) {}
182             Dim nxt As Long = p + BufferLength
183             If nxt > rawStream.Length - INT64 Then
184                 ' 越界了,则数据没有读完
185                 ChunkBuffer = New Byte() {}
186                 Return
187             End If
188
189             Call Array.ConstrainedCopy(rawStream, p = (p + BufferLength), bitChunk, Scan0, Me.BufferLength)
190             Me.ChunkBuffer = bitChunk
191
192             bitChunk = New Byte(INT64 - 1) {}
193             Call Array.ConstrainedCopy(rawStream, p + INT64, bitChunk, Scan0, INT64)
194             Me.uid = BitConverter.ToInt64(bitChunk, Scan0)
195         End Sub
196
197         ''' <summary>
198         ''' 默认是使用UTF8编码来编码字符串的
199         ''' </summary>
200         ''' <returns></returns>
201         Public Function GetUTF8String() As String
202             Return System.Text.Encoding.UTF8.GetString(ChunkBuffer)
203         End Function
204
205         ''' <summary>
206         ''' 将数据首先生成字符串,然后根据函数指针<paramref name="handler"/>句柄的描述从字符串之中反序列化加载对象
207         ''' </summary>
208         ''' <typeparam name="T"></typeparam>
209         ''' <param name="handler"></param>
210         ''' <returns></returns>
211         Public Function LoadObject(Of T)(handler As LoadObject(Of T)) As T
212             Return handler(GetUTF8String)
213         End Function
214
215         ''' <summary>
216         ''' json
217         ''' </summary>
218         ''' <typeparam name="T"></typeparam>
219         ''' <returns></returns>
220         Public Function LoadObject(Of T)() As T
221             Return GetUTF8String.LoadObject(Of T)
222         End Function
223
224         ''' <summary>
225         ''' 从原始数据流<see cref="ChunkBuffer"/>之中进行反序列化得到一个嵌套的数据串流对象
226         ''' </summary>
227         ''' <typeparam name="TStream"></typeparam>
228         ''' <returns></returns>
229         Public Overloads Function GetRawStream(Of TStream As RawStream)() As TStream
230             Return GetRawStream(Of TStream)(rawStream:=ChunkBuffer)
231         End Function
232
233         Public Overrides Function ToString() As String
234             Dim stringData As String = $"(string) {NameOf(ChunkBuffer)}:={GetUTF8String()};  {TotalBytes()} bytes"
235
236             If IsSSLProtocol OrElse IsSSLHandshaking Then
237                 Return $"{NameOf(uid)}:={uid} // {stringData}"
238             Else
239                 Return $"{NameOf(ProtocolCategory)}:={ProtocolCategory}; {NameOf(Protocol)}:={Protocol}; {NameOf(BufferLength)}:={BufferLength};  // {stringData}"
240             End If
241         End Function
242
243         ''' <summary>
244         ''' 这个函数是使用json序列化参数信息的
245         ''' </summary>
246         ''' <typeparam name="T"></typeparam>
247         ''' <param name="cat"></param>
248         ''' <param name="protocol"></param>
249         ''' <param name="params"></param>
250         ''' <returns></returns>
251         Public Shared Function CreateProtocol(Of T)(cat As Long, protocol As Long, params As T) As RequestStream
252             Dim json As String = params.GetJson
253             Return New RequestStream(cat, protocol, json)
254         End Function
255
256         ''' <summary>
257         ''' 服务器端返回数据所使用的,默认使用json序列化,所有的标签为<see cref="HTTP_RFC.RFC_OK"/>
258         ''' </summary>
259         ''' <typeparam name="T"></typeparam>
260         ''' <param name="obj"></param>
261         ''' <returns></returns>
262         Public Shared Function CreatePackage(Of T)(obj As T) As RequestStream
263             Return New RequestStream(HTTP_RFC.RFC_OK, HTTP_RFC.RFC_OK, obj.GetJson)
264         End Function
265
266         ''' <summary>
267         ''' 服务器端返回数据所使用的,所有的标签为<see cref="HTTP_RFC.RFC_OK"/>
268         ''' </summary>
269         ''' <param name="pack"></param>
270         ''' <returns></returns>
271         Public Shared Function CreatePackage(pack As Byte()) As RequestStream
272             Return New RequestStream(HTTP_RFC.RFC_OK, HTTP_RFC.RFC_OK, pack)
273         End Function
274
275         Private Shared ReadOnly ___offset As Byte() = New Byte() {RequestStream.BITWISE_FLAG}
276
277         Const BITWISE_FLAG As Byte = 255
278         Const MIN_LEN As Integer = INT64 + 1 + INT64 + 1 + INT64
279
280         Public Shared Function IsAvaliableStream(stream As Byte()) As Boolean
281             If stream.Length < MIN_LEN Then
282                 Return False
283             End If
284
285             If stream(INT64) <> BITWISE_FLAG OrElse stream(INT64 + 1 + INT64) <> BITWISE_FLAG Then
286                 Return False
287             Else
288                 Return True
289             End If
290         End Function
291
292         Public ReadOnly Property TotalBytes() As Long
293             Get
294                 Return INT64 + 1 + ' ProtocolCategory
295                     INT64 + 1 +    ' Protocol
296                     INT64 +        ' BufferLength
297                     BufferLength + ' ChunkBuffer
298                     INT64          ' uid
299             End Get
300         End Property
301
302         ''' <summary>
303         ''' 执行序列化进行网络之间的数据传输
304         ''' </summary>
305         ''' <returns></returns>
306         Public Overrides Function Serialize() As Byte() Implements ISerializable.Serialize
307             Dim ProtocolCategory As Byte() = BitConverter.GetBytes(Me.ProtocolCategory)
308             Dim Protocol As Byte() = BitConverter.GetBytes(Me.Protocol)
309             Dim BufferLength As Byte() = BitConverter.GetBytes(Me.BufferLength)
310             Dim uid As Byte() = BitConverter.GetBytes(Me.uid)
311
312             Dim bufs As Byte() = New Byte(TotalBytes - 1) {}
313             Dim p As int = Scan0
314             Dim l As New int
315
316             Call Array.ConstrainedCopy(ProtocolCategory, Scan0, bufs, p << (l = ProtocolCategory.Length), l)
317             Call Array.ConstrainedCopy(___offset, Scan0, bufs, ++p, 1)
318             Call Array.ConstrainedCopy(Protocol, Scan0, bufs, p << (l = Protocol.Length), l)
319             Call Array.ConstrainedCopy(___offset, Scan0, bufs, ++p, 1)
320             Call Array.ConstrainedCopy(BufferLength, Scan0, bufs, p << (l = BufferLength.Length), l)
321             Call Array.ConstrainedCopy(Me.ChunkBuffer, Scan0, bufs, p << (l = Me.BufferLength), l)
322             Call Array.ConstrainedCopy(uid, Scan0, bufs, p << (l = uid.Length), l)
323
324             Return bufs
325         End Function
326
327         ''' <summary>
328         ''' 系统里面最基本的基本数据协议
329         ''' </summary>
330         Public Const SYS_PROTOCOL As Long = -8888888L
331
332         ''' <summary>
333         ''' 最基本的Socket数据串流协议
334         ''' </summary>
335         Public Enum Protocols As Long
336             Ping = 10L
337             ''' <summary>
338             ''' 私有密匙加密
339             ''' </summary>
340             SSL = -107L
341             SSLHandshake = -200L
342             ''' <summary>
343             ''' 公共密匙加密
344             ''' </summary>
345             SSL_PublicToken = -405L
346             ''' <summary>
347             ''' 无效的数字证书
348             ''' </summary>
349             InvalidCertificates = -404L
350
351             NOT_SYS = 0L
352         End Enum
353
354         Public Shared Function SystemProtocol(Protocol As Protocols, Message As StringAs RequestStream
355             Return New RequestStream(SYS_PROTOCOL, Protocol, Message)
356         End Function
357
358         Public ReadOnly Property TypeGetSystemProtocol As Protocols
359             Get
360                 Try
361                     Return CType(Protocol, Protocols)
362                 Catch ex As Exception
363                     Return Protocols.NOT_SYS
364                 End Try
365             End Get
366         End Property
367
368         Public ReadOnly Property IsPing As Boolean
369             Get
370                 Return ProtocolCategory = SYS_PROTOCOL AndAlso Protocol = Protocols.Ping
371             End Get
372         End Property
373
374         ''' <summary>
375         ''' 这个请求数据是一个SSL加密数据(使用用户的私有密匙)
376         ''' </summary>
377         ''' <returns></returns>
378         Public ReadOnly Property IsSSLProtocol As Boolean
379             Get
380                 Return ProtocolCategory = SYS_PROTOCOL AndAlso Protocol = Protocols.SSL
381             End Get
382         End Property
383
384         ''' <summary>
385         ''' 使用公共密匙
386         ''' </summary>
387         ''' <returns></returns>
388         Public ReadOnly Property IsSSL_PublicToken As Boolean
389             Get
390                 Return ProtocolCategory = SYS_PROTOCOL AndAlso Protocol = Protocols.SSL_PublicToken
391             End Get
392         End Property
393
394         ''' <summary>
395         ''' 这个数据仅仅是一个文本,没有包含有任何协议头数据
396         ''' </summary>
397         ''' <returns></returns>
398         Public ReadOnly Property IsPlantText As Boolean
399             Get
400                 Return ProtocolCategory = Scan0 AndAlso Protocol = Scan0
401             End Get
402         End Property
403
404         ''' <summary>
405         ''' 这个请求数据是否为握手协议
406         ''' </summary>
407         ''' <returns></returns>
408         Public ReadOnly Property IsSSLHandshaking As Boolean
409             Get
410                 Return ProtocolCategory = SYS_PROTOCOL AndAlso Protocol = Protocols.SSLHandshake
411             End Get
412         End Property
413
414         ''' <summary>
415         ''' 简单的字符串等价
416         ''' </summary>
417         ''' <param name="a"></param>
418         ''' <param name="b"></param>
419         ''' <returns></returns>
420         Public Overloads Shared Operator =(a As RequestStream, b As RequestStream) As Boolean
421             Return String.Equals(a.GetUTF8String, b.GetUTF8String)
422         End Operator
423
424         Public Overloads Shared Operator <>(a As RequestStream, b As RequestStream) As Boolean
425             Return Not String.Equals(a.GetUTF8String, b.GetUTF8String)
426         End Operator
427
428         Public Overloads Shared Operator =(request As String, requestStream As RequestStream) As Boolean
429             Return String.Equals(request, requestStream.GetUTF8String)
430         End Operator
431
432         Public Overloads Shared Operator <>(request As String, requestStream As RequestStream) As Boolean
433             Return Not String.Equals(request, requestStream.GetUTF8String)
434         End Operator
435
436         Public Overloads Shared Operator =(requestStream As RequestStream, request As StringAs Boolean
437             Return String.Equals(request, requestStream.GetUTF8String)
438         End Operator
439
440         Public Overloads Shared Operator <>(requestStream As RequestStream, request As StringAs Boolean
441             Return Not String.Equals(request, requestStream.GetUTF8String)
442         End Operator
443     End Class
444 End Namespace