Page 1 sur 1

Requête POST (Avec les Sockets)

Publié : mer. 02/mai/2012 17:06
par stombretrooper
Salut à tous !

J'ai galéré de mon côté pour faire une fonction 'POST' en utilisant les Sockets, étant donnée le temps que j'y ai passé (à cause d'une faute dans ma requête !), je partage, histoire qu'on soit pas plusieurs à se taper l'implantation d'une telle fonction, qui peut être sacrément utile pour mettre en place une communication application <=> site web.

Je précise que variables doit prendre des valeurs sous cette forme ;
nom_variable1=valeur_1&variable2=valeur2&variable3=valeur3

Code : Tout sélectionner

;-*****************************************************************************
;-*                                 Requête POST                              *
;-*                                                                           *
;-*                            Auteur : stombretrooper                        *
;-*                                Libre de droits.                           *
;-*****************************************************************************


CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  If WSAStartup_($101, @wsaData)<>#NO_ERROR
    End
  EndIf
CompilerEndIf



;Taille du buffer de reception :
#ReceptionDataBuffer = 50*1024

Procedure.s Post(url.s, variables.s)
  ;Décomposition de l'url :
  hote.s = GetURLPart(url.s, #PB_URL_Site)
  fichier.s = GetURLPart(url, #PB_URL_Path) + GetURLPart(url.s, #PB_URL_Parameters)
  
  ;Récupération de l'IP en fonction du nom de domaine :
  *host.HOSTENT = gethostbyname_(hote)
  Dim ip.a(4)
  *pointeur_ip = PeekI(*host\h_addr_list)
  CopyMemory(*pointeur_ip, @ip(), 4)
  ip.s = Str(ip(0))+"."+Str(ip(1))+"."+Str(ip(2))+"."+Str(ip(3))
  
  ;Génération de la requête :
  requete.s = "POST /"+fichier+" HTTP/1.1" + #CRLF$
  requete + "Host: "+hote + #CRLF$
  requete + "User-Agent:Mozilla/4.0" +#CRLF$
  requete + "Connection: Close" + #CRLF$
  requete + "Accept-Encoding: chunked" + #CRLF$
  requete + "Content-type: application/x-www-form-urlencoded" + #CRLF$
  requete + "Content-Length: "+ Str(Len(variables)) + #CRLF$ + #CRLF$
  requete + variables 
  
  ;Buffer de reception :
  *reception = AllocateMemory(#ReceptionDataBuffer)
  receptionlen = #ReceptionDataBuffer - 1
  
  ;Création du socket & connection :
  socket = SOCKET_(#AF_INET, #SOCK_STREAM, #IPPROTO_TCP)
  If socket = #INVALID_SOCKET
    ProcedureReturn "error_socket"
  EndIf
  service.sockaddr_in
  service\sin_addr = inet_addr_(ip)
  service\sin_family = #AF_INET
  service\sin_port = htons_(80)
  *ptr = @service
  If connect_(socket, *ptr, SizeOf(sockaddr_in)) = #SOCKET_ERROR
    ProcedureReturn "error_connection"
  EndIf
  
  ;Envoie de la requête :
  send_(socket, @requete, Len(requete), 0)
  
  ;Récupération des données :
  *size = 0
  Repeat
    recv_(socket, *reception + *size, 1, 0)
    *size + 1
  Until PeekS(*reception + *size - 1, 2) = "0" + #CRLF$ Or *size >= receptionlen
  
  ;Renvoie du résultat :
  retour.s = PeekS(*reception)
  FreeMemory(*reception)
  ProcedureReturn retour
EndProcedure

Debug Post("http://www.google.fr","")


CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  WSACleanup_()
CompilerEndIf
Je suis pas très satisfait de ma manière de récupérer le résultat de la requête. Mais vue que recv_ est bloquant, j'ai pas eue trop d'idée. Pour le moment je m'arrête de "lire" quand on a complètement remplis le buffer OU que le caractère 0 + #CRLF est reçu (sur le système d'envoie par morceau en HTTP, le dernier morceau contient ça pour dire qu'il a finis de transférer les morceaux).

Re: Requête POST (Avec les Sockets)

Publié : ven. 04/mai/2012 15:52
par stombretrooper
Petite correction, le script contenait un bug au niveau du code qui permettait de récupérer une IP à partir d'un nom de domaine.

Re: Requête POST (Avec les Sockets)

Publié : ven. 04/mai/2012 21:00
par Kwai chang caine
Merci 8)