microsoft-visualbasic-runtime/Net/HTTP/URL.vb

133 lines
4.5 KiB
VB.net

Imports Microsoft.VisualBasic.ComponentModel.DataSourceModel
Imports Microsoft.VisualBasic.Language
Imports Microsoft.VisualBasic.Linq
Namespace Net.Http
Public Class URL
''' <summary>
''' the url query parameters
''' </summary>
''' <returns></returns>
Public Property query As Dictionary(Of String, String())
Public Property path As String
Public Property hostName As String
Public Property port As Integer
Public Property protocol As String
''' <summary>
''' #....
''' </summary>
''' <returns></returns>
Public Property hashcode As String
Default Public ReadOnly Property getArgumentVal(query As String) As String
Get
With GetValues(query)
If .IsNothing Then
Return Nothing
Else
Return DirectCast(.GetValue(Scan0), String)
End If
End With
End Get
End Property
Sub New(url As String)
With url.GetTagValue("?", trim:=True, failureNoName:=False)
Dim tokens = .Value.Split("#"c)
Dim tmp$
If tokens.Length > 1 Then
hashcode = tokens.Last
tmp = tokens.Take(tokens.Length - 1).JoinBy("#")
Else
tmp = tokens.FirstOrDefault
End If
query = tmp _
.Split("?"c) _
.ParseUrlQueryParameters() _
.ToDictionary(allStrings:=True) _
.TryCast(Of Dictionary(Of String, String()))
url = .Name
End With
For Each type As String In WebServiceUtils.Protocols
If Strings.InStr(url, type, CompareMethod.Text) = 1 Then
protocol = type
Exit For
End If
Next
If protocol.StringEmpty Then
protocol = "http://"
url = url.TrimStart("/"c)
Else
url = url.Substring(protocol.Length + 1)
End If
With url.GetTagValue("/", trim:=False, failureNoName:=False)
hostName = .Name
path = .Value
With hostName.GetTagValue(":", False, True)
hostName = .Name
If .Value = "" Then
Select Case protocol
Case "http://"
port = 80
Case "https://"
port = 443
Case "ftp://"
port = 21
Case "sftp://"
port = 22
Case Else
port = -1
End Select
Else
port = Integer.Parse(.Value)
End If
End With
End With
End Sub
Private Sub New()
End Sub
Public Function GetValues(query As String) As String()
With LCase(query)
If .DoCall(AddressOf _query.ContainsKey) Then
Return .DoCall(Function(key) _query(key))
Else
Return Nothing
End If
End With
End Function
Public Overrides Function ToString() As String
Return $"{protocol}{hostName}:{port}/{path}?{query.Select(Function(q) q.Value.Select(Function(val) $"{q.Key}={UrlEncode(val)}")).IteratesALL.JoinBy("&")}#{hashcode}"
End Function
Public Shared Function BuildUrl(url As String, query As IEnumerable(Of NamedValue(Of String))) As URL
Return New URL With {
.hostName = "",
.port = -1,
.path = url,
.hashcode = "",
.protocol = "?",
.query = query _
.GroupBy(Function(a) a.Name.ToLower) _
.ToDictionary(Function(a) a.Key,
Function(a)
Return a _
.Select(Function(t) t.Value) _
.ToArray
End Function)
}
End Function
End Class
End Namespace