Telechargement de fichier par protocole http 1.0 via socket

Soyez le premier à donner votre avis sur cette source.

Snippet vu 6 424 fois - Téléchargée 15 fois

Contenu du snippet

cet addon vous permet de télécharger un fichier depuis un serveur web sans utiliser de dll

utilisation:
wbs.webget nom-conection my-callback 80 0 http://www.google.fr/intl/fr_fr/images/logo.gif c:/file.gif

explication:
wbs.webget nom-conection [port] [ssl:0/1 (pas testé)] [url] [destination sur le disque]

pour la position courante du fichier: $sock(wbs.webget.nom-conection).rcvd (/help $sock)

pour toute information complémentaire sur le téléchargement en cour:
une hash table est créé sous le nom: wbs.webget.nom-conection avant l'ouverture du socket et est supprimée a la fermeture du socket (apres l'event du callback)

edit:
j'ai ajouté un système de callback, pour cela:
/getfile download my-callback 80 0 http://www.google.fr/intl/fr_fr/images/logo.gif c:/file.gif

si vous ne voulez pas de callback entrez "x" comme nom:
/getfile download x 80 0 http://www.google.fr/intl/fr_fr/images/logo.gif c:/file.gif

edit: j'ai écrit un fichier de manuel pour la fonction: http://www.wbsscript.free.fr/files/man/man%20webge-w32t.txt
en espérant que celui ci puisse vous être utile

Source / Exemple :


alias wbs.webget.version return 1.4

dialog wbs.webget {
  title "Wbs.webget"
  size -1 -1 285 228
  option dbu
  box "Info", 1, 3 3 277 77
  text "Url", 2, 10 16 25 8
  edit "", 3, 41 14 234 10, autohs
  text "Destination", 4, 10 27 29 8
  edit "", 5, 41 25 234 10
  text "port", 6, 10 37 25 8
  edit "80", 7, 41 36 50 10
  button "Go", 8, 165 210 37 12
  box "Debug", 9, 3 81 277 124
  list 10, 7 90 270 110, size
  text "", 11, 9 68 267 8
  check "Mode SSL", 12, 93 36 37 10
  text "CallBack:", 13, 9 58 190 8
  text "", 14, 201 58 75 8
  button "Stop", 15, 125 210 37 12
  button "Pause", 16, 85 210 37 12
  check "headers only", 17, 134 36 46 10
  check "Cookie", 18, 187 36 29 10
  edit "", 19, 217 36 58 10, autohs
  text "", 20, 4 212 76 8
}

on *:dialog:wbs.webget:*:*:{
  if ($devent == init) {
    mdxinit
    wbs.mdx.make.pbar $dname 11:0-0-100
    bdid 19
    if ($sock(wbs.webget.download)) {
      .timerweb.webget.refresh 0 1 wbs.webget.timer.refresh wbs.webget.download $dname 11
      idid 11 1 0 $hget(wbs.webget.download,Content-Length)
    }
    adid 10 Engine version: $wbs.webget.version
    if (!$sslready) {
      bdid 12
      udid 12
      adid 10 Impossible d'utiliser le mode ssl:
      adid 10 Installez openssl-0.9.8i-setup.exe
    }
  }
  elseif ($devent == sclick) {
    var %sockname = wbs.webget.download , %table = wbs.webget.download
    if ($did == 8) {
      if (!$did(3) || !$did(5)) {
        w.err Impossible de satisfaire la requete: arguments manquant.
        return
      }
      rdid 10
      wbs.webget download wbs.webget.callback $did(7) $did(12).state $did(3) $iif(!$did(17).state,$did(5),x)
      .timerweb.webget.refresh 0 1 wbs.webget.timer.refresh wbs.webget.download $dname 11
      writeini $wcfg webget lasturl $did(3)
    }
    elseif ($did == 12) odid 7 1 $iif($did(12).state,443,80)
    elseif ($did == 18) $iif($did(18).state,edid,bdid) 19
    elseif ($did == 15) {
      if ($sock(wbs.webget.download)) {
        wbs.webget.callback wbs.webget.download close $ctime $calc($ctime - $hget(%table,open)) user abord
        sockclose wbs.webget.download
        hfree %table
        adid 10 Connection was closed by user
      }
      else adid 10 Unable to close socket: no such socket
    }
    elseif ($did == 16) {
      if ($version < 6.17) {
        adid 10 Unable to use "pause" : you're version of mirc is $version and need to be at last 6.17 or newer
        return
      }
      if ($sock(wbs.webget.download)) {
        if ($sock(%sockname).pause) adid 10 The socket is already in "pause" mode: trying resume
        else adid 10 Socket was put in "pause" mode: done.
        sockpause $iif($sock(%sockname).pause,-r) %sockname
      }
      else adid 10 Unable to use "pause" : no such socket
    }
  }
  elseif ($devent == dclick) {
    if ($did == 10) wecho $did(10).seltext
  }
  elseif (($devent == edit) && ($did == 3)) odid 5 1 $replace($gettok($did(3),-1,47),$+($chr(37),20),_)
}
alias wbs.webget.callback {
  ;ici un exemple concret d'utilisation de la fonction callback
  var %dname = wbs.webget , %table = wbs.webget.download
  if ($dialog(%dname).title) {
    did -a %dname 10 callback: $1-
    did -o %dname 13 1 CallBack: $2-
    if (($3 == content-lenght) && ($4)) {
      if ($dialog(%dname).title) {
        did -i %dname 11 1 0 $4
        did -o %dname 14 1 / $wsize($4)
        did -a %dname 11 0
      }
    }
    elseif ($2 == ierror) {
      if ($3 == 1) || ($3 == 1) .remove $qt($hget(%table,file-temp))
    }
    elseif ($2 == pre-connect) {
      ;ici un exemple de personalisation du user agent
      hadd -m %table user-agent Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.0.6) Gecko/2009011913 Firefox/2.0.0.14
      if ($did(%dname,18).state) hadd -m %table cookie $$did(%dname,19)
    }
    elseif ($2 == close) {
      var %value = $hget(wbs.webget.download,content-length)
      did -a %dname 11 %value
      did -o %dname 14 1 $wsize(%value) / $wsize(%value)
      did -a %dname 10 Connection closed.
      did -a %dname 10 Conection duration: $duration($4) $calc($5 % 1000) ms
    }
  }
}
alias wbs.webget.timer.refresh {
  ;utilisation: /timer 0 1 wbs.webget.timer.refresh [sockname] [dialogue]
  if (($sock($1)) && ($dialog($2).title)) {
    var %max = $hget(wbs.webget. $+ $gettok($1,3-,46),Content-Length)
    did -a $2 11 $sock($1).rcvd 0 %max
    did -o $2 14 1 $wsize($sock($1).rcvd) / $wsize(%max)
    did -o $2 20 1 Average speed: $wsize($calc($sock($1).rcvd / $sock($1).to)) $+ /s
  }
  else .timerweb.webget.refresh off
}
;################## FIN DE L'EXEMPLE DU DIALOGUE ET DEBUT DU CODE UTILE ##################
alias wbs.server.url return $gettok($$1,2,47)
alias wbs.webget.showstats {
  var %n = $sock(wbs.webget.*,0)
  if (!%n) wecho No socket.
  while (%n > 0) {
    var %sname = $sock(wbs.webget.*,%n) , %rcvd = $sock(%sname).rcvd , %size = $hget(%sname,content-length)
    wecho $qt(%sname) $+($chr(91),type: $sock(%sname).type,$chr(93)) $+($chr(91),port: $sock(%sname).port,$chr(93)) $br(ip: $sock(%sname).ip)  $&
      $br($wsize(%rcvd) / $wsize(%size)) $br($round($calc(%rcvd / %size * 100),2) $+ $chr(37)) $br(from: $duration($sock(%sname).to) ) $&
      $br(pause: $iif($sock(%sname).pause,yes,no)) $br(ssl: $iif($sock(%sname).ssl,yes,no))
    dec %n
  }
}
;ici je préfere faire une alias vers mon alias car je préfere employer mon alias car "getfile" peu etre un nom attribué dans d'autres scripts
alias getfile {
  if ($1) wbs.webget $1-
  else wbs.webget.showstats
}
alias -l br return $+($chr(91),$1-,$chr(93))
alias wbs.webget {
  ;6 arguments requis: nom,alias de callback,port,ssl (0/1),url,destination
  ;exemple: wbs.webget download callback 80 0 http://www.google.fr/intl/fr_fr/images/logo.gif c:/file.gif
  ;il est possible de spécifier un user-agent personalisé en l'entran manuelement dans la table AVANT l'appel de la commande wbs.webget ou getfile
  ;syntaxe: wbs.webget.[nom-de-la-conection] user-agent
  ;exemple: hadd -m %table wbs.webget.download user-agent mIrc $version
  if ($5) {
    var %table = wbs.webget. $+ $1
    ;ici je préfere aussi laisser a l'utilisateur de pouvoir formuler lui même sa requette GET s'il le shouaite
    if (!$hget(%table,get)) hadd -m %table get $5
    if ($6 != x) hadd -m %table file $6-
    hadd -m %table mode 0
    hadd -m %table ctime $ctime
    hadd -m %table name $1
    if (!$hget(%table,redirects-left)) hadd -m %table redirects-left 16
    if (!$hget(%table,file-temp)) hadd -m %table file-temp $1 $+ .temp
    if ($exists($hget(%table,file-temp))) callback %table ierror 1 $qt($hget(%table,file-temp)) already exists
    if ($2 != x) hadd %table callback $2
    if ($sock(wbs.webget. $+ $1)) {
      callback wbs.webget. $+ $1 info hard-sockclose
      sockclose wbs.webget. $+ $1
    }
    callback %table pre-connect
    sockopen $iif($4 == 1,-e) $+(wbs.webget.,$1) $wbs.server.url($5) $3
  }
  else wecho $sname error: wbs.webget: syntax: /wbs.webget [name] [callback alias ("x" if not)] [port] [ssl (0/1)] [url] [destination]
}
alias wsockwrite {
  sockwrite $1-
  if ($hget($2,callback)) $v1 $2 sockwrite $1-
}
alias -l callback {
  ;utilisation: callback [htable] alias de callback
  ;todo permrete l'utilisation de plusieures fonction de callback succesives séparées par des ","
  if (($hget($1,callback)) && ($isalias($hget($1,callback)))) $hget($1,callback) $1-
}
alias -l sname return wbs.webget
on *:sockopen:wbs.webget.*:{
  var %table = $sockname
  hadd -m %table open $ctime $ticks
  callback %table info open $ctime $ticks
  callback %table info serverip $sock($sockname).ip $sock($sockname).port
  if ($hget(%table,post)) wsockwrite -n $sockname POST $v1 HTTP/ $+ $iif($hget(%table,http-version),$v1,1.0)
  else wsockwrite -n $sockname GET / $+ $gettok($hget(%table,get),3-,47)) HTTP/ $+ $iif($hget(%table,http-version),$v1,1.0)
  if ($hget(%table,Authorization)) wsockwrite -n $sockname Authorization: $v1
  if (!$hget(%table,no-referer)) wsockwrite -n $sockname Referer: $iif($hget(%table,referer),$v1,http://wbsscript.free.fr/)
  if ($hget(%table,accept)) wsockwrite -n $sockname Accept: $v1
  if ($hget(%table,connection)) wsockwrite -n $sockname Connection: $v1
  if ($hget(%table,cache-control)) wsockwrite -n $sockname Cache-Control: $v1  
  if ($hget(%table,cookie)) wsockwrite -n $sockname Cookie: $v1
  if (!$hget(%table,no-user-agent)) wsockwrite -n $sockname User-Agent: $iif($hget(%table,user-agent),$v1,CERN-LineMode/2.15 libwww/2.17)
  wsockwrite -n $sockname Host: $iif($hget(%table,host),$v1,$wbs.server.url($hget(%table,get))) $+ $crlf $+ $crlf

}
;ici le but de l'interpreteur est de clarifier le code dans la fonction du socket, le socket contien cependent la gestion des erreures
alias wbs.webget.interpreter {
  var %buffer = $2- , %table = $1 , %errors = 400;404;500;403, %err = 0
  tokenize 32 $2-
  if ($gettok($1,1,47) == HTTP) {
    hadd -m %table http  $2-
    callback %table http $2-
  }
  elseif ($1 == Content-Length:) {
    hadd -m %table Content-Length $2
    callback %table info content-lenght $2
  }
  elseif ($1 == Set-Cookie:) {
    hadd -m %table cookie $2-
    callback %table cookie $2-
  }
  elseif ($1 == Location:) {
    var %location = $2
    if (($left(%location,7) != http://) && ($left(%location,8) != https://)) var %location = $+(http://,$sock($sockname).ip,$2)
    var %arguments = $hget(%table,name) $iif($hget(%table,callback),$v1,x) $sock($sockname).port $iif($sock($sockname).ssl,1,0) %location $iif($hget(%table,file),$v1,x)
    sockclose $sockname
    callback %table error $hget(%table,http) $2-
    hdec %table redirects-left
    if ($hget(%table,redirects-left) <= 0) {
      callback %table ierror 2 too many redirections
      hfree %table
      return
    }
    hadd -m %table get %location
    callback %table reconnect %arguments
    wbs.webget %arguments
  }
}

on *:sockread:wbs.webget.*:{
  var %buffer = $null , %table = $sockname , %errors = 400;404;500;403, %err = 0 , %writefile = $qt($hget(%table,file-temp))
  while ((!$sockerr) && (!%err)) {
    if ($hget(%table,mode) == 0) {
      sockread %buffer
      tokenize 32 %buffer
      wbs.webget.interpreter $sockname %buffer
      callback %table buffer %buffer
      if ($1 == Location:) inc %err
      elseif ($istok(%errors,$2,59)) {
        sockclose $sockname
        var %err = $2
        callback %table error %err $calc($ctime - $hget(%table,start-time))
        hfree %table
        break
      }
      elseif (!%buffer) {
        ;ce passage marque la fin des headers intervient juste avant le debut du transfer binaire
        if (($hget(%table,Content-Length) == 0) || (!$hget(%table,file))) {
          callback %table close $ctime $calc($ctime - $hget(%table,ctime)) $ticks no-data
          sockclose $sockname
          hfree %table
          break
        }
        hadd -m %table mode 1
        hadd -m %table safemode 1
      }
    }
    elseif ($hget(%table,mode) == 1) {
      ;mode binaire (traitement)
      sockread &buffer
      ;la ligne ci dessous est surtout la pour éviter le bug des crlf lié a mirc qui les efface comme un malpropre, a modiffier
      if ($bvar(&buffer,0,5).text != $crlf) {
        if ($hget(%table,safemode)) {
          hdel %table safemode
          callback %table info start $ctime
          hadd -m %table start-time $ctime
        }
      }
      if (!$hget(%table,safemode)) {
        ;ici je préfere remetre une sous boucle pour ne pas avoir a ré-interpreter toutes les autres conditions
        bwrite %writefile -1 &buffer
        while ((!$sockerr) && (!%err)) {
          sockread &buffer
          bwrite %writefile -1 &buffer
          if ($sockbr == 0) break
        }
      }
    }
    if ($sockbr == 0) break
  }
  if ($sockerr) callback %table error sockerr $sockerr
}
on *:sockclose:wbs.webget.*:{
  var %table = $sockname , %file = $qt($hget(%table,file))
  if ($exists(%file)) .remove %file
  if ($hget(%table,mode)) .rename $qt($iif($hget(%table,file-temp),$v1,$+($mircdir,$sockname,.temp))) %file
  callback %table file %file
  callback %table close $ctime $calc($ctime - $hget(%table,open)) $ticks finished
  hfree %table
}
alias wbs.webget.timer.callback {
  ;utilisation: /.timerwbs.webget.timer.callback 0 1  wbs.webget.timer.callback [sockname] [alias]
  ;effet: appele [alias] et retourne: [sockname] [position actuelle] [durée de la conection]
  if (($sock($1)) && ($isalias($2))) {
    $2 $sock($1).rcvd $hget(wbs.webget. $+ $gettok($1,3-,46),Content-Length)
    if (!$timer(wbs.webget.timer.callback)) .timerwbs.webget.timer.callback 0 1  wbs.webget.timer.callback $1 $2
  }
  else .timerwbs.webget.timer.callback off
}

;#aliases de compatibilitées
alias -l wbs.mdx.make.pbar {
  ;usage: wbs.mdx.make.pbar $dname id:0-0-100
  ;values: defaut-debut-fin
  var %dname = $1 , %target = $gettok($2,1,58) , %values = $replace($gettok($2,2,58),-,$chr(32))
  if ($dialog(%dname).title) {
    wbs.mdx SetControlMDX %dname %target ProgressBar > $wdll(ctl_gen.mdx)
    did -i %dname %target 1 $gettok(%values,2-,32)
    did -a %dname %target $gettok(%values,1,32)
  }
}

;alias de compatibilitée pour exportation du code
alias -l wdll return $qt($+($scriptdir,dlls\,$1))
alias -l w.err adid 10 $1-
alias -l idid did -i $dname $1-
alias -l adid did -a $dname $1-
alias -l rdid did -r $dname $1-
alias -l odid did -o $dname $1-
alias -l bdid did -b $dname $1-
alias -l udid did -u $dname $1-
alias -l wecho echo -a $1-
alias -l wsize {
  if ($1 !isnum 0-) return n/a 
  else return $replace($lower($bytes($1-,3).suf $+ $iif($right($bytes($1-,3).suf,1) !== b,b)),b,b)
}
;uniquement pour le gui:
alias -l wbs.mdx.make.pbar {
  ;usage: wbs.mdx.make.pbar $dname id:0-0-100
  ;values: defaut-debut-fin
  var %dname = $1 , %target = $gettok($2,1,58) , %values = $replace($gettok($2,2,58),-,$chr(32))
  if ($dialog(%dname).title) {
    wbs.mdx SetControlMDX %dname %target ProgressBar > $wdll(ctl_gen.mdx)
    did -i %dname %target 1 $gettok(%values,2-,32)
    did -a %dname %target $gettok(%values,1,32)
  }
}

Conclusion :


je ne met pas les aliases "mdxinit" et "mdx" car celles ci sont déjà tellement répandues que je préfère ne pas les mettre pour éviter des confits

#FACULTATIF ! (interface uniquement: useless)
placez les dlls de mdx dans le dossier "dlls/" la ou se trouve le script, si vous les avez deja ailleurs moddifiez la fonction "wdll" (a la la fin du code)
(je met ca car chez moi le wdll fait appels a bien trop de sous fonction (utilisation d'un cache)

je suis bien évidement ouvert a toute idée d'amélioration

A voir également

Ajouter un commentaire

Commentaires

Messages postés
266
Date d'inscription
lundi 19 mai 2003
Statut
Membre
Dernière intervention
7 juillet 2009

le manuel se trouve maintenant ici:
http://www.wbsscript.free.fr/files/man/wbs.webget.txt
Messages postés
150
Date d'inscription
mardi 15 juin 2004
Statut
Membre
Dernière intervention
24 août 2010
2
Bien foutu, complet et commenté, que demandes le peuple ? :)
Vraiment une bonne idée d'application des sockets, et la fonction pour le callback c'est vraiment bien vu ! 9/10, la perfection n'existe pas^^
Messages postés
266
Date d'inscription
lundi 19 mai 2003
Statut
Membre
Dernière intervention
7 juillet 2009

Voila je viens de mètre à jours, la grande nouveauté cette fois ci c'est la possibilité d'utiliser la fonction en mode "headers" uniquement si besoin, étant en train de coder un client msn en mirc script j'avais besoin de récupérer des headers pour l'authentification au service et pour cela je devais envoyer des headers non standards, j'ai donc ajouté les fonctionnalité au code (j'ai mis le manuel à jours)
cas ajoutées:
hadd -m %table connection Keep-Alive [peu etre ce que vous voulez a la place de keep-alive, generalement "close" par defaut)
hadd -m %table Authorization [parametres]
hadd -m %table http-version 1.1 (permet ici de dire au serveur que l'on utilise http 1.1 au lieu de 1.0 par defaut)

voila j'espere que cela vous sera aussi utile qu'a moi :)
Messages postés
266
Date d'inscription
lundi 19 mai 2003
Statut
Membre
Dernière intervention
7 juillet 2009

un petit exemple tout simple:

dialog wbs.getimage {
title "Wbs.getimage"
size -1 -1 292 244
option dbu
edit "", 1, 3 9 248 10
button "Get", 2, 252 7 37 12
icon 3, 3 21 285 219
}

on *:dialog:wbs.getimage:sclick:2:{
wbs.webget wbs-getimage wbs.getimage.callback 80 0 $did(1) image.jpg
}
alias wbs.getimage.callback {
if ($2 == close) did -g wbs.getimage 3 image.jpg
}
éssaie avec: http://www.ircfr.com/gdi/um/857098.cs.jpg
ou n'importe quelle autre image.jpg sur le web
j'espère que mon exemple sera suffisamment concret :)
l'idée n'est pas de ré-inventer le téléchargement mais plutôt de permettre aux scripteurs d'améliorer les gestionnaire de mises a jours par exemple
Messages postés
26
Date d'inscription
lundi 11 septembre 2006
Statut
Membre
Dernière intervention
5 mars 2009

"Un exemple fameux de se code, serait de faire un system de lecteur d'image, ya toujours plein de gens qui poste des liens, bah avec ce genre de truc, on pourrait voir l'image sans même changer d'application :)"
Tu reponds partout parfaitement à ma question, et j'adore ton idée :)
Ps: Je ne cherchais surtout pas à critiquer ce code, je cherchais plutot une raison de le prendre ;)
Afficher les 12 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.