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 |