home *** CD-ROM | disk | FTP | other *** search
/ Planet Source Code Jumbo …e CD Visual Basic 1 to 7 / 5_2007-2008.ISO / data / Zips / HTTP_Class2082709102007.psc / cHttpClient.cls < prev    next >
Text File  |  2007-09-11  |  33KB  |  1,252 lines

  1. VERSION 1.0 CLASS
  2. BEGIN
  3.   MultiUse = -1  'True
  4.   Persistable = 0  'NotPersistable
  5.   DataBindingBehavior = 0  'vbNone
  6.   DataSourceBehavior  = 0  'vbNone
  7.   MTSTransactionMode  = 0  'NotAnMTSObject
  8. END
  9. Attribute VB_Name = "cHttpClient"
  10. Attribute VB_GlobalNameSpace = False
  11. Attribute VB_Creatable = True
  12. Attribute VB_PredeclaredId = False
  13. Attribute VB_Exposed = False
  14. '
  15. ' Classe cHttpClient
  16. ' (c) Thomas John (NoRabbit)
  17. '
  18. '
  19. 'classe CSocket remplaτant le contr⌠le winsock (http://www.vbip.com)
  20. Public WithEvents cs As CSocket
  21. Attribute cs.VB_VarHelpID = -1
  22. '
  23. 'classe minuteur reception des donnees
  24. Public WithEvents csTmrReception As Minuteur
  25. Attribute csTmrReception.VB_VarHelpID = -1
  26. '
  27. 'classe minuteur time out connexion
  28. Public WithEvents csTmrTimeOut As Minuteur
  29. Attribute csTmrTimeOut.VB_VarHelpID = -1
  30. '
  31. '
  32. 'contient le "reste" d'une commande (voir le traεtement des donnΘes)
  33. Dim ResteRecptTemp As String
  34. '
  35. 'le nombre max de donnees a envoyer en une fois (octets)
  36. Const MaxDonneesEnvoi = 4
  37. '
  38. 'spΘcifie si le socket est prΩt pour envoyer des donnΘes
  39. Dim PretEnvoiSz As Boolean
  40. '
  41. 'specifie si on peut fermer le socket apres la fin d un envoi de donnees
  42. Dim FermerSocketApresEnvoi As Boolean
  43. '
  44. '
  45. 'serveur
  46. Dim ServeurSz As String
  47. '
  48. 'port
  49. Dim PortSz As Long
  50. '
  51. 'methode de la requete (GET, POST,...)
  52. Dim MethodeRequete As String
  53. '
  54. 'page appellee
  55. Dim PageRequete As String
  56. '
  57. '
  58. 'headers a envoyer
  59. Dim EnvHeaders() As String
  60. '
  61. 'headers recus
  62. Dim RecHeaders() As String
  63. '
  64. 'totalite des headers recus ?
  65. Dim bRecHeaders As Boolean
  66. '
  67. '
  68. 'reponse du serveur (200, 404, ...)
  69. Dim ReponseHTTP As String
  70. '
  71. 'message de la reponse du serveur (OK, ...)
  72. Dim ReponseMsg As String
  73. '
  74. 'tranfer encoding (chunked, ...)
  75. Dim TransferEncoding As String
  76. '
  77. '
  78. 'version du protocole (HTTP/1.1)
  79. Dim VersionProtocole As String
  80. '
  81. 'FORM DATA
  82. 'contient le nom des data qu on envoie
  83. Dim FormDataNom() As String
  84. '
  85. 'contient le nom du fichier
  86. Dim FormDataFichier() As String
  87. '
  88. 'contient le type de donnees
  89. Dim FormDataType() As String
  90. '
  91. 'contient les donnees
  92. Dim FormDataDonnees() As String
  93. '
  94. 'contient le tout a envoyer
  95. Dim FormDataEnvoi() As String
  96. '
  97. '
  98. 'taille des donnees recues
  99. Public RecTailleData As Long
  100. '
  101. 'taille des donnees totales a recevoir
  102. Public RecTailleTotaleData As Long
  103. '
  104. '
  105. 'taille du chunk en cour
  106. Dim ChunkTaille As Long
  107. 'taille totale des chunks connus reunis
  108. Dim ChunkTailleTotale As Long
  109. 'taille des donnees recues
  110. Dim ChunkTailleRecu As Long
  111. 'taille des donnees restantes du chunk en cour
  112. Dim ChunkReste As Long
  113. 'les donnees restantes du chunk en cour
  114. Dim ChunkResteData As String
  115. 'fin de la reception des chunks ?
  116. Public ChunkRecFin As Boolean
  117. '
  118. '
  119. 'occupe a traiter les donnees ?
  120. Public traiterDonneesOccupe As Boolean
  121. '
  122. '
  123. 'les etats de notre classe
  124. Public Enum etats
  125.     '
  126.     SOCKET_FERME = 0
  127.     SOCKET_OUVERT = 1
  128.     SOCKET_RECEPTION = 2
  129.     '
  130. End Enum
  131. '
  132. 'l etat de notre classe
  133. Dim etat As etats
  134. '
  135. '
  136. 'EVENEMENTS DE LA CLASSE
  137. Event reception(Data As String, TailleRecu As Long, TailleTotaleRecu As Long, Fini As Boolean)
  138. Event connection()
  139. Event fermeture()
  140. Event erreur(Data As String)
  141. Event timeout()
  142. Event headers(Nom As String, Data As String)
  143. '
  144. '
  145. '************************************************
  146. '* EVENEMENTS class
  147. '************************************************
  148. '
  149. 'initialisation
  150. Private Sub Class_Initialize()
  151.     '
  152.     'on initialise quelques variables
  153.     Set cs = New CSocket
  154.     '
  155.     Set csTmrReception = New Minuteur
  156.     Set csTmrTimeOut = New Minuteur
  157.     '
  158.     csTmrReception.Intervalle = 100
  159.     csTmrTimeOut.Intervalle = 5000
  160.     '
  161.     initVars
  162.     '
  163. End Sub
  164. '
  165. 'de-initialisation
  166. Private Sub Class_Terminate()
  167.     '
  168.     On Error Resume Next
  169.     '
  170.     cs.CloseSocket
  171.     '
  172.     Set cs = Nothing
  173.     '
  174.     Set csTmrReception = Nothing
  175.     Set csTmrTimeOut = Nothing
  176.     '
  177. End Sub
  178. '
  179. '************************************************
  180. '* EVENEMENTS class
  181. '************************************************
  182. '
  183. '
  184. 'initialise les variables de base
  185. Public Sub initVars()
  186.     '
  187.     MethodeRequete = "GET"
  188.     VersionProtocole = "HTTP/1.1"
  189.     '
  190.     FermerSocketApresEnvoi = False
  191.     bRecHeaders = False
  192.     '
  193.     ReDim EnvHeaders(0 To 0)
  194.     ReDim RecHeaders(0 To 0)
  195.     '
  196.     ReDim FormDataNom(0 To 0)
  197.     ReDim FormDataDonnees(0 To 0)
  198.     ReDim FormDataType(0 To 0)
  199.     ReDim FormDataFichier(0 To 0)
  200.     ReDim FormDataEnvoi(1 To 2)
  201.     '
  202.     etat = SOCKET_FERME
  203.     '
  204.     'on ajoute qques headers de base
  205.     'host sera remplace par apres, je le met ici pour qu il soit en debut de liste
  206.     ajouterHeader "Host", ""
  207.     ajouterHeader "User-Agent", "cHttpClient"
  208.     'ajouterHeader "Accept", "text/plain"
  209.     'ajouterHeader "Accept-Language", "en-us,en;q=0.5"
  210.     'ajouterHeader "Accept-Encoding", "gzip,deflate"
  211.     'ajouterHeader "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7"
  212.     'ajouterHeader "Keep-Alive", "300"
  213.     'ajouterHeader "Connection", "keep-alive"
  214.     ajouterHeader "Connection", "Close"
  215.     '
  216. End Sub
  217. '
  218. '
  219. '************************************************
  220. '* FONCTIONS header envoi
  221. '************************************************
  222. '
  223. 'ajoute un header a envoyer
  224. Public Sub ajouterHeader(Nom As String, Data As String, Optional retourLigne As Boolean = True)
  225.     '
  226.     Dim iH As Integer
  227.     '
  228.     'on verifie si ce nom existe deja dans la liste
  229.     iH = rechHeader(Nom)
  230.     '
  231.     If iH <= 0 Then
  232.         '
  233.         'non, on cree une nouvelle entree
  234.         iH = UBound(EnvHeaders) + 1
  235.         '
  236.         ReDim Preserve EnvHeaders(LBound(EnvHeaders) To iH)
  237.         '
  238.     End If
  239.     '
  240.     'on insere les donnees dans le tableau a l endroit specifie
  241.     'on ajoute le retour de ligne a la fin s il le faut
  242.     EnvHeaders(iH) = Nom & ": " & Data & IIf(retourLigne = True, vbCrLf, "")
  243.     '
  244. End Sub
  245. '
  246. 'recherche si un header est deja present dans la liste
  247. Private Function rechHeader(Nom As String) As Integer
  248.     '
  249.     Dim i As Integer
  250.     Dim iH As Integer
  251.     '
  252.     iH = UBound(EnvHeaders)
  253.     '
  254.     'on verifie si ce nom existe dans la liste
  255.     For i = 1 To iH
  256.         '
  257.         If LCase(Left(EnvHeaders(i), Len(Nom))) = LCase(Nom) Then
  258.             '
  259.             'oui, on renvoie l index
  260.             rechHeader = i
  261.             '
  262.             'et on quitte la fonction ici
  263.             Exit Function
  264.             '
  265.         End If
  266.         '
  267.     Next
  268.     '
  269.     'n existe pas, on renvoie 0
  270.     rechHeader = 0
  271.     '
  272. End Function
  273. '
  274. 'envoie les headers
  275. Private Sub envoiHeaders()
  276.     '
  277.     Dim i As Integer
  278.     Dim iH As Integer
  279.     '
  280.     iH = UBound(EnvHeaders)
  281.     '
  282.     'on parcourt la liste
  283.     For i = 1 To iH
  284.         '
  285.         Env EnvHeaders(i)
  286.         '
  287.     Next
  288.     '
  289. End Sub
  290. '
  291. '************************************************
  292. '* FIN FONCTIONS header envoi
  293. '************************************************
  294. '
  295. '
  296. '************************************************
  297. '* FONCTIONS form data
  298. '************************************************
  299. '
  300. 'ajoute un form data a envoyer
  301. Public Sub ajouterFormData(Nom As String, Data As String, Optional Fichier As String = "", Optional TypeData As String = "")
  302.     '
  303.     Dim iH As Integer
  304.     '
  305.     'on verifie si ce nom existe deja dans la liste
  306.     iH = rechFormData(Nom)
  307.     '
  308.     If iH <= 0 Then
  309.         '
  310.         'non, on cree une nouvelle entree
  311.         iH = UBound(FormDataNom) + 1
  312.         '
  313.         ReDim Preserve FormDataNom(LBound(FormDataNom) To iH)
  314.         ReDim Preserve FormDataDonnees(LBound(FormDataDonnees) To iH)
  315.         ReDim Preserve FormDataFichier(LBound(FormDataFichier) To iH)
  316.         ReDim Preserve FormDataType(LBound(FormDataType) To iH)
  317.         '
  318.     End If
  319.     '
  320.     'on insere les donnees dans les tableaux
  321.     FormDataNom(iH) = Nom
  322.     FormDataDonnees(iH) = Data
  323.     FormDataFichier(iH) = Fichier
  324.     FormDataType(iH) = TypeData
  325.     '
  326. End Sub
  327. '
  328. 'recherche si un form data est deja present dans la liste
  329. Private Function rechFormData(Nom As String) As Integer
  330.     '
  331.     Dim i As Integer
  332.     Dim iH As Integer
  333.     '
  334.     iH = UBound(FormDataNom)
  335.     '
  336.     'on verifie si ce nom existe dans la liste
  337.     For i = 1 To iH
  338.         '
  339.         If LCase(FormDataNom(i)) = LCase(Nom) Then
  340.             '
  341.             'oui, on renvoie l index
  342.             rechFormData = i
  343.             '
  344.             'et on quitte la fonction ici
  345.             Exit Function
  346.             '
  347.         End If
  348.         '
  349.     Next
  350.     '
  351.     'n existe pas, on renvoie 0
  352.     rechFormData = 0
  353.     '
  354. End Function
  355. '
  356. 'prepare les form data pour envoi
  357. Private Sub prepareFormDatas()
  358.     '
  359.     Dim i As Integer
  360.     Dim iH As Integer
  361.     Dim Boundary As String
  362.     Dim l As Long
  363.     Dim gSz As String
  364.     '
  365.     iH = UBound(FormDataNom)
  366.     '
  367.     'on verifie qu on a qque chose
  368.     If iH <= 0 Then Exit Sub
  369.     '
  370.     'ok, on cree notre "Boundary" qui va servir a delimiter les donnees qu on envoie
  371.     Boundary = creerBoundary(14)
  372.     '
  373.     'les guillemets
  374.     gSz = Chr(34)
  375.     '
  376.     'la taille des donnees
  377.     l = 0
  378.     '
  379.     'on parcourt la liste
  380.     For i = 1 To iH
  381.         '
  382.         DoEvents
  383.         '
  384.         'notre premier boundary pour ces donnees, on ajoute "--" devant...
  385.         l = l + ajoutFormDataEnvoi("--" & Boundary & vbCrLf)
  386.         '
  387.         'les infos de ces donnees
  388.         l = l + ajoutFormDataEnvoi("Content-Disposition: form-data; name=" & gSz & FormDataNom(i) & gSz)
  389.         '
  390.         'on verifie s il ne faut pas envoyer un fichier
  391.         If Len(FormDataFichier(i)) > 0 Then
  392.             '
  393.             'oui, on rajoute son nom a la suite
  394.             l = l + ajoutFormDataEnvoi("; filename=" & gSz & FormDataFichier(i) & gSz & vbCrLf)
  395.             '
  396.             'ensuite le type de donnees
  397.             l = l + ajoutFormDataEnvoi("Content-Type: " & FormDataType(i) & vbCrLf & vbCrLf)
  398.             '
  399.             'et enfin les donnees
  400.             l = l + ajoutFormDataEnvoi("fichier: " & FormDataFichier(i))
  401.             '
  402.         Else
  403.             '
  404.             'non, on ajoute simplement les donnees a la suite
  405.             l = l + ajoutFormDataEnvoi(vbCrLf & vbCrLf & FormDataDonnees(i) & vbCrLf)
  406.             '
  407.         End If
  408.         '
  409.         'on verifie s il s agit du dernier element de nos tableau
  410.         If i = iH Then
  411.             '
  412.             'oui, on termine par notre boundary de fin, on ajoute "--" devant et derriere
  413.             l = l + ajoutFormDataEnvoi("--" & Boundary & "--" & vbCrLf)
  414.             '
  415.         End If
  416.         '
  417.     Next
  418.     '
  419.     'on ajoute les infos dans l entete pour "presenter" les donnees "form data"
  420.     FormDataEnvoi(1) = "Content-Type: multipart/form-data; boundary=" & Boundary & vbCrLf
  421.     '
  422.     'la taille de ces donnees
  423.     FormDataEnvoi(2) = "Content-Length: " & l & vbCrLf & vbCrLf
  424.     '
  425. End Sub
  426. '
  427. 'ajoute les donnees dans le tableau FormDataEnvoi
  428. Private Function ajoutFormDataEnvoi(Data As String) As Long
  429.     '
  430.     Dim iH As Integer
  431.     Dim l As Long
  432.     '
  433.     iH = UBound(FormDataEnvoi) + 1
  434.     '
  435.     'les 2 premier index de ce tableau sont reserves
  436.     'on redimensionne
  437.     ReDim Preserve FormDataEnvoi(1 To iH)
  438.     '
  439.     FormDataEnvoi(iH) = Data
  440.     '
  441.     'on verifie s il ne s agit pas d un fichier
  442.     If Left(Data, 9) = "fichier: " Then
  443.         '
  444.         'oui, on recupere sa taille + la taille de vbcrlf
  445.         l = FileLen(Mid(Data, 10)) + Len(vbCrLf)
  446.         '
  447.     Else
  448.         '
  449.         'non, pas de fichier
  450.         l = Len(Data)
  451.         '
  452.     End If
  453.     '
  454.     'on renvoie la longueur de ces donnees
  455.     ajoutFormDataEnvoi = l
  456.     '
  457. End Function
  458. '
  459. 'envoie les form data
  460. Private Sub envoiFormDatas()
  461.     '
  462.     Dim i As Integer
  463.     Dim iH As Integer
  464.     '
  465.     iH = UBound(FormDataEnvoi)
  466.     '
  467.     'on verifie qu on a qque chose en plus que les 2 premiers headers de presentation
  468.     'de ces form data
  469.     If iH <= 2 Then Exit Sub
  470.     '
  471.     'on parcourt la liste
  472.     For i = 1 To iH
  473.         '
  474.         'on verifie qu il ne faut pas envoyer un fichier
  475.         If Left(FormDataEnvoi(i), 9) = "fichier: " Then
  476.             '
  477.             'si, on l envoie
  478.             envoiFichier Mid(FormDataEnvoi(i), 10)
  479.             '
  480.             'et le retour de ligne de fin
  481.             Env vbCrLf
  482.             '
  483.         Else
  484.             '
  485.             'non, on envoie les infos du tableau
  486.             Env FormDataEnvoi(i)
  487.             '
  488.         End If
  489.         '
  490.     Next
  491.     '
  492. End Sub
  493. '
  494. 'envoie un fichier
  495. Private Sub envoiFichier(Fichier As String)
  496.     '
  497.     Dim FichSz As Integer
  498.     Dim sData As String
  499.     Dim TailleTotale As Long
  500.     Dim tailleRestante As Long
  501.     Dim tailleEnvoi As Long
  502.     '
  503.     FichSz = FreeFile
  504.     '
  505.     Open Fichier For Binary As FichSz
  506.     '
  507.     'on recupere la taille totale et la taille restante
  508.     TailleTotale = LOF(FichSz)
  509.     tailleRestante = TailleTotale
  510.     '
  511.     'on envoie les donnees par bout
  512.     Do
  513.         '
  514.         DoEvents
  515.         '
  516.         'on specifie la taille des donnees a envoyer
  517.         tailleEnvoi = MaxDonneesEnvoi
  518.         '
  519.         'on verifie si ce n est pas trop grand
  520.         If tailleEnvoi > tailleRestante Then tailleEnvoi = tailleRestante
  521.         '
  522.         'on recupere les donnees
  523.         sData = Space(tailleEnvoi)
  524.         Get FichSz, , sData
  525.         '
  526.         'et on les envoie
  527.         Env sData
  528.         '
  529.         'on soustrait la taille des donnees envoyees a la taille des donnees restantes
  530.         tailleRestante = tailleRestante - tailleEnvoi
  531.         '
  532.         'on verifie si on a termine
  533.         If tailleRestante <= 0 Then Exit Do
  534.         '
  535.     Loop
  536.     '
  537.     Close FichSz
  538.     '
  539. End Sub
  540. '
  541. 'cree un boundary aleatoire
  542. Private Function creerBoundary(Max As Integer)
  543.     '
  544.     Dim i As Integer
  545.     Dim s As String
  546.     '
  547.     Randomize
  548.     '
  549.     For i = 1 To Max
  550.         '
  551.         s = s & Round(Rnd() * 9)
  552.         '
  553.     Next
  554.     '
  555.     creerBoundary = "---------------------------" & s
  556.     '
  557. End Function
  558. '
  559. '************************************************
  560. '* FIN FONCTIONS form data
  561. '************************************************
  562. '
  563. '
  564. 'PROCEDURE PRINCIPALE (CONNEXION)
  565. Public Function connecter(Serveur As String, Port As Long, Page As String, Methode As String) As Boolean
  566.     '
  567.     'on verifie si on est deja connecte
  568.     If etat <> SOCKET_FERME Then
  569.         '
  570.         connecter = False
  571.         '
  572.         Exit Function
  573.         '
  574.     End If
  575.     '
  576.     'on stocke les infos nΘcessaires dans les variables
  577.     ServeurSz = Serveur
  578.     PortSz = Port
  579.     '
  580.     PageRequete = Page
  581.     MethodeRequete = Methode
  582.     '
  583.     'on initialise qques variables
  584.     ChunkTaille = 0
  585.     ChunkTailleTotale = 0
  586.     ChunkTailleRecu = 0
  587.     ChunkReste = 0
  588.     ChunkResteData = ""
  589.     ChunkRecFin = False
  590.     '
  591.     RecTailleTotaleData = 0
  592.     RecTailleData = 0
  593.     '
  594.     ResteRecptTemp = ""
  595.     '
  596.     FermerSocketApresEnvoi = False
  597.     '
  598.     'on se connecte
  599.     cs.Connect Serveur, Port
  600.     '
  601.     'on lance le timer timeout
  602.     csTmrTimeOut.Actif = True
  603.     '
  604.     connecter = True
  605.     '
  606. End Function
  607. '
  608. 'deconnexion
  609. Public Sub deconnecter()
  610.     '
  611.     'on stoppe les timers
  612.     csTmrReception.Actif = False
  613.     csTmrTimeOut.Actif = False
  614.     '
  615.     cs.CloseSocket
  616.     '
  617.     etat = SOCKET_FERME
  618.     '
  619.     RaiseEvent fermeture
  620.     '
  621. End Sub
  622. '
  623. '
  624. '************************************************
  625. '* EVENEMENTS CSocket
  626. '************************************************
  627. '
  628. Private Sub Cs_OnClose()
  629.     '
  630.     'on specifie que notre socket est ferme
  631.     'il se peut que notre timer de reception des donnees soit toujours actif
  632.     'c est la fonction de traitement des donnees qui arretera ou pas ce timer
  633.     'et enverra l evenement "fermeture" pour eviter les double fermetures
  634.     etat = SOCKET_FERME
  635.     '
  636. End Sub
  637. '
  638. Private Sub Cs_OnConnect()
  639.     '
  640.     'on stoppe le timer timeout
  641.     csTmrTimeOut.Actif = False
  642.     '
  643.     'on est connectΘ
  644.     etat = SOCKET_OUVERT
  645.     '
  646.     RaiseEvent connection
  647.     '
  648.     'on n a pas encore recu les headers
  649.     bRecHeaders = False
  650.     '
  651.     'on est pret a envoyer
  652.     PretEnvoiSz = True
  653.     '
  654.     'on n est pas occupe a traiter les donnees
  655.     traiterDonneesOccupe = False
  656.     '
  657.     'on envoie la premiere ligne de la requete
  658.     Env MethodeRequete & " " & PageRequete & " " & VersionProtocole & vbCrLf
  659.     '
  660.     'on ajoute le header "host"
  661.     ajouterHeader "Host", ServeurSz
  662.     '
  663.     'on envoie les headers
  664.     envoiHeaders
  665.     '
  666.     'on prepare les form data
  667.     prepareFormDatas
  668.     '
  669.     'et on les envoie
  670.     envoiFormDatas
  671.     '
  672.     Env vbCrLf
  673.     '
  674.     'FermerSocketApresEnvoi = True
  675.     '
  676. End Sub
  677. '
  678. Private Sub Cs_OnConnectionRequest(ByVal requestID As Long)
  679.     '
  680.     'pas utilisΘ ici
  681.     '
  682. End Sub
  683. '
  684. Private Sub Cs_OnDataArrival(ByVal bytesTotal As Long)
  685.     '
  686.     etat = SOCKET_RECEPTION
  687.     '
  688.     Dim DonnSz As String
  689.     '
  690.     cs.GetData DonnSz, , bytesTotal
  691.     '
  692.     ResteRecptTemp = ResteRecptTemp & DonnSz
  693.     '
  694.     'on active notre timer de traitement des donnees
  695.     csTmrReception.Actif = True
  696.     '
  697. End Sub
  698. '
  699. Private Sub Cs_OnError(ByVal Number As Integer, Description As String, ByVal Scode As Long, ByVal Source As String, ByVal HelpFile As String, ByVal HelpContext As Long, CancelDisplay As Boolean)
  700.     '
  701.     cs.CloseSocket
  702.     '
  703.     etat = SOCKET_FERME
  704.     '
  705.     RaiseEvent erreur(Description)
  706.     '
  707. End Sub
  708. '
  709. Private Sub Cs_OnSendComplete()
  710.     '
  711.     'le socket est α nouveau prΩt α envoyer des donnΘes
  712.     PretEnvoiSz = True
  713.     '
  714.     'on verifie s il ne faut pas fermer le socket
  715.     'If FermerSocketApresEnvoi = True Then Cs.CloseSocket
  716.     '
  717. End Sub
  718. '
  719. Private Sub Cs_OnSendProgress(ByVal bytesSent As Long, ByVal bytesRemaining As Long)
  720.     '
  721.     'pas utilisΘ
  722.     '
  723. End Sub
  724. '
  725. '************************************************
  726. '* FIN DES EVENEMENTS CSocket
  727. '************************************************
  728. '
  729. '
  730. '************************************************
  731. '* TRAITEMENT DES DONNEES RECUES
  732. '************************************************
  733. '
  734. '(premiere etape) on traite les donnees brutes recues
  735. Public Sub traiterDonneesBrutes()
  736.     '
  737.     'occupe ?
  738.     If traiterDonneesOccupe = True Then Exit Sub
  739.     '
  740.     'maintenant on l est
  741.     traiterDonneesOccupe = True
  742.     '
  743.     '**********************************************************
  744.     '
  745.     'C est ici qu on separe les "headers" du reste des donnees.
  746.     'Les "headers" (entetes) d un message html sont separes par
  747.     'deux vbcrlf.
  748.     'Une fois ces deux vbcrlf detectes, on traite le reste des
  749.     'donnees separement
  750.     '
  751.     '**********************************************************
  752.     '
  753.     'on verifie si on est connecte, sinon on a rien a faire ici
  754.     'If etat = SOCKET_FERME Then Exit Sub
  755.     '
  756.     Dim sTmp As String
  757.     '
  758.     Dim Bloc1 As String
  759.     Dim Bloc2 As String
  760.     Dim pos As Long
  761.     '
  762.     Dim SeparateurSz As String
  763.     '
  764.     SeparateurSz = vbCrLf & vbCrLf
  765.     '
  766.     'on recupere les donnees sauvegardees
  767.     Bloc1 = ResteRecptTemp
  768.     '
  769.     'on efface le reste
  770.     ResteRecptTemp = ""
  771.     '
  772.     'on verifie si on a bien qque chose a traiter, sinon on passe a la fin
  773.     If Len(Bloc1) <= 0 Then GoTo VERIF_REC_TOT
  774.     '
  775.     'on verifie si on a deja recu la totalite des headers
  776.     If bRecHeaders = False Then
  777.         '
  778.         'non, on recherche notre separateur
  779.         pos = InStr(1, Bloc1, SeparateurSz)
  780.         '
  781.         If pos > 0 Then
  782.             '
  783.             'ok, on l a, on separe ces headers du reste des donnees
  784.             Bloc2 = Left(Bloc1, pos - 1)
  785.             Bloc1 = Right(Bloc1, Len(Bloc1) - pos - Len(SeparateurSz) + 1)
  786.             '
  787.             bRecHeaders = True
  788.             '
  789.             'et on les envoie pour traitement
  790.             'on rajoute un vbcrlf pour que notre procedure detecte plus facilement
  791.             'le dernier header
  792.             traiterHeaders Bloc2 & vbCrLf
  793.             '
  794.         Else
  795.             '
  796.             'aucun sΘparateur n'a ΘtΘ trouvΘ, on sauvegarde les donnees recues
  797.             'avec celles sauvegardees entre-temps
  798.             ResteRecptTemp = Bloc1 & ResteRecptTemp
  799.             '
  800.             'et on quite la procΘdure
  801.             GoTo FIN_PROCEDURE
  802.             '
  803.         End If
  804.         '
  805.     End If
  806.     '
  807.     'les headers ont ete recus, on traite ces donnees en fonction de differents facteurs
  808.     If bRecHeaders = True Then
  809.         '
  810.         If TransferEncoding = "chunked" Then
  811.             '
  812.             'on recoit les donnees en mode "chunked", cad bout par bout.
  813.             'chaque bout commence par une ligne specifiant la taille de ce bout
  814.             '
  815.             'on verifie si on a recu tout le chunk et plus
  816.             If Len(Bloc1) > ChunkReste And ChunkReste > 0 Then
  817.                 '
  818.                 'on recupere la fin du chunk
  819.                 sTmp = Left(Bloc1, ChunkReste)
  820.                 '
  821.                 'le reste des donnees (le chunk suivant)
  822.                 Bloc1 = Right(Bloc1, Len(Bloc1) - ChunkReste)
  823.                 '
  824.                 'on reinitialise qques variables
  825.                 ChunkReste = 0
  826.                 ChunkTaille = 0
  827.                 '
  828.             End If
  829.             '
  830.             'on verifie s il faut traiter un nouveau chunk
  831.             If ChunkReste = 0 Then
  832.                 '
  833.                 Bloc1 = recChunkTaille(Bloc1)
  834.                 '
  835.                 'on verifie si ca n est pas la fin...
  836.                 If ChunkRecFin = True Then
  837.                     '
  838.                     'Exit Sub
  839.                     '
  840.                 End If
  841.                 '
  842.             End If
  843.             '
  844.             'on verifie s il faut comptabiliser le reste des donnees a recevoir
  845.             If ChunkReste > 0 Then
  846.                 '
  847.                 'pas encore recu toutes les donnees, on deduit la taille des donnees
  848.                 'recues du reste du chunk a recevoir
  849.                 ChunkReste = ChunkReste - Len(Bloc1)
  850.                 '
  851.             End If
  852.             '
  853.             'on verifie s il ne faut pas ajouter la fin du chunk precedent a ce debut de chunk
  854.             If Len(sTmp) > 0 Then Bloc1 = sTmp & Bloc1
  855.             '
  856.         End If
  857.         '
  858.         'on comptabilise la taille totale des donnees recues jusqu a present
  859.         RecTailleData = RecTailleData + Len(Bloc1)
  860.         '
  861.         'on envoie les donnees traitees
  862.         RaiseEvent reception(Bloc1, RecTailleData, RecTailleTotaleData, ChunkRecFin)
  863.         '
  864.         '
  865.         '
  866. VERIF_REC_TOT:
  867.         '
  868.         'on verifie si on a encore des donnees a traiter
  869.         If Len(ResteRecptTemp) <= 0 Then
  870.             '
  871.             'non, on verifie si on a recu toutes les donnees
  872.             If RecTailleData = RecTailleTotaleData And ChunkRecFin = True Then
  873.                 '
  874.                 'oui, on ferme notre socket ici
  875.                 cs.CloseSocket
  876.                 '
  877.                 etat = SOCKET_FERME
  878.                 '
  879.                 'on stoppe le timer
  880.                 csTmrReception.Actif = False
  881.                 '
  882.                 'on informe de la fin
  883.                 RaiseEvent fermeture
  884.                 '
  885.             Else
  886.                 '
  887.                 'on verifie si notre socket est en reception
  888.                 If etat <> SOCKET_RECEPTION Then
  889.                     '
  890.                     'non, on stoppe le timer
  891.                     csTmrReception.Actif = False
  892.                     '
  893.                     'on informe de la fin
  894.                     RaiseEvent fermeture
  895.                     '
  896.                 End If
  897.                 '
  898.             End If
  899.             '
  900.             GoTo FIN_PROCEDURE
  901.             '
  902.         End If
  903.         '
  904.         '
  905.         '
  906.     End If
  907.     '
  908. FIN_PROCEDURE:
  909.     '
  910.     'on n est plus occupe
  911.     traiterDonneesOccupe = False
  912.     '
  913. End Sub
  914. '
  915. 'recupere la taille du chunk et renvoie les donnees restantes
  916. Private Function recChunkTaille(Data As String) As String
  917.     '
  918.     Dim sRetour As String
  919.     Dim tmp As String
  920.     Dim Taille As Long
  921.     '
  922.     Dim Bloc2 As String
  923.     Dim pos As Long
  924.     '
  925.     'on enleve les caracteres indesirables du debut de la chaine
  926.     'on ne prend que les 50 premiers caracteres de la chaine pour
  927.     'eviter un depassement...
  928.     Data = lTrimS(Left(Data, 50), vbCrLf & vbTab & " ") & Mid(Data, 51)
  929.     '
  930.     'on verifie si on a un retour de ligne
  931.     pos = InStr(1, Data, vbCrLf)
  932.     '
  933.     If pos > 0 Then
  934.         '
  935.         'oui, on separe la taille du chunk du reste des donnees
  936.         Bloc2 = Left(Data, pos - 1)
  937.         Data = Right(Data, Len(Data) - pos - Len(vbCrLf) + 1)
  938.         '
  939.         'on epure notre taille de tout caractere inutile (Cr, Lf, espaces...)
  940.         Bloc2 = lTrimS(Bloc2, vbCrLf & vbTab & " ")
  941.         Bloc2 = rTrimS(Bloc2, vbCrLf & vbTab & " ")
  942.         '
  943.         'on converti le code hex en dec
  944.         ChunkTaille = hex2dec(Bloc2)
  945.         '
  946.         'Debug.Print "chunk: " & ChunkTaille
  947.         '
  948.         'on verifie la taille de ce chunk
  949.         If ChunkTaille <= 0 Then
  950.             '
  951.             'fini, plus de chunk
  952.             ChunkRecFin = True
  953.             '
  954.         Else
  955.             '
  956.             'un nouveau chunk
  957.             '
  958.             'on met a jour la taille totale des donnees a recevoir
  959.             RecTailleTotaleData = RecTailleTotaleData + ChunkTaille
  960.             '
  961.             'on verifie que ce nouveau chunk n en contient pas un autre
  962.             If Len(Data) > ChunkTaille Then
  963.                 '
  964.                 'si, on recupere le chunk connu
  965.                 sRetour = Left(Data, ChunkTaille)
  966.                 '
  967.                 'et on sauve l autre partie dans notre variable globale
  968.                 ResteRecptTemp = Right(Data, Len(Data) - ChunkTaille) & ResteRecptTemp
  969.                 '
  970.                 'on reinitialise qques variables
  971.                 ChunkReste = 0
  972.                 ChunkTaille = 0
  973.                 '
  974.             Else
  975.                 '
  976.                 'pas d autre chunk,on recupere les donnees
  977.                 sRetour = Data
  978.                 '
  979.                 'on definit le reste a recuperer
  980.                 ChunkReste = ChunkTaille
  981.                 '
  982.             End If
  983.             '
  984.         End If
  985.         '
  986.     Else
  987.         '
  988.         'non, on sauve le reste
  989.         ResteRecptTemp = Data & ResteRecptTemp
  990.         '
  991.     End If
  992.     '
  993.     recChunkTaille = sRetour
  994.     '
  995. End Function
  996. '
  997. 'convertion de hex vers dec
  998. Public Function hex2dec(Data As String) As Long
  999.     '
  1000.     Dim total As Long
  1001.     Dim l As Long
  1002.     Dim i As Integer
  1003.     '
  1004.     For i = 1 To Len(Data)
  1005.         '
  1006.         'DoEvents
  1007.         '
  1008.         total = total * 16
  1009.         '
  1010.         'on recupere la position de ce caractere dans la table ascii
  1011.         l = Asc(Mid(Data, i, 1))
  1012.         '
  1013.         'on verifie si c est un chiffre
  1014.         If l < 58 Then
  1015.             '
  1016.             'oui, on soustrait 48 de sorte a retrouver le nombre initial
  1017.             '1 dans la table ascii se trouve a la position 49
  1018.             l = l - 48
  1019.             '
  1020.         Else
  1021.             '
  1022.             'non, c est une lettre (a,b,c,d,e,f)
  1023.             'soustraction pour retrouver la valeur correspondante en hex
  1024.             l = l - 87
  1025.             '
  1026.         End If
  1027.         '
  1028.         'on additionne
  1029.         total = total + l
  1030.         '
  1031.     Next
  1032.     '
  1033.     'et on renvoie la valeur
  1034.     hex2dec = total
  1035.     '
  1036. End Function
  1037. '
  1038. 'on separe les differents headers et on traite les infos recues
  1039. Private Sub traiterHeaders(Data As String, Optional SeparateurSz As String = vbCrLf)
  1040. '    '
  1041.     '**********************************************************
  1042.     '
  1043.     'on separe les differents headers et on les stocke dans un
  1044.     'tableau
  1045.     '
  1046.     '*********************************************************
  1047.     '
  1048.     Dim Bloc1 As String
  1049.     Dim Bloc2 As String
  1050.     Dim pos As Long
  1051.     Dim iH As Integer
  1052.     '
  1053.     'les donnees a traiter
  1054.     Bloc1 = Data
  1055.     '
  1056.     'on fait une boucle jusqu'α ce qu'on arrive α la fin du bloc
  1057.     pos = 1
  1058.     Do Until pos = 0
  1059.         '
  1060.         'DoEvents
  1061.         '
  1062.         'on cherche la position de notre sΘparateur
  1063.         pos = InStr(1, Bloc1, SeparateurSz)
  1064.         '
  1065.         'si la position est > 0 c'est qu'il l'a trouvΘ
  1066.         If pos > 0 Then
  1067.             '
  1068.             'on sΘpare la premiΦre partie du reste du bloc
  1069.             Bloc2 = Left(Bloc1, pos - 1)
  1070.             Bloc1 = Right(Bloc1, Len(Bloc1) - pos - Len(SeparateurSz) + 1)
  1071.             '
  1072.             'on ajoute un element a notre tableau
  1073.             iH = UBound(RecHeaders) + 1
  1074.             '
  1075.             ReDim Preserve RecHeaders(LBound(RecHeaders) To iH)
  1076.             RecHeaders(iH) = Bloc2
  1077.             '
  1078.             'on traite le premier header (reponse code et msg)
  1079.             If iH = 1 Then
  1080.                 '
  1081.                 traiterCodeReponse Bloc2
  1082.                 '
  1083.             Else
  1084.                 '
  1085.                 'on traite ce header normalement
  1086.                 traiterSimpleHeader Bloc2
  1087.                 '
  1088.             End If
  1089.             '
  1090.         Else
  1091.             '
  1092.             'on a fini
  1093.             Exit Do
  1094.             '
  1095.         End If
  1096.         '
  1097.     Loop
  1098.     '
  1099. End Sub
  1100. '
  1101. 'traite le premier header (reponse code et msg)
  1102. Private Sub traiterCodeReponse(Data As String)
  1103.     '
  1104.     'on recupere le code de reponse et le msg http
  1105.     Dim sTmp() As String
  1106.     '
  1107.     sTmp = Split(Data, " ", 3)
  1108.     '
  1109.     If UBound(sTmp) > 0 Then
  1110.         '
  1111.         ReponseHTTP = sTmp(1)
  1112.         '
  1113.     End If
  1114.     
  1115.     If UBound(sTmp) > 1 Then
  1116.         '
  1117.         ReponseMsg = sTmp(2)
  1118.         '
  1119.     End If
  1120.     '
  1121.     'on envoie ces infos
  1122.     RaiseEvent headers("c_http_client_code", ReponseHTTP)
  1123.     RaiseEvent headers("c_http_client_msg", ReponseMsg)
  1124.     '
  1125. End Sub
  1126. '
  1127. 'traite un header simple
  1128. Private Sub traiterSimpleHeader(Data As String)
  1129.     '
  1130.     Dim sTmp() As String
  1131.     Dim pos As Long
  1132.     '
  1133.     sTmp = Split(Data, ":")
  1134.     '
  1135.     'on verifie qu on a bien 2 elements (au-)
  1136.     If UBound(sTmp) > 0 Then
  1137.         '
  1138.         'on epure les infos
  1139.         sTmp(0) = Trim(sTmp(0))
  1140.         sTmp(1) = Trim(sTmp(1))
  1141.         '
  1142.         'on traite ce header
  1143.         Select Case sTmp(0)
  1144.             '
  1145.             'la taille totale des donnees a recevoir
  1146.             Case "Content-Length"
  1147.                 '
  1148.                 RecTailleTotaleData = CLng(sTmp(1))
  1149.                 '
  1150.                 'specifie que la taille totale est definitive
  1151.                 ChunkRecFin = True
  1152.                 '
  1153.             'type de transfert
  1154.             Case "Transfer-Encoding"
  1155.                 '
  1156.                 TransferEncoding = sTmp(1)
  1157.                 '
  1158.                 'specifie que la taille totale n est pas definitive
  1159.                 ChunkRecFin = False
  1160.                 '
  1161.             '
  1162.         End Select
  1163.         '
  1164.         'on informe de la reception de ce header
  1165.         RaiseEvent headers(sTmp(0), sTmp(1))
  1166.         '
  1167.     End If
  1168.     '
  1169. End Sub
  1170. '
  1171. 'recupere la valeur d un header
  1172. Public Function recValHeader(Nom As String) As String
  1173.     '
  1174.     Dim i As Integer
  1175.     Dim iH As Integer
  1176.     '
  1177.     iH = UBound(RecHeaders)
  1178.     '
  1179.     For i = 1 To iH
  1180.         '
  1181.         If LCase(Left(RecHeaders(i), Len(Nom))) = LCase(Nom) Then
  1182.             '
  1183.             recValHeader = Mid(RecHeaders(i), Len(Nom) + 3)
  1184.             '
  1185.             Exit Function
  1186.             '
  1187.         End If
  1188.         '
  1189.     Next
  1190.     '
  1191.     recValHeader = ""
  1192.     '
  1193. End Function
  1194. '
  1195. 'ENVOI DES DONNEES
  1196. Private Sub Env(Data As String)
  1197.     '
  1198.     Form1.txtEnvData = Form1.txtEnvData & Data
  1199.     '
  1200.     'Exit Sub
  1201.     '
  1202.     'on vΘrifie si le socket n'est pas fermΘ
  1203.     If cs.State = sckClosed Then Exit Sub
  1204.     If cs.State = sckClosing Then Exit Sub
  1205.     '
  1206.     'on vΘrifie si le socket est prΩt α envoyer des donnΘes
  1207.     If PretEnvoiSz = False Then
  1208.         '
  1209.         'non, donc on attend
  1210.         '
  1211.         Do Until PretEnvoiSz = True
  1212.             '
  1213.             DoEvents
  1214.             '
  1215.             'on vΘrifie quand mΩme si entre-temps, le socket ne s'est pas fermΘ
  1216.             If cs.State = sckClosed Then Exit Sub
  1217.             If cs.State = sckClosing Then Exit Sub
  1218.             '
  1219.         Loop
  1220.         '
  1221.     End If
  1222.     '
  1223.     PretEnvoiSz = False
  1224.     '
  1225.     'on envoie les donnΘes
  1226.     cs.SendData Data
  1227.     '
  1228. End Sub
  1229. '
  1230. 'on traite les donnees
  1231. Private Sub csTmrReception_Action()
  1232.     '
  1233.     traiterDonneesBrutes
  1234.     '
  1235. End Sub
  1236. '
  1237. 'timeout
  1238. Private Sub csTmrTimeOut_Action()
  1239.     '
  1240.     'on stoppe les timers
  1241.     csTmrReception.Actif = False
  1242.     csTmrTimeOut.Actif = False
  1243.     '
  1244.     'on ferme la connexion
  1245.     cs.CloseSocket
  1246.     '
  1247.     etat = SOCKET_FERME
  1248.     '
  1249.     RaiseEvent timeout
  1250.     '
  1251. End Sub
  1252.