whois-parser-next 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -1
  3. data/README.md +31 -12
  4. data/RELEASING.md +2 -2
  5. data/ROADMAP.md +20 -15
  6. data/SECURITY.md +2 -2
  7. data/lib/whois/parser/version.rb +1 -1
  8. data/lib/whois/parsers/base_centralnic_icann.rb +12 -0
  9. data/lib/whois/parsers/base_cira_registry.rb +19 -0
  10. data/lib/whois/parsers/base_icann_compliant.rb +1 -1
  11. data/lib/whois/parsers/base_identity_digital.rb +12 -0
  12. data/lib/whois/parsers/base_jwhois.rb +48 -0
  13. data/lib/whois/parsers/base_nic_reserved_available.rb +17 -0
  14. data/lib/whois/parsers/base_reserved_registry.rb +27 -0
  15. data/lib/whois/parsers/base_top1000_icann.rb +39 -0
  16. data/lib/whois/parsers/base_top1000_retired.rb +26 -0
  17. data/lib/whois/parsers/base_unsupported_registry.rb +1 -1
  18. data/lib/whois/parsers/cwhois.cnnic.cn.rb +10 -0
  19. data/lib/whois/parsers/registry_response_safety.rb +2 -0
  20. data/lib/whois/parsers/whois.ax.rb +15 -3
  21. data/lib/whois/parsers/whois.cctld.uz.rb +50 -14
  22. data/lib/whois/parsers/whois.cnnic.cn.rb +31 -3
  23. data/lib/whois/parsers/whois.dominio.gq.rb +11 -0
  24. data/lib/whois/parsers/whois.dotukr.com.rb +23 -0
  25. data/lib/whois/parsers/whois.gtld.knet.cn.rb +10 -0
  26. data/lib/whois/parsers/whois.kyregistry.ky.rb +10 -0
  27. data/lib/whois/parsers/whois.madrid.rs.corenic.net.rb +8 -0
  28. data/lib/whois/parsers/whois.mediaserv.net.rb +9 -0
  29. data/lib/whois/parsers/whois.ngtld.cn.rb +8 -0
  30. data/lib/whois/parsers/whois.nic.academy.rb +8 -0
  31. data/lib/whois/parsers/whois.nic.accountant.rb +8 -0
  32. data/lib/whois/parsers/whois.nic.actor.rb +8 -0
  33. data/lib/whois/parsers/whois.nic.agency.rb +8 -0
  34. data/lib/whois/parsers/whois.nic.airforce.rb +8 -0
  35. data/lib/whois/parsers/whois.nic.amsterdam.rb +8 -0
  36. data/lib/whois/parsers/whois.nic.apartments.rb +8 -0
  37. data/lib/whois/parsers/whois.nic.army.rb +8 -0
  38. data/lib/whois/parsers/whois.nic.associates.rb +8 -0
  39. data/lib/whois/parsers/whois.nic.auction.rb +8 -0
  40. data/lib/whois/parsers/whois.nic.aw.rb +33 -0
  41. data/lib/whois/parsers/whois.nic.baby.rb +8 -0
  42. data/lib/whois/parsers/whois.nic.bank.rb +29 -0
  43. data/lib/whois/parsers/whois.nic.bar.rb +8 -0
  44. data/lib/whois/parsers/whois.nic.barcelona.rb +8 -0
  45. data/lib/whois/parsers/whois.nic.barclays.rb +8 -0
  46. data/lib/whois/parsers/whois.nic.bargains.rb +8 -0
  47. data/lib/whois/parsers/whois.nic.basketball.rb +8 -0
  48. data/lib/whois/parsers/whois.nic.bayern.rb +8 -0
  49. data/lib/whois/parsers/whois.nic.beauty.rb +8 -0
  50. data/lib/whois/parsers/whois.nic.beer.rb +8 -0
  51. data/lib/whois/parsers/whois.nic.berlin.rb +8 -0
  52. data/lib/whois/parsers/whois.nic.bible.rb +8 -0
  53. data/lib/whois/parsers/whois.nic.bid.rb +8 -0
  54. data/lib/whois/parsers/whois.nic.bike.rb +8 -0
  55. data/lib/whois/parsers/whois.nic.bingo.rb +8 -0
  56. data/lib/whois/parsers/whois.nic.blog.rb +34 -0
  57. data/lib/whois/parsers/whois.nic.bmw.rb +8 -0
  58. data/lib/whois/parsers/whois.nic.bond.rb +8 -0
  59. data/lib/whois/parsers/whois.nic.boston.rb +8 -0
  60. data/lib/whois/parsers/whois.nic.broker.rb +8 -0
  61. data/lib/whois/parsers/whois.nic.build.rb +8 -0
  62. data/lib/whois/parsers/whois.nic.builders.rb +8 -0
  63. data/lib/whois/parsers/whois.nic.buzz.rb +8 -0
  64. data/lib/whois/parsers/whois.nic.bzh.rb +32 -0
  65. data/lib/whois/parsers/whois.nic.cafe.rb +8 -0
  66. data/lib/whois/parsers/whois.nic.cam.rb +8 -0
  67. data/lib/whois/parsers/whois.nic.camera.rb +8 -0
  68. data/lib/whois/parsers/whois.nic.canon.rb +11 -0
  69. data/lib/whois/parsers/whois.nic.capital.rb +8 -0
  70. data/lib/whois/parsers/whois.nic.cards.rb +8 -0
  71. data/lib/whois/parsers/whois.nic.careers.rb +8 -0
  72. data/lib/whois/parsers/whois.nic.casa.rb +8 -0
  73. data/lib/whois/parsers/whois.nic.cash.rb +8 -0
  74. data/lib/whois/parsers/whois.nic.center.rb +8 -0
  75. data/lib/whois/parsers/whois.nic.ceo.rb +8 -0
  76. data/lib/whois/parsers/whois.nic.ch.rb +6 -2
  77. data/lib/whois/parsers/whois.nic.charity.rb +8 -0
  78. data/lib/whois/parsers/whois.nic.city.rb +8 -0
  79. data/lib/whois/parsers/whois.nic.claims.rb +8 -0
  80. data/lib/whois/parsers/whois.nic.cleaning.rb +8 -0
  81. data/lib/whois/parsers/whois.nic.coach.rb +8 -0
  82. data/lib/whois/parsers/whois.nic.codes.rb +8 -0
  83. data/lib/whois/parsers/whois.nic.coffee.rb +8 -0
  84. data/lib/whois/parsers/whois.nic.computer.rb +8 -0
  85. data/lib/whois/parsers/whois.nic.condos.rb +8 -0
  86. data/lib/whois/parsers/whois.nic.construction.rb +8 -0
  87. data/lib/whois/parsers/whois.nic.contractors.rb +8 -0
  88. data/lib/whois/parsers/whois.nic.cooking.rb +8 -0
  89. data/lib/whois/parsers/whois.nic.cool.rb +8 -0
  90. data/lib/whois/parsers/whois.nic.coop.rb +18 -3
  91. data/lib/whois/parsers/whois.nic.creditcard.rb +8 -0
  92. data/lib/whois/parsers/whois.nic.cruises.rb +8 -0
  93. data/lib/whois/parsers/whois.nic.cyou.rb +8 -0
  94. data/lib/whois/parsers/whois.nic.dance.rb +8 -0
  95. data/lib/whois/parsers/whois.nic.data.rb +8 -0
  96. data/lib/whois/parsers/whois.nic.deals.rb +8 -0
  97. data/lib/whois/parsers/whois.nic.degree.rb +8 -0
  98. data/lib/whois/parsers/whois.nic.democrat.rb +8 -0
  99. data/lib/whois/parsers/whois.nic.diamonds.rb +8 -0
  100. data/lib/whois/parsers/whois.nic.digital.rb +8 -0
  101. data/lib/whois/parsers/whois.nic.directory.rb +8 -0
  102. data/lib/whois/parsers/whois.nic.doctor.rb +8 -0
  103. data/lib/whois/parsers/whois.nic.dog.rb +8 -0
  104. data/lib/whois/parsers/whois.nic.dvag.rb +8 -0
  105. data/lib/whois/parsers/whois.nic.eco.rb +8 -0
  106. data/lib/whois/parsers/whois.nic.education.rb +8 -0
  107. data/lib/whois/parsers/whois.nic.email.rb +8 -0
  108. data/lib/whois/parsers/whois.nic.energy.rb +8 -0
  109. data/lib/whois/parsers/whois.nic.engineer.rb +8 -0
  110. data/lib/whois/parsers/whois.nic.equipment.rb +8 -0
  111. data/lib/whois/parsers/whois.nic.estate.rb +8 -0
  112. data/lib/whois/parsers/whois.nic.eus.rb +8 -0
  113. data/lib/whois/parsers/whois.nic.expert.rb +8 -0
  114. data/lib/whois/parsers/whois.nic.exposed.rb +8 -0
  115. data/lib/whois/parsers/whois.nic.express.rb +8 -0
  116. data/lib/whois/parsers/whois.nic.family.rb +8 -0
  117. data/lib/whois/parsers/whois.nic.fan.rb +8 -0
  118. data/lib/whois/parsers/whois.nic.fans.rb +8 -0
  119. data/lib/whois/parsers/whois.nic.feedback.rb +8 -0
  120. data/lib/whois/parsers/whois.nic.film.rb +8 -0
  121. data/lib/whois/parsers/whois.nic.fish.rb +8 -0
  122. data/lib/whois/parsers/whois.nic.fishing.rb +8 -0
  123. data/lib/whois/parsers/whois.nic.florist.rb +8 -0
  124. data/lib/whois/parsers/whois.nic.football.rb +8 -0
  125. data/lib/whois/parsers/whois.nic.forex.rb +8 -0
  126. data/lib/whois/parsers/whois.nic.foundation.rb +8 -0
  127. data/lib/whois/parsers/whois.nic.fox.rb +8 -0
  128. data/lib/whois/parsers/whois.nic.fr.rb +3 -0
  129. data/lib/whois/parsers/whois.nic.frl.rb +8 -0
  130. data/lib/whois/parsers/whois.nic.furniture.rb +8 -0
  131. data/lib/whois/parsers/whois.nic.futbol.rb +8 -0
  132. data/lib/whois/parsers/whois.nic.fyi.rb +8 -0
  133. data/lib/whois/parsers/whois.nic.gal.rb +8 -0
  134. data/lib/whois/parsers/whois.nic.gd.rb +4 -0
  135. data/lib/whois/parsers/whois.nic.ge.rb +74 -0
  136. data/lib/whois/parsers/whois.nic.gent.rb +8 -0
  137. data/lib/whois/parsers/whois.nic.giving.rb +8 -0
  138. data/lib/whois/parsers/whois.nic.glass.rb +8 -0
  139. data/lib/whois/parsers/whois.nic.gmbh.rb +8 -0
  140. data/lib/whois/parsers/whois.nic.graphics.rb +8 -0
  141. data/lib/whois/parsers/whois.nic.gratis.rb +8 -0
  142. data/lib/whois/parsers/whois.nic.guru.rb +8 -0
  143. data/lib/whois/parsers/whois.nic.hamburg.rb +8 -0
  144. data/lib/whois/parsers/whois.nic.haus.rb +8 -0
  145. data/lib/whois/parsers/whois.nic.holdings.rb +8 -0
  146. data/lib/whois/parsers/whois.nic.holiday.rb +8 -0
  147. data/lib/whois/parsers/whois.nic.house.rb +8 -0
  148. data/lib/whois/parsers/whois.nic.immo.rb +8 -0
  149. data/lib/whois/parsers/whois.nic.immobilien.rb +8 -0
  150. data/lib/whois/parsers/whois.nic.inc.rb +8 -0
  151. data/lib/whois/parsers/whois.nic.institute.rb +8 -0
  152. data/lib/whois/parsers/whois.nic.insure.rb +8 -0
  153. data/lib/whois/parsers/whois.nic.international.rb +8 -0
  154. data/lib/whois/parsers/whois.nic.jewelry.rb +8 -0
  155. data/lib/whois/parsers/whois.nic.kaufen.rb +8 -0
  156. data/lib/whois/parsers/whois.nic.kiwi.rb +8 -0
  157. data/lib/whois/parsers/whois.nic.kn.rb +8 -0
  158. data/lib/whois/parsers/whois.nic.kyoto.rb +8 -0
  159. data/lib/whois/parsers/whois.nic.land.rb +8 -0
  160. data/lib/whois/parsers/whois.nic.lat.rb +8 -0
  161. data/lib/whois/parsers/whois.nic.lawyer.rb +8 -0
  162. data/lib/whois/parsers/whois.nic.lease.rb +8 -0
  163. data/lib/whois/parsers/whois.nic.legal.rb +8 -0
  164. data/lib/whois/parsers/whois.nic.limited.rb +8 -0
  165. data/lib/whois/parsers/whois.nic.limo.rb +8 -0
  166. data/lib/whois/parsers/whois.nic.live.rb +8 -0
  167. data/lib/whois/parsers/whois.nic.london.rb +8 -0
  168. data/lib/whois/parsers/whois.nic.love.rb +8 -0
  169. data/lib/whois/parsers/whois.nic.luxury.rb +8 -0
  170. data/lib/whois/parsers/whois.nic.maison.rb +8 -0
  171. data/lib/whois/parsers/whois.nic.makeup.rb +8 -0
  172. data/lib/whois/parsers/whois.nic.man.rb +8 -0
  173. data/lib/whois/parsers/whois.nic.management.rb +8 -0
  174. data/lib/whois/parsers/whois.nic.mba.rb +8 -0
  175. data/lib/whois/parsers/whois.nic.media.rb +8 -0
  176. data/lib/whois/parsers/whois.nic.memorial.rb +8 -0
  177. data/lib/whois/parsers/whois.nic.men.rb +8 -0
  178. data/lib/whois/parsers/whois.nic.miami.rb +8 -0
  179. data/lib/whois/parsers/whois.nic.mobile.rb +8 -0
  180. data/lib/whois/parsers/whois.nic.moda.rb +8 -0
  181. data/lib/whois/parsers/whois.nic.moe.rb +8 -0
  182. data/lib/whois/parsers/whois.nic.money.rb +8 -0
  183. data/lib/whois/parsers/whois.nic.monster.rb +8 -0
  184. data/lib/whois/parsers/whois.nic.mortgage.rb +8 -0
  185. data/lib/whois/parsers/whois.nic.moscow.rb +8 -0
  186. data/lib/whois/parsers/whois.nic.museum.rb +8 -0
  187. data/lib/whois/parsers/whois.nic.net.sa.rb +28 -9
  188. data/lib/whois/parsers/whois.nic.network.rb +8 -0
  189. data/lib/whois/parsers/whois.nic.nrw.rb +8 -0
  190. data/lib/whois/parsers/whois.nic.observer.rb +8 -0
  191. data/lib/whois/parsers/whois.nic.okinawa.rb +17 -0
  192. data/lib/whois/parsers/whois.nic.ooo.rb +8 -0
  193. data/lib/whois/parsers/whois.nic.partners.rb +8 -0
  194. data/lib/whois/parsers/whois.nic.photography.rb +8 -0
  195. data/lib/whois/parsers/whois.nic.photos.rb +8 -0
  196. data/lib/whois/parsers/whois.nic.pizza.rb +8 -0
  197. data/lib/whois/parsers/whois.nic.place.rb +8 -0
  198. data/lib/whois/parsers/whois.nic.plumbing.rb +8 -0
  199. data/lib/whois/parsers/whois.nic.pm.rb +3 -0
  200. data/lib/whois/parsers/whois.nic.press.rb +8 -0
  201. data/lib/whois/parsers/whois.nic.properties.rb +8 -0
  202. data/lib/whois/parsers/whois.nic.quebec.rb +8 -0
  203. data/lib/whois/parsers/whois.nic.quest.rb +8 -0
  204. data/lib/whois/parsers/whois.nic.racing.rb +8 -0
  205. data/lib/whois/parsers/whois.nic.radio.rb +8 -0
  206. data/lib/whois/parsers/whois.nic.realty.rb +8 -0
  207. data/lib/whois/parsers/whois.nic.recipes.rb +8 -0
  208. data/lib/whois/parsers/whois.nic.reisen.rb +8 -0
  209. data/lib/whois/parsers/whois.nic.rent.rb +8 -0
  210. data/lib/whois/parsers/whois.nic.rentals.rb +8 -0
  211. data/lib/whois/parsers/whois.nic.republican.rb +8 -0
  212. data/lib/whois/parsers/whois.nic.rest.rb +8 -0
  213. data/lib/whois/parsers/whois.nic.restaurant.rb +8 -0
  214. data/lib/whois/parsers/whois.nic.review.rb +8 -0
  215. data/lib/whois/parsers/whois.nic.rip.rb +8 -0
  216. data/lib/whois/parsers/whois.nic.rodeo.rb +8 -0
  217. data/lib/whois/parsers/whois.nic.ruhr.rb +8 -0
  218. data/lib/whois/parsers/whois.nic.saarland.rb +8 -0
  219. data/lib/whois/parsers/whois.nic.salon.rb +8 -0
  220. data/lib/whois/parsers/whois.nic.sap.rb +8 -0
  221. data/lib/whois/parsers/whois.nic.sarl.rb +8 -0
  222. data/lib/whois/parsers/whois.nic.sbs.rb +8 -0
  223. data/lib/whois/parsers/whois.nic.schule.rb +8 -0
  224. data/lib/whois/parsers/whois.nic.schwarz.rb +8 -0
  225. data/lib/whois/parsers/whois.nic.scot.rb +8 -0
  226. data/lib/whois/parsers/whois.nic.security.rb +8 -0
  227. data/lib/whois/parsers/whois.nic.select.rb +8 -0
  228. data/lib/whois/parsers/whois.nic.services.rb +8 -0
  229. data/lib/whois/parsers/whois.nic.shoes.rb +8 -0
  230. data/lib/whois/parsers/whois.nic.shopping.rb +8 -0
  231. data/lib/whois/parsers/whois.nic.skin.rb +8 -0
  232. data/lib/whois/parsers/whois.nic.soccer.rb +8 -0
  233. data/lib/whois/parsers/whois.nic.solar.rb +8 -0
  234. data/lib/whois/parsers/whois.nic.sport.rb +8 -0
  235. data/lib/whois/parsers/whois.nic.ss.rb +36 -0
  236. data/lib/whois/parsers/whois.nic.storage.rb +8 -0
  237. data/lib/whois/parsers/whois.nic.study.rb +8 -0
  238. data/lib/whois/parsers/whois.nic.style.rb +8 -0
  239. data/lib/whois/parsers/whois.nic.support.rb +8 -0
  240. data/lib/whois/parsers/whois.nic.surf.rb +8 -0
  241. data/lib/whois/parsers/whois.nic.surgery.rb +8 -0
  242. data/lib/whois/parsers/whois.nic.swiss.rb +8 -0
  243. data/lib/whois/parsers/whois.nic.taipei.rb +8 -0
  244. data/lib/whois/parsers/whois.nic.tatar.rb +19 -0
  245. data/lib/whois/parsers/whois.nic.team.rb +8 -0
  246. data/lib/whois/parsers/whois.nic.tennis.rb +8 -0
  247. data/lib/whois/parsers/whois.nic.theater.rb +8 -0
  248. data/lib/whois/parsers/whois.nic.tickets.rb +8 -0
  249. data/lib/whois/parsers/whois.nic.tienda.rb +8 -0
  250. data/lib/whois/parsers/whois.nic.tips.rb +8 -0
  251. data/lib/whois/parsers/whois.nic.tires.rb +8 -0
  252. data/lib/whois/parsers/whois.nic.tirol.rb +8 -0
  253. data/lib/whois/parsers/whois.nic.top.rb +15 -0
  254. data/lib/whois/parsers/whois.nic.town.rb +8 -0
  255. data/lib/whois/parsers/whois.nic.toyota.rb +8 -0
  256. data/lib/whois/parsers/whois.nic.toys.rb +8 -0
  257. data/lib/whois/parsers/whois.nic.trade.rb +8 -0
  258. data/lib/whois/parsers/whois.nic.training.rb +8 -0
  259. data/lib/whois/parsers/whois.nic.university.rb +8 -0
  260. data/lib/whois/parsers/whois.nic.uno.rb +8 -0
  261. data/lib/whois/parsers/whois.nic.us.rb +30 -0
  262. data/lib/whois/parsers/whois.nic.vet.rb +8 -0
  263. data/lib/whois/parsers/whois.nic.viajes.rb +8 -0
  264. data/lib/whois/parsers/whois.nic.villas.rb +8 -0
  265. data/lib/whois/parsers/whois.nic.voyage.rb +8 -0
  266. data/lib/whois/parsers/whois.nic.webcam.rb +8 -0
  267. data/lib/whois/parsers/whois.nic.wedding.rb +8 -0
  268. data/lib/whois/parsers/whois.nic.wien.rb +8 -0
  269. data/lib/whois/parsers/whois.nic.wiki.rb +8 -0
  270. data/lib/whois/parsers/whois.nic.wtf.rb +8 -0
  271. data/lib/whois/parsers/whois.nic.xin.rb +8 -0
  272. data/lib/whois/parsers/whois.nic.xn--80adxhks.rb +8 -0
  273. data/lib/whois/parsers/whois.nic.xn--d1acj3b.rb +15 -0
  274. data/lib/whois/parsers/whois.nic.xn--mk1bu44c.rb +13 -0
  275. data/lib/whois/parsers/whois.nic.xn--t60b56a.rb +8 -0
  276. data/lib/whois/parsers/whois.nic.xn--tckwe.rb +39 -0
  277. data/lib/whois/parsers/whois.nic.yoga.rb +8 -0
  278. data/lib/whois/parsers/whois.nic.yokohama.rb +8 -0
  279. data/lib/whois/parsers/whois.nic.yt.rb +24 -0
  280. data/lib/whois/parsers/whois.online.rs.corenic.net.rb +8 -0
  281. data/lib/whois/parsers/whois.pknic.net.pk.rb +70 -0
  282. data/lib/whois/parsers/whois.publicinterestregistry.net.rb +8 -0
  283. data/lib/whois/parsers/whois.ryce-rsp.com.rb +13 -0
  284. data/lib/whois/parsers/whois.teleinfo.cn.rb +16 -0
  285. metadata +285 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 64090073c595bd3cbd6e1a52628cf6d3481de3933b791d9338bf1793922dc6a4
4
- data.tar.gz: b15050ea47d7662aedb25a2f0e6e0e8997c7c825b2de70e149dce0f85fd7dd8c
3
+ metadata.gz: 5c90a3f9e48b3ede88480bcaec9eabccfe31a7f60cf867df226192f54e0dbe29
4
+ data.tar.gz: 683529a7de7ea08c12065878dbc59d364f43163264d2c8338f1b90011aec5821
5
5
  SHA512:
6
- metadata.gz: 8946d38a18bdb012fc79661fc31fcf67f4e63b7cdd728e14dacf48c77a72317322f145544d89b97725f292d4e1860a2aa9ba4842824378745541aea0e9408eee
7
- data.tar.gz: 8d10ae4db2cfdf8aee03bc17d4867afd56e03dfa19ddcf4ca31610acbd4957bad49a34a3c6fbbbc2988c77ae42c7f86e1c4ae8e1f2a0bd1342ffe5febd68bbbe
6
+ metadata.gz: d9608362d4824d5c3a9044b3dd59e2c82935e915c88b938af75c9f8904852fab632b2e76132f25fd7a4faf7652ed63cdd54f86327c73e9efa1326df5d0225c14
7
+ data.tar.gz: 8c93323b08ea3c950f809bd201026a4a2a5086f9d5fddfcb31dad8a2888a5857ad4810f3932b3995b1abf4adee44fa4bf6354f96191527b5799952f4508a40e2
data/CHANGELOG.md CHANGED
@@ -3,7 +3,65 @@
3
3
  This project uses [Semantic Versioning 2.0.0](http://semver.org/).
4
4
 
5
5
 
6
- #### Unreleased 0.1.0
6
+ #### Release 0.3.0 (2026-09-25)
7
+
8
+ - ADDED: Added evidence-backed `.top` registration and exact authoritative
9
+ absence parsing. `.us` now recognizes registration evidence while keeping
10
+ the registry's non-authoritative `No Data Found` response unknown.
11
+ - ADDED: Added conservative `.pk` parsing for exact PKNIC registered and
12
+ explicitly available responses. The standard `whois` 6.0.3 mapping selects
13
+ a legacy web adapter, and `Whois::Client.new(host: ...)` cannot override
14
+ that adapter. DomScan needs a fixed-host port-43 route through its managed
15
+ relay before `.pk` counts as effective coverage.
16
+ - ADDED: Tightened `.uz` and `.sa` parsing against current registered and
17
+ exact authoritative-absence responses. `.uz` reserved names remain
18
+ `:reserved`, not registered or available. Added a conservative `.ge` parser
19
+ for exact registered and absence responses from IANA's `whois.nic.ge` host;
20
+ `whois` 6.0.3 defaults `.ge` to `whois.registration.ge`, so a fixed-host
21
+ route is still required before counting it as effective coverage.
22
+ - SAFETY: Kept blocked, empty, and ambiguous `.ch` responses unknown, and
23
+ added unavailable-only handling for explicit unsupported responses from
24
+ `.digital`, `.email`, `.live`, `.media`, `.network`, and `.services`.
25
+ - DOCS: Added a scorecard for 1,000 observed TLD strings from the ICANN DNS
26
+ Magnitude snapshot dated 2026-09-12. Its strict count of 175 paired rows is
27
+ pinned to parser baseline `f2c822c` and excludes the Top 100, whose summary
28
+ labels do not expose row-level evidence pairs. The scorecard does not claim
29
+ 1,000 effective WHOIS integrations or a single effective-coverage rate.
30
+ Later `.uz`/`.sa` evidence and `.pk`/`.ge` parsers are follow-ups, not
31
+ additions to that pinned count.
32
+ - SOURCES: The audit notes link to the [ICANN DNS Magnitude
33
+ snapshot](https://magnitude.research.icann.org/historic/20260912.full.html),
34
+ [IANA `.top`](https://www.iana.org/domains/root/db/top.html),
35
+ [IANA `.us`](https://www.iana.org/domains/root/db/us.html),
36
+ [IANA `.ch`](https://www.iana.org/domains/root/db/ch.html),
37
+ [IANA `.pk`](https://www.iana.org/domains/root/db/pk.html), and the
38
+ [official PKNIC site](https://www.pknic.net.pk/). The
39
+ [rank 104-105 report](docs/audits/top-101-125-tlds-2026-09-19.md) cites
40
+ [IANA `.uz`](https://www.iana.org/domains/root/db/uz.html),
41
+ [UZINFOCOM](https://www.cctld.uz/),
42
+ [IANA `.sa`](https://www.iana.org/domains/root/db/sa.html), and
43
+ [IANA `.ge`](https://www.iana.org/domains/root/db/ge.html).
44
+ - EVIDENCE: [Top-1,000 scorecard](docs/audits/top-1000-effective-coverage-scorecard-2026-09-25.md),
45
+ [current `.top`/`.us` observations](docs/audits/top-us-current-2026-09-25.md),
46
+ [`.pk` routing and registry evidence](docs/audits/top1000-es-pk-shop-dev-app-2026-09-25.md),
47
+ and [rank 101-125 follow-up evidence](docs/audits/top-101-125-tlds-2026-09-19.md).
48
+
49
+
50
+ #### Release 0.2.0 (2026-09-25)
51
+
52
+ - ADDED: Extended the usage-ranked audit and parser work through 1,000 ICANN
53
+ DNS Magnitude TLD strings from the 2026-09-12 snapshot.
54
+ - CLARIFIED: The 1,000 rows are observed TLD strings, not 1,000 guaranteed
55
+ working registries or domain-availability results. The audit keeps verified
56
+ parser evidence, explicit unavailable or unsupported responses,
57
+ unknown or unresolved endpoints, and classification-only rows distinct.
58
+ - ADDED: Preserved the source manifest, verification evidence, planning
59
+ inventory, and five implementation-package reports for ranks 301-1000.
60
+ - TESTED: The combined parser and audit suite passes 6,768 examples with 0
61
+ failures on Ruby 3.2.2 and 3.4.5.
62
+
63
+
64
+ #### Release 0.1.0 (2026-09-19)
7
65
 
8
66
  - CHANGED: Continued the project as `whois-parser-next`, with the original MIT
9
67
  license, attribution, and Git history preserved.
data/README.md CHANGED
@@ -38,8 +38,9 @@ of current WHOIS responses, explicit unknown states, registry-specific
38
38
  fixtures, and safe handling of malformed, rate-limited, retired, or changed
39
39
  server responses.
40
40
 
41
- The current development gem name is `whois-parser-next`. It has not yet been
42
- published to RubyGems.
41
+ The current source version is `0.3.0`. Check the [RubyGems project
42
+ page](https://rubygems.org/gems/whois-parser-next) for its publication status
43
+ and the latest published version.
43
44
 
44
45
  ## Compatibility
45
46
 
@@ -53,12 +54,11 @@ Whois::Parser
53
54
  ```
54
55
 
55
56
  Existing applications can retain `require "whois-parser"` and their
56
- `Whois::Parser` integrations while changing the dependency source:
57
+ `Whois::Parser` integrations. To install version 0.3.0 after it appears on
58
+ RubyGems, pin it as follows:
57
59
 
58
60
  ```ruby
59
- gem "whois-parser-next",
60
- github: "estevecastells/whois-parser-next",
61
- require: "whois-parser"
61
+ gem "whois-parser-next", "= 0.3.0", require: "whois-parser"
62
62
  ```
63
63
 
64
64
  ## Requirements
@@ -83,12 +83,31 @@ bundle exec rspec
83
83
 
84
84
  ## Coverage evidence
85
85
 
86
- The 2026-09-19 live audit covers the ICANN DNS Magnitude ordering through rank
87
- 300. Start with the [Top 20 review](docs/audits/top-20-tlds-2026-09-19.md) and
88
- [Top 100 audit](docs/audits/top-100-tlds-2026-09-19.md); the same directory
89
- contains the contiguous 25-TLD reports for ranks 101 through 300. Each report
90
- separates verified parsing from unavailable, retired, restricted, web-only,
91
- and unresolved WHOIS paths.
86
+ The [2026-09-25 scorecard](docs/audits/top-1000-effective-coverage-scorecard-2026-09-25.md)
87
+ summarizes evidence for 1,000 observed TLD strings from the
88
+ [ICANN DNS Magnitude snapshot dated 2026-09-12](https://magnitude.research.icann.org/historic/20260912.full.html).
89
+ These strings are not 1,000 guaranteed working WHOIS registries or
90
+ domain-availability results. Its strict paired count is pinned to baseline
91
+ `f2c822c`, excludes the Top 100 whose summary labels do not expose row-level
92
+ evidence pairs, and does not claim an effective-coverage percentage. The
93
+ scorecard keeps verified parser evidence, explicit unavailable or unsupported
94
+ responses, unknown or unresolved endpoints, and classification-only rows
95
+ distinct. Later `.uz`/`.sa` paired evidence and `.pk`/`.ge` parsers are
96
+ follow-ups, not changes to the pinned scorecard counts. The `.pk` parser does
97
+ not make the default `whois` 6.0.3 Web adapter use port 43; `Whois::Client`
98
+ host configuration does not override that adapter. The `.ge` parser targets
99
+ IANA's `whois.nic.ge`, while the default `whois` route is
100
+ `whois.registration.ge`. Both require explicit fixed-host routing before an
101
+ application can count them as effective coverage.
102
+
103
+ Start with the [source verification report](docs/audits/top-1000-source-verification-2026-09-19.md),
104
+ the [Top 20 review](docs/audits/top-20-tlds-2026-09-19.md), and the [Top 100
105
+ audit](docs/audits/top-100-tlds-2026-09-19.md). The same directory contains
106
+ the contiguous reports for ranks 101 through 300, the [301-1000 work-package
107
+ plan](docs/audits/whois-parser-top1000-work-packages-2026-09-19.md), and the
108
+ five package audit reports. Each report preserves the evidence boundary and
109
+ does not turn unavailable, unsupported, unresolved, or classification-only
110
+ rows into availability claims.
92
111
 
93
112
  ## Join the work
94
113
 
data/RELEASING.md CHANGED
@@ -21,8 +21,8 @@ RubyGems API key to the repository or its Actions secrets.
21
21
  Create and push the annotated release tag only after the checks above pass:
22
22
 
23
23
  ```shell
24
- git tag -a v0.1.0 -m "whois-parser-next 0.1.0"
25
- git push origin v0.1.0
24
+ git tag -a v0.3.0 -m "whois-parser-next 0.3.0"
25
+ git push origin v0.3.0
26
26
  ```
27
27
 
28
28
  The release workflow repeats the full suite and package smoke test before it
data/ROADMAP.md CHANGED
@@ -6,24 +6,29 @@ feature calendar.
6
6
 
7
7
  ## Current release
8
8
 
9
- - Establish a safe, maintained successor with Ruby 3.2 through Ruby 4 support.
10
- - Audit the first 300 rows of a dated, reproducible TLD-usage snapshot.
11
- - Replace unsafe fallback classifications with explicit unknown or unavailable
12
- outcomes when a response lacks authoritative evidence.
13
- - Keep the gem compatible with `require "whois-parser"` and `Whois::Parser`.
14
- - Publish through short-lived RubyGems trusted-publishing credentials.
9
+ - Published `whois-parser-next` 0.2.0 to RubyGems, retaining the established
10
+ `require "whois-parser"` and `Whois::Parser` compatibility.
11
+ - Completed the audit of 1,000 observed TLD strings from the ICANN DNS Magnitude
12
+ snapshot dated 2026-09-12. These rows are ranked TLD strings, not 1,000
13
+ confirmed working WHOIS registries or domain-availability results.
14
+ - Kept verified parser evidence, unavailable or unsupported responses,
15
+ unresolved endpoints, and classification-only rows distinct.
15
16
 
16
17
  ## Next priorities
17
18
 
18
- 1. Continue evidence-backed TLD coverage in reproducible, non-overlapping
19
- batches.
20
- 2. Add regression fixtures when registries change format, server, policy, or
21
- availability wording.
22
- 3. Reduce avoidable runtime dependencies without changing public behavior.
23
- 4. Improve contributor tooling for fixture privacy, server-mapping drift, and
24
- ambiguous-response safety.
25
- 5. Document parser confidence and provenance without pretending that a parsed
26
- WHOIS response is an availability guarantee.
19
+ 1. Refresh the existing 1,000-row cohort only against a new, dated source
20
+ snapshot, keeping each snapshot's ranks and labels separate.
21
+ 2. Close parser evidence gaps for mapped official WHOIS hosts with bounded
22
+ probes and sanitized fixtures for exact response behavior. DNS failures,
23
+ timeouts, unsupported replies, and ambiguous responses remain unresolved or
24
+ unavailable.
25
+ 3. Add or change parser behavior only when current response evidence is backed
26
+ by a regression spec; do not infer one host's behavior for unmapped or
27
+ unverified TLDs.
28
+ 4. Scope any expansion beyond rank 1,000 from a separately documented dataset
29
+ before treating it as parser-coverage work.
30
+ 5. Reduce avoidable runtime dependencies and improve contributor tooling for
31
+ fixture privacy, server-mapping drift, and response-safety checks.
27
32
 
28
33
  ## Performance and Rust
29
34
 
data/SECURITY.md CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  ## Supported versions
4
4
 
5
- Until the first release, only the current main branch is supported.
5
+ The current main branch and the latest published release are supported.
6
6
 
7
7
  | Version | Supported |
8
8
  |---|---|
9
9
  | main | Yes |
10
- | Released versions | No released versions yet |
10
+ | 0.2.0 (latest release) | Yes |
11
11
 
12
12
  ## Reporting a vulnerability
13
13
 
@@ -1,6 +1,6 @@
1
1
  module Whois
2
2
  class Parser
3
3
  # The current library version.
4
- VERSION = "0.1.0".freeze
4
+ VERSION = "0.3.0".freeze
5
5
  end
6
6
  end
@@ -0,0 +1,12 @@
1
+ require_relative 'base_icann_compliant'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # CentralNic registries that expose the ICANN key/value record shape.
6
+ class BaseCentralnicIcann < BaseIcannCompliant
7
+ self.scanner = Scanners::BaseIcannCompliant, {
8
+ pattern_available: /^The queried object does not exist:\s+DOMAIN NOT FOUND\s*$/i,
9
+ }
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'whois.cira.ca'
2
+ require_relative 'registry_response_safety'
3
+
4
+ module Whois
5
+ class Parsers
6
+ # CIRA-shaped registries use the same record scanner, but an unexpected
7
+ # non-record response must remain unknown rather than becoming a parser
8
+ # error that callers might accidentally treat as registration.
9
+ class BaseCiraRegistry < WhoisCiraCa
10
+ include RegistryResponseSafety
11
+
12
+ property_supported :status do
13
+ super()
14
+ rescue ParserError
15
+ :unknown
16
+ end
17
+ end
18
+ end
19
+ end
@@ -54,7 +54,7 @@ module Whois
54
54
  end
55
55
 
56
56
  property_supported :registered? do
57
- [:registered, :reserved].include?(status)
57
+ status == :registered
58
58
  end
59
59
 
60
60
 
@@ -0,0 +1,12 @@
1
+ require_relative 'base_icann_compliant'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # Shared ICANN key/value parser for Identity Digital registries.
6
+ #
7
+ # Individual registries differ only in the authoritative absence marker;
8
+ # host-specific subclasses keep those markers explicit.
9
+ class BaseIdentityDigital < BaseIcannCompliant
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,48 @@
1
+ require_relative 'base'
2
+ require_relative 'registry_response_safety'
3
+
4
+ module Whois
5
+ class Parsers
6
+ # Minimal parser contract for JWhoisServer responses used by the French
7
+ # overseas registries. Registration is reported only from a domain line;
8
+ # the registry's explicit NO OBJECT FOUND marker is the sole absence proof.
9
+ class BaseJwhois < Base
10
+ include RegistryResponseSafety
11
+
12
+ property_supported :domain do
13
+ content_for_scanner[/^domain:\s*(\S+)\s*$/i, 1]&.downcase
14
+ end
15
+
16
+ property_supported :status do
17
+ if available?
18
+ :available
19
+ elsif registered_evidence?
20
+ :registered
21
+ else
22
+ :unknown
23
+ end
24
+ end
25
+
26
+ property_supported :available? do
27
+ content_for_scanner.match?(/^NO OBJECT FOUND!\s*$/i)
28
+ end
29
+
30
+ property_supported :registered? do
31
+ status == :registered
32
+ end
33
+
34
+ property_supported :nameservers do
35
+ content_for_scanner.scan(/^nameserver:\s*(\S+)\s*$/i).flatten.map do |name|
36
+ Parser::Nameserver.new(name: name.downcase)
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def registered_evidence?
43
+ content_for_scanner.match?(/^domain:\s*\S+/i) &&
44
+ content_for_scanner.match?(/^(?:changed|nameserver):\s*\S+/i)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'base_icann_compliant'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # Shared parser for registries that use the ICANN response layout and
6
+ # report an exact `Available` line for an absent object.
7
+ class BaseNicReservedAvailable < BaseIcannCompliant
8
+ self.scanner = Scanners::BaseIcannCompliant, {
9
+ pattern_available: /^Available\s*$/i,
10
+ }
11
+
12
+ def reserved?
13
+ content_for_scanner.match?(/^Reserved:\s*/i)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,27 @@
1
+ require_relative 'base'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # A registry response that explicitly reserves or prohibits the queried
6
+ # name. It is not evidence of either registration or availability.
7
+ class BaseReservedRegistry < Base
8
+ property_supported :status do
9
+ :unknown
10
+ end
11
+
12
+ property_supported :available? do
13
+ false
14
+ end
15
+
16
+ property_supported :registered? do
17
+ false
18
+ end
19
+
20
+ def response_unavailable?
21
+ content_for_scanner.match?(
22
+ /\A(?:Reserved Domain Name|This name is reserved by the Registry\b|The queried object does not exist:.*reserved list)/i
23
+ )
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,39 @@
1
+ require_relative 'base_icann_compliant'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # Conservative ICANN-style parser shared by the package-3 registries.
6
+ # The absence markers are complete lines observed in current port-43
7
+ # responses. Empty, denied, and throttled responses remain unavailable via
8
+ # RegistryResponseSafety inherited from BaseIcannCompliant.
9
+ class BaseTop1000Icann < BaseIcannCompliant
10
+ AVAILABLE_MARKERS = [
11
+ /^No Data Found\s*$/i,
12
+ /^The queried object does not exist:\s*(?:DOMAIN NOT FOUND|no matching objects found)\s*$/i,
13
+ /^>>> Domain \S+ is available for registration\s*$/i,
14
+ /^Domain not found\s*$/i,
15
+ /^%% NOT FOUND\s*$/i,
16
+ ].freeze
17
+
18
+ RESERVED_MARKERS = [
19
+ /^Reserved Domain Name\s*$/i,
20
+ /^This name is reserved by the Registry\.\s*$/i,
21
+ ].freeze
22
+
23
+ property_supported :available? do
24
+ AVAILABLE_MARKERS.any? { |marker| content_for_scanner.match?(marker) }
25
+ end
26
+
27
+ property_supported :reserved? do
28
+ RESERVED_MARKERS.any? { |marker| content_for_scanner.match?(marker) }
29
+ end
30
+
31
+ # `reserved?` is intentionally a parser predicate rather than a public
32
+ # record property. BaseIcannCompliant consults it while determining the
33
+ # status of a reserved registry response.
34
+ def reserved?
35
+ RESERVED_MARKERS.any? { |marker| content_for_scanner.match?(marker) }
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'base'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # WHOIS endpoints that have retired port-43 service in favour of RDAP.
6
+ class BaseTop1000Retired < Base
7
+ property_supported :status do
8
+ :unknown
9
+ end
10
+
11
+ property_supported :available? do
12
+ false
13
+ end
14
+
15
+ property_supported :registered? do
16
+ false
17
+ end
18
+
19
+ def response_unavailable?
20
+ content_for_scanner.match?(
21
+ /^Notice: Effective May 1, 2026, the WHOIS service has been retired\b/i
22
+ )
23
+ end
24
+ end
25
+ end
26
+ end
@@ -21,7 +21,7 @@ module Whois
21
21
 
22
22
  def response_unavailable?
23
23
  content_for_scanner.match?(
24
- /^(?:TLD is not supported\.|No Data Found)\s*$/i
24
+ /\A(?:TLD is not supported\.|No Data Found)[ \t]*(?:\n|\z)/i
25
25
  )
26
26
  end
27
27
  end
@@ -0,0 +1,10 @@
1
+ require_relative 'whois.cnnic.cn'
2
+
3
+ module Whois
4
+ class Parsers
5
+ # The registry publishes both `cwhois.cnnic.cn` and the historical
6
+ # `whois.cnnic.cn` service name. Keep both names on the same parser.
7
+ class CwhoisCnnicCn < WhoisCnnicCn
8
+ end
9
+ end
10
+ end
@@ -22,6 +22,8 @@ module Whois
22
22
  def response_unavailable?
23
23
  response_incomplete? || content_for_scanner.match?(
24
24
  /^(?:\s*(?:%|#)\s*)?(?:requests of this client are not permitted|access to the whois service is denied|whois service is unavailable)\b/i
25
+ ) || content_for_scanner.match?(
26
+ /\ATLD is not supported\.[ \t]*(?:\n|\z)/i
25
27
  )
26
28
  end
27
29
  end
@@ -8,6 +8,7 @@
8
8
 
9
9
 
10
10
  require_relative 'base'
11
+ require_relative 'registry_response_safety'
11
12
 
12
13
 
13
14
  module Whois
@@ -23,21 +24,25 @@ module Whois
23
24
  # The Example parser for the list of all available methods.
24
25
  #
25
26
  class WhoisAx < Base
27
+ include RegistryResponseSafety
26
28
 
27
29
  property_supported :status do
28
30
  if available?
29
31
  :available
30
- else
32
+ elsif registered_evidence?
31
33
  :registered
34
+ else
35
+ :unknown
32
36
  end
33
37
  end
34
38
 
35
39
  property_supported :available? do
36
- !!(content_for_scanner =~ /^No records matching .+ found/)
40
+ !!(content_for_scanner =~ /^No records matching \S+ found\.\s*$/i ||
41
+ content_for_scanner =~ /^Domain not found\s*$/i)
37
42
  end
38
43
 
39
44
  property_supported :registered? do
40
- !available?
45
+ status == :registered
41
46
  end
42
47
 
43
48
 
@@ -58,6 +63,13 @@ module Whois
58
63
  end
59
64
  end
60
65
 
66
+ private
67
+
68
+ def registered_evidence?
69
+ content_for_scanner.match?(/^Domain Name:\s+\S+/i) &&
70
+ content_for_scanner.match?(/^(?:Created|Name Server \d):\s+\S+/i)
71
+ end
72
+
61
73
  end
62
74
 
63
75
  end
@@ -27,26 +27,15 @@ module Whois
27
27
  include RegistryResponseSafety
28
28
 
29
29
  property_supported :status do
30
- if available?
31
- :available
32
- elsif content_for_scanner =~ /^Status: (.+?)\n/
33
- case ::Regexp.last_match(1).downcase
34
- when "active" then :registered
35
- when "reserved" then :reserved
36
- else
37
- Whois::Parser.bug!(ParserError, "Unknown status `#{::Regexp.last_match(1)}'.")
38
- end
39
- else
40
- :unknown
41
- end
30
+ classify_status
42
31
  end
43
32
 
44
33
  property_supported :available? do
45
- !!(content_for_scanner =~ /not found in database/)
34
+ classify_status == :available
46
35
  end
47
36
 
48
37
  property_supported :registered? do
49
- [:registered, :reserved].include?(status)
38
+ classify_status == :registered
50
39
  end
51
40
 
52
41
 
@@ -77,6 +66,53 @@ module Whois
77
66
  end
78
67
  end
79
68
 
69
+ private
70
+
71
+ def classify_status
72
+ return :unknown if absence_conflicts_with_record?
73
+
74
+ evidence = []
75
+ evidence << :registered if registered_evidence?
76
+ evidence << :reserved if reserved_evidence?
77
+ evidence << :available if available_evidence?
78
+ evidence.one? ? evidence.first : :unknown
79
+ end
80
+
81
+ def absence_conflicts_with_record?
82
+ return false unless absence_domain_names.any?
83
+
84
+ domain_names.any? || status_values.any? || content_for_scanner.match?(/^[ \t]*Domain Name:/i)
85
+ end
86
+
87
+ def registered_evidence?
88
+ domain_names.one? && status_values == ["active"]
89
+ end
90
+
91
+ def reserved_evidence?
92
+ domain_names.one? && status_values == ["reserved"]
93
+ end
94
+
95
+ def available_evidence?
96
+ absence_domain_names.one? && status_values.empty? &&
97
+ !content_for_scanner.match?(/^[ \t]*Domain Name:/i)
98
+ end
99
+
100
+ def domain_names
101
+ content_for_scanner.scan(
102
+ /^[ \t]*Domain Name:[ \t]*((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+uz)[ \t]*$/i
103
+ ).flatten.map(&:downcase).uniq
104
+ end
105
+
106
+ def status_values
107
+ content_for_scanner.scan(/^[ \t]*Status:[ \t]*([a-z]+)[ \t]*$/i).flatten.map(&:downcase).uniq
108
+ end
109
+
110
+ def absence_domain_names
111
+ content_for_scanner.scan(
112
+ /^[ \t]*Sorry, but domain:[ \t]*"((?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+uz)", not found in database[ \t]*$/i
113
+ ).flatten.map(&:downcase).uniq
114
+ end
115
+
80
116
  end
81
117
 
82
118
  end