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
| Imports System.Net
Imports System.IO
Public Class Form1
' La requête se fait avec un HttpWebRequest, et on créé les données par la class que j'ai créé qui s'appel MultipartFormDataBodyCreator.
'
' Propriété et procédures publiques de MultipartFormDataBodyCreator:
'
' Public Sub Add(Name as String, _ ' Le nom du champs à ajouter
' Value as String, _ ' La valeur
' Optional IsFileField as Bollean = False") ' Si il s'agit d'un fichier, mettre IsFileField = true
' ' et Value = le chemin du fichier
'
' Public Property Boundary as String ' Le Boundary à utiliser (sert à délimiter les champs dans la requête)
'
' Public Function Create() as Byte() ' Retourne les données à envoyer sous forme d'un tableau de byte
'
'
' Pour envoyer la requête présenté juste au dessus, il faut donc faire comme ceci:
Private Sub SendFile()
Try
Dim bodyCreator As New MultipartFormDataBodyCreator ' La classe que j'ai créé et que je présente plus loins
Dim File As String = "C:\toto.txt" ' Le fichier à envoyer
' Création des données à envoyer
' --------------------
bodyCreator.Fields.Add("uploadtype", "on")
bodyCreator.Fields.Add("replay", File, True) ' C'est le fichier
'bodyCreator.Fields.Add("MAX_FILE_SIZE", "3145728") '<== limitte le fichier à 3Mo
bodyCreator.Fields.Add("refer", "http://xxxxxxxx.php")
'bodyCreator.Fields.Add("brand", "")
'bodyCreator.Fields.Add("optsize", "320x320")
Dim body() As Byte = bodyCreator.Create ' Les données à envoyer sous forme de tableau de Byte
Dim boundary As String = bodyCreator.Boundary ' Le boudary délimitant les champs. Utile pour créer la requête
' Création de la requête
' ------------------------
Dim Request As HttpWebRequest = HttpWebRequest.Create("http://xxxxxxx.php")
Request.Method = "POST"
Request.UserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.7) Gecko/20060909 Firefox/1.5.0.7"
Request.KeepAlive = True
Request.ServicePoint.Expect100Continue = False ' Important si le serveur ne gère pas les Expect
Request.Referer = "http://xxxxxxxxx.php"
Request.ContentType = "multipart/form-data; boundary=" & boundary ' Ajouter le boundary après le Content-Type
Request.ContentLength = body.Length
' Ecriture des données
' ------------------------------------
Dim writer As Stream = Request.GetRequestStream
writer.Write(body, 0, body.Length)
writer.Close()
' Réponse
' -----------------
Dim response = Request.GetResponse()
Dim reader As New IO.StreamReader(response.GetResponseStream())
Dim ResponseBody = reader.ReadToEnd
reader.Close()
response.Close()
MsgBox(ResponseBody) ' Le réponse du serveur
Catch ex As Exception
MsgBox(ex.ToString)
End Try
End Sub
Public Class MultipartFormDataBodyCreator
' Le Boundary délimitant chaque élément (Field) dans le corps du message
' On y met une valeure constante, mais normalement il faudrait s'assurer que cette
' chaine de caractère n'existe pas ailleur dans les données à envoyer (si c'est le cas, l'envois va planter)
Public Property Boundary() As String
Get
Return _Boundary
End Get
Set(ByVal value As String)
_Boundary = value
End Set
End Property
Private _Boundary As String = "-----------------768299458641184676334"
' Les éléments à inclure dans le corps du message, tous défini par une paire Nom/Valeur
' Une propriété IsFileField as Bollean définie si c'est le champs du fichier à envoyer
' (dans quel cas Value contiendra le chemin du fichier à envoyer)
Public Property Fields() As FieldList
Get
Return _Fields
End Get
Set(ByVal value As FieldList)
_Fields = value
End Set
End Property
Private _Fields As New FieldList
' Création d'un tableau de bytes contenant toutes les données à envoyer durant le request
Public Function Create() As Byte()
Dim encoding As New System.Text.ASCIIEncoding() ' Pour convertir le text en bytes
Dim body(-1) As Byte ' Le contenu final
' Parcourir tous les champs pour créer le body
For Each Field As Field In _Fields
Dim sb As New System.Text.StringBuilder ' Pour créer les champs texte
Dim FieldAsBytes() As Byte ' Le champs à ajouter au body en bytes
' Ajouter ce qui est commun aux champs FILE et les autres, c'est à dire une
' ligne avec le bundary puis la disposition et le nom du champ sur une autre ligne
sb.AppendLine("--" & Boundary) ' Le bundary précédé de "--"
sb.Append("Content-Disposition: form-data; name=""" & Field.Name & """") ' La disposition et le nom du champs (sans finir la ligne!)
' La suite dépend si c'est un fichier ou non
If Field.IsFileField Then ' C'est un fichier
' Ajouter le nom du fichier sur la meme ligne que le nom du champ
' Sur les lignes suivantes, le type de contenu et 1 ligne vide (puis viendra le fichier)
sb.AppendLine("; filename=""" & System.IO.Path.GetFileName(Field.Value) & """")
sb.AppendLine("Content-Type: image/jpeg" & vbCrLf)
FieldAsBytes = encoding.GetBytes(sb.ToString) ' Le 1er bout du champ codé en bytes
' On ajoute le contenu du fichier fichier au tableau FieldAsBytes
Dim FileBytes() As Byte = IO.File.ReadAllBytes(Field.Value) ' Le contenu du fichier
Array.Resize(FieldAsBytes, FieldAsBytes.Length + FileBytes.Length) ' Agrandir FieldAsBytes
Array.Copy(FileBytes, 0, FieldAsBytes, sb.Length, FileBytes.Length) ' Ajouter le contenu du fichier
' Ajouter un vbcrlf pour finir le champ
Array.Resize(FieldAsBytes, FieldAsBytes.Length + 2)
Array.Copy(encoding.GetBytes(vbCrLf), 0, FieldAsBytes, FieldAsBytes.Length - 2, 2)
Else
' C'est un élément du formulaire autre qu'un fichier
sb.AppendLine("") ' Finir la ligne précédente
sb.AppendLine(vbCrLf & Field.Value) ' Une ligne vide et la valeur
FieldAsBytes = encoding.GetBytes(sb.ToString) ' Créer un tableau de Byte
End If
' Ajouter la nouvelle entrée dans le body
Dim CurrentBodySize As Integer = body.Length
Array.Resize(body, body.Length + FieldAsBytes.Length) ' Agrandir le body
Array.Copy(FieldAsBytes, 0, body, body.Length - FieldAsBytes.Length, FieldAsBytes.Length) ' Copier FieldAsBytes à la fin du body
Next
' A la fin on ajoute le bundary et "--"
Dim EndLine() As Byte = encoding.GetBytes("--" & Boundary & "--" & vbCrLf)
Array.Resize(body, body.Length + EndLine.Length)
Array.Copy(EndLine, 0, body, body.Length - EndLine.Length, EndLine.Length)
Return body
End Function
End Class
Public Class FieldList
Inherits Generic.List(Of Field)
' Cette class éritée d'une collection générique List(Of Field) est créé juste pour ajouter les 2 procédures suivantes:
Public Overloads Sub Add(ByVal Name As String, ByVal Value As String, Optional ByVal IsFileField As Boolean = False)
MyBase.Add(New Field(Name, Value, IsFileField))
End Sub
Public Overloads Sub Insert(ByVal Index As Integer, ByVal Name As String, ByVal Value As String, Optional ByVal IsFileField As Boolean = False)
MyBase.Insert(Index, New Field(Name, Value, IsFileField))
End Sub
End Class
Public Class Field
' Représente un champs de formulaire
Public IsFileField As Boolean = False
Public Name As String = ""
Public Value As String = ""
Public Sub New()
End Sub
Public Sub New(ByVal Name As String, ByVal Value As String, Optional ByVal IsFileField As Boolean = False)
Me.Name = Name
Me.Value = Value
Me.IsFileField = IsFileField
End Sub
End Class
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Call SendFile()
End Sub
End Class |
Partager