# Ruby ha un nuovo Whois

**URL:** <https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428>\
**Category:** IT\
**Created:** [August 8, 2009, 3:42pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428 "2009-08-08T15:42:09Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 8, 2009, 3:42pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/1 "2009-08-08T15:42:09Z")

</div>

Vorrei segnalarvi che ho aperto ieri pubblicamente il repository di una  
libreria Whois scritta in pure Ruby.  
Il repository si trova all’indirizzo [GitHub - weppos/whois: An intelligent — pure Ruby — WHOIS client and parser.](http://github.com/weppos/whois)  
mentre  
il progetto è [http://code.simonecarletti.com/whois](http://code.simonecarletti.com/whois).  
La libreria non è ancora stata rilasciata sotto forma di GEM.

In questi mesi sto lavorando ad un progetto Ruby/Rails che basa una  
fetta  
importante del suo funzionamento su interrogazioni whois per ottenere  
informazioni sui domini. Quando cominciai, a maggio, investigai il  
panorama  
dei whois Ruby esistenti ed il risultato fu disastroso. Erano tutti  
incompleti, non aggiornati o dipendenti da altre librerie come il  
famosissimo package Whois per Linux sviluppato da Marco d’Itri.

Utilizzare il whois di Marco era un’alternativa, ma c’erano due problemi  
a  
riguardo

1. Ruby non è molto veloce nell’eseguire chiamate a binari di sistema  
(ad  
esempio, motivo per cui GitHub ha sviluppato Grit)
2. La soluzione non era flessibile (niente controllo sulla libreria,  
errori, eccezioni…)

Così ho deciso di sviluppare una soluzione in pure Ruby che potesse  
offrire  
la maggior parte delle funzioni necessarie. Ho anche contattato Marco  
d’Itri  
per alcune delucidazioni sul sorgente della sua lib C.

Mi piacerebbe avere qualche parere sul risultato. Qualcuno di voi ha mai  
avuto esigenza di eseguire interrogazioni Whois?

La libreria sarà disponibile con licenza MIT. Ho contattato lo  
sviluppatore  
della GEM Whois originale che mi ha gentilmente concesso le chiavi del  
progetto su RubyForge. La nuova libreria rimpiazzerà quindi l’attuale GEM  
Whois offrendo un’API più completa ed aggiornata.

Conto di rilasciare la lib entro  
lunedì.Ogni feedback o critica è bene accetta, inclusi eventuali commenti sul  
codice.

–  
Simone C.

Site & Blog: [http://www.simonecarletti.com](http://www.simonecarletti.com)  
Email: removed\_email\_address@domain.invalid  
LinkedIn: [http://linkedin.com/in/weppos](http://linkedin.com/in/weppos)  
Nick: weppos | Skype: weppos

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 9, 2009, 12:48pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/2 "2009-08-09T12:48:30Z")

</div>

Simone C. wrote:

> Mi piacerebbe avere qualche parere sul risultato. Qualcuno di voi ha mai  
> avuto esigenza di eseguire interrogazioni Whois?

Non ho ancora provato il tuo programma ma mi capita di fare query whois  
per verificare l’esistenza di dominii e tutto sommato poterne dare un  
elenco in pasto ad un programma potrebbe risparmiare un po’ di tempo.

Mi fa piacere vedere che usi redmine, Ã¨ il sw che uso pure io per tutti  
i miei progetti 🙂

Paolo

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 9, 2009, 1:41pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/3 "2009-08-09T13:41:30Z")

</div>

Ciao Paolo,  
sì, uso Redmine per i miei progetti ma anche in azienda lo usiamo come  
issue  
tracker per ogni progetto.

Approfitto per segnalarti che da qualche ora la nuova versione della  
libreria è anche disponibile via RubyGems,

> **[Ruby has a new WHOIS library — Simone Carletti](https://simonecarletti.com/blog/2009/08/ruby-has-a-new-whois-library/)**
>
> Today I'm announcing the availability of a new Whois library written in pure Ruby.

[http://rubyforge.org/forum/forum.php?forum\_id=34130](http://rubyforge.org/forum/forum.php?forum_id=34130)

Quando avrai modo di provarla, fammi sapere cosa ne pensi. 🙂

– Simone

2009/8/9 Paolo M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> ## Paolo
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> * * *
> 
> Ml mailing list  
> removed\_email\_address@domain.invalid  
> [http://lists.ruby-it.org/mailman/listinfo/ml](http://lists.ruby-it.org/mailman/listinfo/ml)

–  
Simone C.

Site & Blog: [http://www.simonecarletti.com](http://www.simonecarletti.com)  
Email: removed\_email\_address@domain.invalid  
LinkedIn: [http://linkedin.com/in/weppos](http://linkedin.com/in/weppos)  
Nick: weppos | Skype: weppos

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 10, 2009, 9:52am UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/4 "2009-08-10T09:52:50Z")

</div>

Simone C. wrote:

> Ciao Paolo,  
> sï¿½, uso Redmine per i miei progetti ma anche in azienda lo usiamo come  
> issue  
> tracker per ogni progetto.
> 
> Approfitto per segnalarti che da qualche ora la nuova versione della  
> libreria ï¿½ anche disponibile via RubyGems,
> 
> [Ruby has a new WHOIS library — Simone Carletti](http://www.simonecarletti.com/blog/2009/08/ruby-has-a-new-whois-library/)  
> [http://rubyforge.org/forum/forum.php?forum\_id=34130](http://rubyforge.org/forum/forum.php?forum_id=34130)
> 
> Quando avrai modo di provarla, fammi sapere cosa ne pensi. 🙂

Ciao Simone,

ho installato la gemma e l’ho provata. Funziona e i vantaggi rispetto ad  
una ricerca manuale ci sono anche se non sono poi cosÃ¬ grandi. Mi  
piacerebbe infatti avere una risposta automatica sull’esistenza o meno  
del dominio e poter estrarre delle informazioni dalla risposta del  
server.

Non Ã¨ semplice, dato che ogni registrar presenta i dati in un formato  
diverso, ma ho sviluppato un rapido concept. API e implementazione sono  
molto provvisori.

Nella dir della gemma aggiungiamo il file lib/info.rb (facendone require  
in whois.rb) con questo contenuto

* * *

module Whois  
class Info  
attr\_reader :registrar, :whois\_server, :url, :name\_servers,  
:statuses,  
:registrant, :technical\_contact,  
:administrative\_contact,  
:created\_at, :updated\_at, :expires\_at

```
def initialize(info_lines)
  @registrant = []
  @technical_contact = []
  @administrative_contact = []
  @names = []
  @contact_ids = []
  @name_servers = []
  @statuses = []
  @exists = true
  info_lines.split("\n").each do |line|
    # available domain detection part 1
    if line.match /No match for/
      @exists = false
      break
    end
    name, value = line.split(": ")
    next unless value
    next if name.match /NOTICE|TERMS OF USE/
    @registrar = value if name.match /Registrar/
    @whois_server = value if name.match /Whois Server/
    @url = value if name.match /Referral URL/
    @registrant << value if name.match /Registrant/
    @technical_contact << value if name.match /Technical/
    @administrative_contact << value if name.match /Administrative/
    @name_servers << value if name.match /Name Server/
    @statuses << value if name.match /Status/
    @created_at = value if name.match /Creation Date|Created/
    @updated_at = value if name.match /Updated Date|Updated|Last 

```

Update/  
@expires\_at = value if name.match /Expiration  
Date|Expires|Expire Date/  
end  
end

```
def exists?
  # available domain detection part 2, more euristics required
  return false if @statuses.length == 1 && @statuses[0].gsub(" ", 

```

“”) == “AVAILABLE”  
@exists  
end

end  
end

* * *

poi siamo in grado di scrivere codice come

* * *

require ‘rubygems’  
require ‘whois’

domain = ARGV[0]  
response = Whois.whois(domain)  
info = Whois::Info.new(response)  
unless info.exists?  
puts “No match for #{domain}”  
exit  
end

## puts “Registrar #{info.registrar}” puts “Server #{info.whois\_server}” puts “Registrant #{info.registrant.join(”, “)}” puts “Tech contact #{info.technical\_contact.join(”, “)}” puts “Adm contact #{info.administrative\_contact.join(”, “)}” puts “Name servers #{info.name\_servers.join(”, “)}” puts “Status #{info.statuses.join(”, “)}” puts “Created at #{info.created\_at}” puts “Updated at #{info.updated\_at}” puts “Expires at #{info.expires\_at}”

e chiamare il programma con

$ ruby whois\_test.rb [google.com](http://google.com)  
$ ruby whois\_test.rb simonecarletti.it  
$ ruby whois\_test.rb [simonecarletti.com](http://simonecarletti.com)  
$ ruby whois\_test.rb [asdfasdfasdf.com](http://asdfasdfasdf.com) (sorpresa!)  
$ ruby whois\_test.rb [asdfasdfasdf123123.com](http://asdfasdfasdf123123.com)  
$ ruby whois\_test.rb asdfasdfasdf123123.it

Probabilmente l’euristica per estrarre le informazioni andrebbe messa in  
una serie di adapter per i vari registrar (ora riesce ad estrarre  
informazioni solo in pochi casi) e sicuramente si tratta di un  
lavoraccio. Tuttavia se il progetto coinvolgesse molti sviluppatori ed  
ognuno si scrivesse l’adapter per uno dei propri registrar lo sforzo per  
il singolo sarebbe ragionevole. La cosa difficile sarÃ coordinare gli  
sviluppi stabilendo l’organizzazione delle informazioni estratte. Nota  
poi che il client whois di linux giÃ fa un’aggregazione perchÃ© spesso  
prima della risposta del server presenta un riassunto con un minimo di  
informazioni. Ad esempio:

Domain Name: [ASDFASDFASDF.COM](http://ASDFASDFASDF.COM)  
Registrar: NAMEVIEW, INC.  
Whois Server: [whois.nameview.com](http://whois.nameview.com)  
Referral URL: [http://www.nameview.com](http://www.nameview.com)  
Name Server: [NS1.HITFARM.COM](http://NS1.HITFARM.COM)  
Name Server: [NS2.HITFARM.COM](http://NS2.HITFARM.COM)  
Status: clientTransferProhibited  
Updated Date: 12-mar-2009  
Creation Date: 19-mar-2002  
Expiration Date: 19-mar-2010

ChissÃ che scavando nei suoi sorgenti non si possa recuperare del codice  
da portare a Ruby.

Un’ultima cosa: l’API della demo non mi soddisfa. Whois::Info potrebbe  
sparire e i metodi per leggere i suoi attributi dovrebbero forse essere  
metodi del client, ma in fondo Ã¨ solo del codice scritto per spiegarmi  
meglio.

Che ne dici? Comunque Ã¨ giÃ un buon progetto perchÃ© se non lo fosse non  
ci si potrebbe costruire sopra del sw in un’oretta, post sul forum  
incluso 🙂

Ciao  
Paolo

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 10, 2009, 6:59pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/5 "2009-08-10T18:59:06Z")

</div>

Come al solito… spettacolo !  
Ho forkato la libreria, se posso contribuire fammi sapere 🙂  
In ogni caso adesso gli do’ un’occhiata

Sandro

2009/8/10 Simone C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 10, 2009, 10:06am UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/6 "2009-08-10T10:06:23Z")

</div>

Ciao Paolo

2009/8/10 Paolo M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Mi piacerebbe infatti avere una risposta automatica sull’esistenza o meno  
> del dominio e poter estrarre delle informazioni dalla risposta del  
> server.

hai perfettamente ragione ed è il prossimo macro obiettivo, l’unico  
infatti  
che ho voluto inserire nella Roadmap nella documentazione della lib.

> Non è semplice, dato che ogni registrar presenta i dati in un formato  
> diverso,

Il punto è proprio questo. Inoltre si somma un problema. Quando il whois  
server è di tipo thin, come nel caso dei .com o .tv, esistono due  
risposte:  
quella del whois padre e quella del whois specifico.  
Entrambe sono ovviamente in formati specifici.

Non solo, GoDaddy risponde in modo diverso da Tucows dunque anche  
all’interno della stessa estensione esistono differenze sostanziali.

> Probabilmente l’euristica per estrarre le informazioni andrebbe messa in  
> una serie di adapter per i vari registrar (ora riesce ad estrarre  
> informazioni solo in pochi casi) e sicuramente si tratta di un  
> lavoraccio. Tuttavia se il progetto coinvolgesse molti sviluppatori ed  
> ognuno si scrivesse l’adapter per uno dei propri registrar lo sforzo per  
> il singolo sarebbe ragionevole. La cosa difficile sarà coordinare gli  
> sviluppi stabilendo l’organizzazione delle informazioni estratte.

In realtà il mio obiettivo sarebbe quello di non presentare un sistema  
euristico bensì dotare la libreria di un parser per ogni whois server.  
Fortunatamente, ogni whois ha una risposta univoca per cui la mia idea  
era  
di ritornare come risposta un oggetto che estende stringa (per  
compatibilità  
con l’implementazione attuale) che salvi al suo interno anche l’oggetto  
@server.

Si potrà quindi fare

d = Whois::Client.new.query(“[weppos.com](http://weppos.com)”)

# =\> stringa registry

d = Whois::Client.new.find(“[weppos.com](http://weppos.com)”)

# =\> oggetto decomposto

d.available?

# =\> false

d.contacts.first.name

# =\> Simone C.

d.nameservers

# =\> [“192.168.0.1”, “192.168.0.1”]

…

L’API è provvisoria. L’idea è quella di avere una lista di oggetti/attributi  
normalzzati al quale ricondurre ogni risposta del whois. Ovviamente ci  
saranno alcuni shortcut come

Whois.whois(“[weppos.com](http://weppos.com)”)

# =\> stringa

Whois.available?(“[weppos.com](http://weppos.com)”)

# =\> false

> Nota  
> poi che il client whois di linux già fa un’aggregazione perché spesso  
> prima della risposta del server presenta un riassunto con un minimo di  
> informazioni. Ad esempio:

Sì, è un bug noto. Al momento non concateno le risposte nel caso di un thin  
server.  
[http://code.simonecarletti.com/issues/show/259](http://code.simonecarletti.com/issues/show/259)

Che ne dici? Comunque è già un buon progetto perché se non lo fosse non

> ci si potrebbe costruire sopra del sw in un’oretta, post sul forum  
> incluso 🙂

Grazie! 🙂

–  
Simone C.

Site & Blog: [http://www.simonecarletti.com](http://www.simonecarletti.com)  
Email: removed\_email\_address@domain.invalid  
LinkedIn: [http://linkedin.com/in/weppos](http://linkedin.com/in/weppos)  
Nick: weppos | Skype: weppos

---

<div class="post-metadata">

**Author:** ![overclokkato](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/o/c67d28/32.png) [@overclokkato](https://www.ruby-forum.com/u/overclokkato)\
**Post date:** [August 11, 2009, 3:27pm UTC](https://www.ruby-forum.com/t/ruby-ha-un-nuovo-whois/173428/7 "2009-08-11T15:27:13Z")

</div>

2009/8/10 Sandro P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

> Ho forkato la libreria, se posso contribuire fammi sapere 🙂

Un paio di mani ed una tastiera in più fanno sempre comodo. 😃

In ogni caso adesso gli do’ un’occhiata

> 

Ogni feedback è bene accetto.

A proposito di questo vi segnalo che

- E’ uscita la release 0.5.1 che integra una utility eseguibile da  
command line, ad esempio $ ruby-whois [google.com](http://google.com). Utile soprattutto a  
chi  
non ha utility whois perché si trova su un sistema operativo Windows.
- La nuova release corregge il problema segnalato da Paolo riguardo  
ai  
Whois thin (esempio il .com)

Dulcis in fundo, prima di fuggire al mare ho appena eseguito il commit  
della  
nuova architettura con il supporto ai parser.  
Ho preparato, come esempio, un primissimo parser per i domini .it.  
Il tutto è disponibile in una branch sperimentale  
[http://github.com/weppos/whois/tree/response](http://github.com/weppos/whois/tree/response)

Ora è possibile eseguire comandi tipo

require ‘whois’

Whois.available? “weppos.it”

# =\> false

r = Whois.query(“weppos.it”)  
r.available?

# =\> false

r.status

# =\> :active

r.expires\_on

# =\> Time.new(“2009-12-21”)

Per commenti o altro è disponibile una mailing list specifica così evito di  
monopolizzare questa. 😉  
[http://groups.google.com/group/ruby-whois](http://groups.google.com/group/ruby-whois)

Grazie a tutti i per i feedback ricevuti fino ad ora.

–  
Simone C.

Site & Blog: [http://www.simonecarletti.com](http://www.simonecarletti.com)  
Email: removed\_email\_address@domain.invalid  
LinkedIn: [http://linkedin.com/in/weppos](http://linkedin.com/in/weppos)  
Nick: weppos | Skype: weppos
