1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
Private Sub Srv_http()
Dim arguments As String() = New String() {"--base", "web", "--address", monip, "--port", port_http}
Log("serveur web lancé avec " & monip & ":" & port_http, True)
WebHTTP(arguments)
End Sub
Private ReadOnly type_de_contenu As New Dictionary(Of String, String) From {
{".htm", "text/html"},
{".html", "text/html"},
{".js", "text/javascript"},
{".css", "text/css"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"}
} ' ajout si besoin
Private Function Trouve_type_de_contenu(ByVal chemin As String) As String
Dim ext As String = IO.Path.GetExtension(chemin)
If type_de_contenu.ContainsKey(ext) Then Return type_de_contenu(ext)
Return "text/plain"
End Function
Private Const READ_BUFFER_SIZE As Integer = 512 * 1024
Public Sub WebHTTP(ByVal arguments() As String)
Dim occupe As Boolean = False
Try
Dim options As New Dictionary(Of String, String) From {{"--port", "8080"}, {"--address", "127.0.0.1"}, {"--base", String.Empty}}
For i As Integer = 0 To arguments.Length - 2
If arguments(i).StartsWith("-") AndAlso options.ContainsKey(arguments(i)) Then options(arguments(i)) = arguments(i + 1)
Next
'recupere le chemin de base
Dim basedir As String = Path.Combine(My.Computer.FileSystem.CurrentDirectory, options("--base"))
'on ecoute
Dim s As New TcpListener(IPAddress.Parse(options("--address")), Integer.Parse(options("--port")))
Dim client As TcpClient
s.Start()
Do
client = s.AcceptTcpClient() 'on attend le prochain TCP client, et accepte la cnx
Dim flux As NetworkStream = client.GetStream() 'on lit
Dim sendingData As New Text.StringBuilder()
Dim rdata(READ_BUFFER_SIZE - 1) As Byte
Dim read As Integer
Try
Do
read = flux.Read(rdata, 0, READ_BUFFER_SIZE)
sendingData.Append(Encoding.UTF8.GetString(rdata, 0, read))
Loop While read = READ_BUFFER_SIZE
Catch
End Try
#If Not DEBUG Then
Try
#End If
If sendingData.Length > 0 Then
occupe = True
Dim data As String = sendingData.ToString()
Dim headers() As String = data.Split({ControlChars.Cr, ControlChars.Lf}, StringSplitOptions.RemoveEmptyEntries)
Dim basicRequestInfo() As String = headers(0).Split(" "c)
Dim method As String = basicRequestInfo(0)
Dim filepath As String = basicRequestInfo(1).Substring(1)
Dim actualFilepath As String = Path.Combine(basedir, Uri.UnescapeDataString(Regex.Replace(filepath, "\?.*$", "")).TrimStart("/"c).Replace("/"c, "\"c))
Dim httpVersion As String = basicRequestInfo(2)
Dim responseHeaders As New Dictionary(Of String, String)
Dim statusCode As String = "200"
Dim statusReason As String = "OK"
Dim responseContent() As Byte = {}
If httpVersion <> "HTTP/1.0" AndAlso httpVersion <> "HTTP/1.1" Then 'verifie la version http : HTTP/1.0 and HTTP/1.1 seulement
statusCode = "505"
statusReason = "HTTP Version Not Supported"
responseContent = Encoding.UTF8.GetBytes("505 HTTP Version Not Supported")
Else
If (filepath) = "now" Then
Statistique_v2(Date.Parse(Now.Year & "-" & Now.Month & "-" & Now.Day & " 00:00:01"), Date.Parse(Now.Year & "-" & Now.Month & "-" & Now.Day & " 23:59:59"))
filepath = Path.Combine(basedir, "stats.html")
actualFilepath = Path.Combine(basedir, "stats.html")
End If
If (filepath) = "yesterday" Then
filepath = Path.Combine(basedir, "stats.html")
actualFilepath = Path.Combine(basedir, "stats.html")
Statistique_v2((Date.Parse(Now.Year & "-" & Now.Month & "-" & Now.Day & " 00:00:01")).AddDays(-1), Date.Parse((Now.Year & "-" & Now.Month & "-" & Now.Day & " 23:59:59")).AddDays(-1))
End If
If (filepath) = "week" Then
filepath = Path.Combine(basedir, "stats.html")
actualFilepath = Path.Combine(basedir, "stats.html")
Statistique_v2((Date.Parse(Now.Year & "-" & Now.Month & "-" & Now.Day & " 00:00:01")).AddDays(-7), Date.Parse((Now.Year & "-" & Now.Month & "-" & Now.Day & " 23:59:59")))
End If
If (filepath) = "month" Then
filepath = Path.Combine(basedir, "stats.html")
actualFilepath = Path.Combine(basedir, "stats.html")
Statistique_v2((Date.Parse(Now.Year & "-" & Now.Month & "-" & Now.Day & " 00:00:01")).AddMonths(-1), Date.Parse((Now.Year & "-" & Now.Month & "-" & Now.Day & " 23:59:59")))
End If
Try 'Attempt to check if the requested path is a directory; if so, we'll add index.html to it:
If filepath = String.Empty OrElse filepath = "/" Then
actualFilepath = Path.Combine(basedir, "index.html")
filepath = "/"
ElseIf Directory.Exists(actualFilepath) Then
actualFilepath = Path.Combine(actualFilepath, "index.html")
End If
Catch
'Ignore the error; it will appear once again when we try to read the file.
End Try
If method = "GET" Then 'Check the method - we only support GET and HEAD:
If filepath.Contains("..") Then 'Make sure nobody's trying to hack the system by requesting ../whatever or an absolute path:
statusCode = "403"
statusReason = "Forbidden"
responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
Log("fichier {0} en erreur 403 Forbidden : " & filepath)
ElseIf Not File.Exists(actualFilepath) Then
statusCode = "404"
statusReason = "Not Found"
responseContent = Encoding.UTF8.GetBytes("404 Not Found :(")
Log("fichier {0} en erreur 404 Not Found : " & filepath & " " & actualFilepath)
Else
Try
responseContent = File.ReadAllBytes(actualFilepath) 'Read the requested file:
responseHeaders.Add("Content-Length", responseContent.Length.ToString()) 'Get the requested file's length:
responseHeaders.Add("Content-Type", trouve_type_de_contenu(actualFilepath)) 'And get its content type too:
Catch
statusCode = "403" 'Couldn't get the file's information - assume forbidden.
statusReason = "Forbidden"
responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
End Try
End If
ElseIf method = "HEAD" Then
If filepath.Contains("..") Then 'Make sure nobody's trying to hack the system by requesting ../whatever or an absolute path:
statusCode = "403"
statusReason = "Forbidden"
responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
Log("fichier {0} en erreur 403 Forbidden : " & filepath)
ElseIf Not File.Exists(actualFilepath) Then
statusCode = "404"
statusReason = "Not Found"
responseContent = Encoding.UTF8.GetBytes("404 Not Found")
Log("{0} en erreur 404 Not Found : " & filepath)
Else
Try
responseHeaders.Add("Content-Length", New FileInfo(actualFilepath).Length.ToString()) 'Get the requested file's length:
responseHeaders.Add("Content-Type", trouve_type_de_contenu(actualFilepath)) 'And get its content type too:
Catch
statusCode = "403"
statusReason = "Forbidden"
responseContent = Encoding.UTF8.GetBytes("403 Forbidden")
End Try
End If
Else
statusCode = "405"
statusReason = "Method Not Allowed"
End If
Dim response As New List(Of Byte) 'Prepare the response:
response.AddRange(Encoding.UTF8.GetBytes("HTTP/1.1 " & statusCode & statusReason & ControlChars.CrLf)) 'Prepare the response's HTTP version and status:
Dim combinedResponseHeaders As New List(Of String) 'Prepare the response's headers:
For Each header As KeyValuePair(Of String, String) In responseHeaders : combinedResponseHeaders.Add(header.Key & ": " & header.Value) : Next
response.AddRange(Encoding.UTF8.GetBytes(String.Join(ControlChars.CrLf, combinedResponseHeaders.ToArray())))
response.Add(13) : response.Add(10) : response.Add(13) : response.Add(10) : response.AddRange(responseContent) 'Prepare the response's content:
flux.Write(response.ToArray(), 0, response.Count) 'Finally, write the response:
End If
End If
#If Not DEBUG Then
Catch ex As Exception
Console.WriteLine("Serious error while processing request: ")
Console.WriteLine(ex.ToString())
Try
Dim errorResponse() As Byte = Encoding.UTF8.GetBytes("HTTP/1.1 500 Internal Server Error" & ControlChars.CrLf & ControlChars.CrLf & "500 Internal Server Error")
ns.Write(errorResponse, 0, errorResponse.Length)
Catch
End Try
End Try
#End If
client.Close()
occupe = False
Loop
Catch ex As SocketException
Log(" pb socket tcp; socket deja utilisé ", True)
End Try
End Sub |
Partager