rdap

package module
v0.9.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 2, 2018 License: MIT Imports: 21 Imported by: 0

README

OpenRDAP is an command line RDAP client implementation in Go. Build Status

https://www.openrdap.org - homepage

https://www.openrdap.org/demo - live demo

Features

  • Command line RDAP client
  • Query types supported:
    • ip
    • domain
    • autnum
    • nameserver
    • entity
    • help
    • url
    • domain-search
    • domain-search-by-nameserver
    • domain-search-by-nameserver-ip
    • nameserver-search
    • nameserver-search-by-ip
    • entity-search
    • entity-search-by-handle
  • Query bootstrapping (automatic RDAP server URL detection for ip/domain/autnum/(experimental) entity queries)
  • Bootstrap cache (optional, uses ~/.openrdap by default)
  • X.509 client authentication
  • Output formats: text, JSON, WHOIS style
  • Experimental object tagging support

Installation

This program uses Go. The Go compiler is available from https://golang.org/.

To install:

go get -u github.com/openrdap/rdap

This will install the "rdap" binary in your $GOPATH/go/bin directory. Try running:

~/go/bin/rdap google.com

Usage

Query type Usage
Domain (.com) rdap -v example.com
Domain (.みんな) rdap -v -e nic.みんな
Network rdap -v 2001:db8::
Autnum rdap -v AS15169
Entity (test bootstrap) rdap -v -e 1-VRSN
Nameserver rdap -v -t nameserver -s https://rdap-pilot.verisignlabs.com/rdap/v1 ns1.google.com
Help rdap -v -t help -s https://rdap-pilot.verisignlabs.com/rdap/v1
Domain Search rdap -v -t domain-search -s https://rdap-pilot.verisignlabs.com/rdap/v1 exampl*.com
Domain Search (by NS) rdap -v -t domain-search-by-nameserver -s https://rdap-pilot.verisignlabs.com/rdap/v1 ns1.google.com
Domain Search (by NS IP) rdap -v -t domain-search-by-nameserver-ip -s https://rdap-pilot.verisignlabs.com/rdap/v1 194.72.238.11
Nameserver Search rdap -v -t nameserver-search -s https://rdap-pilot.verisignlabs.com/rdap/v1 ns*.yahoo.com
Nameserver Search (by IP) rdap -v -t nameserver-search-by-ip -s https://rdap-pilot.verisignlabs.com/rdap/v1 194.72.238.11
Entity Search rdap -v -t entity-search -s https://rdap-pilot.verisignlabs.com/rdap/v1 Register*-VRSN
Entity Search (by handle) rdap -v -t entity-search-by-handle -s https://rdap-pilot.verisignlabs.com/rdap/v1 1*-VRSN

See https://www.openrdap.org/docs.

Go docs

godoc

Requires

Go 1.7+

Documentation

Overview

Package rdap implements a client for the Registration Data Access Protocol (RDAP).

RDAP is a modern replacement for the text-based WHOIS (port 43) protocol. It provides registration data for domain names/IP addresses/AS numbers, and more, in a structured format.

This client executes RDAP queries and returns the responses as Go values.

Quick usage:

client := &rdap.Client{}
domain, err := client.QueryDomain("example.cz")

if err == nil {
  fmt.Printf("Handle=%s Domain=%s\n", domain.Handle, domain.LDHName)
}

The QueryDomain(), QueryAutnum(), and QueryIP() methods all provide full contact information, and timeout after 30s.

Normal usage:

// Query example.cz.
req := &rdap.Request{
  Type: rdap.DomainRequest,
  Query: "example.cz",
}

client := &rdap.Client{}
resp, err := client.Do(req)

if domain, ok := resp.Object.(*rdap.Domain); ok {
  fmt.Printf("Handle=%s Domain=%s\n", domain.Handle, domain.LDHName)
}

As of June 2017, all five number registries (AFRINIC, ARIN, APNIC, LANIC, RIPE) run RDAP servers. A small number of TLDs (top level domains) support RDAP so far, listed on https://data.iana.org/rdap/dns.json.

The RDAP protocol uses HTTP, with responses in a JSON format. A bootstrapping mechanism (http://data.iana.org/rdap/) is used to determine the server to query.

Example
// OpenRDAP
// Copyright 2017 Tom Harwood
// MIT License, see the LICENSE file.

package main

import (
	"fmt"

	"github.com/openrdap/rdap"
)

func main() {
	var jsonBlob = []byte(`
		{
			"objectClassName": "domain",
			"rdapConformance": ["rdap_level_0"],
			"handle":          "EXAMPLECOM",
			"ldhName":         "example.com",
			"status":          ["active"],
			"entities":        [
				{
					"objectClassName": "entity",
					"handle": "EXAMPLECOMREG",
					"roles": ["registrant"],
					"vcardArray": [
						"vcard",
						[
							["version", {}, "text", "4.0"],
							["fn", {}, "text", "John Smith"],
							["adr", {}, "text",
								[
									"Box 1",
									"Suite 29",
									"1234 Fake St",
									"Toronto",
									"ON",
									"M5E 1W5",
									"Canada"
								]
							],
							["tel", {}, "uri", "tel:+1-555-555-5555"],
							["email", {}, "text", "hi@example.com"]
						]
					]
				}
			]
		}
	`)

	// Decode the response.
	d := rdap.NewDecoder(jsonBlob)
	result, err := d.Decode()

	// Print the response.
	if err != nil {
		fmt.Printf("%s\n", err)
	} else {
		domain := result.(*rdap.Domain)
		PrintDomain(domain)
	}

}

// PrintDomain prints some basic rdap.Domain fields.
func PrintDomain(d *rdap.Domain) {
	// Registry unique identifier for the domain. Here, "example.cz".
	fmt.Printf("Handle=%s\n", d.Handle)

	// Domain name (LDH = letters, digits, hyphen). Here, "example.cz".
	fmt.Printf("LDHName=%s\n", d.LDHName)

	// Domain registration status. Here, "active".
	// See https://tools.ietf.org/html/rfc7483#section-10.2.2.
	fmt.Printf("Status=%v\n", d.Status)

	// Contact information.
	for i, e := range d.Entities {
		// Contact roles, such as "registrant", "administrative", "billing".
		// See https://tools.ietf.org/html/rfc7483#section-10.2.4.
		fmt.Printf("Contact %d, roles: %v:\n", i, e.Roles)

		// RDAP uses VCard for contact information, including name, address,
		// telephone, and e-mail address.
		if e.VCard != nil {
			v := e.VCard

			// Name.
			fmt.Printf("  Name      : '%s'\n", v.Name())

			// Address.
			fmt.Printf("  POBox     : '%s'\n", v.POBox())
			fmt.Printf("  Ext       : '%s'\n", v.ExtendedAddress())
			fmt.Printf("  Street    : '%s'\n", v.StreetAddress())
			fmt.Printf("  Locality  : '%s'\n", v.Locality())
			fmt.Printf("  Region    : '%s'\n", v.Region())
			fmt.Printf("  PostalCode: '%s'\n", v.PostalCode())
			fmt.Printf("  Country   : '%s'\n", v.Country())

			// Phone numbers.
			fmt.Printf("  Tel       : '%s'\n", v.Tel())
			fmt.Printf("  Fax       : '%s'\n", v.Fax())

			// Email address.
			fmt.Printf("  Email     : '%s'\n", v.Email())

			// The raw VCard fields are also accessible.
		}
	}
}
Output:

Handle=EXAMPLECOM
LDHName=example.com
Status=[active]
Contact 0, roles: [registrant]:
  Name      : 'John Smith'
  POBox     : 'Box 1'
  Ext       : 'Suite 29'
  Street    : '1234 Fake St'
  Locality  : 'Toronto'
  Region    : 'ON'
  PostalCode: 'M5E 1W5'
  Country   : 'Canada'
  Tel       : 'tel:+1-555-555-5555'
  Fax       : ''
  Email     : 'hi@example.com'

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func RunCLI

func RunCLI(args []string, stdout io.Writer, stderr io.Writer, options CLIOptions) int

RunCLI runs the OpenRDAP command line client.

|args| are the command line arguments to use (normally os.Args[1:]). |stdout| and |stderr| are the io.Writers for STDOUT/STDERR. |options| specifies extra options.

Returns the program exit code.

Types

type Autnum

type Autnum struct {
	DecodeData *DecodeData

	Common
	Conformance     []string `rdap:"rdapConformance"`
	ObjectClassName string
	Notices         []Notice

	Handle      string
	StartAutnum *uint32
	EndAutnum   *uint32
	IPVersion   string `rdap:"ipVersion"`
	Name        string
	Type        string
	Status      []string
	Country     string
	Entities    []Entity
	Remarks     []Remark
	Links       []Link
	Port43      string
	Events      []Event
}

Autnum represents information of Autonomous System registrations.

Autnum is a topmost RDAP response object.

type CLIOptions

type CLIOptions struct {
	// Sandbox mode disables the --cache-dir option, to prevent arbitrary writes to
	// the file system.
	//
	// This is used for https://www.openrdap.org/demo.
	Sandbox bool
}

CLIOptions specifies options for the command line client.

type Client

type Client struct {
	HTTP      *http.Client
	Bootstrap *bootstrap.Client

	// Optional callback function for verbose messages.
	Verbose func(text string)

	ServiceProviderExperiment bool
	UserAgent                 string
}

Client implements an RDAP client.

This client executes RDAP requests, and returns the responses as Go values.

Quick usage:

client := &rdap.Client{}
domain, err := client.QueryDomain("example.cz")

if err == nil {
  fmt.Printf("Handle=%s Domain=%s\n", domain.Handle, domain.LDHName)
}

The QueryDomain(), QueryAutnum(), and QueryIP() methods all provide full contact information, and timeout after 30s.

Normal usage:

// Query example.cz.
req := &rdap.Request{
  Type: rdap.DomainRequest,
  Query: "example.cz",
}

client := &rdap.Client{}
resp, err := client.Do(req)

if domain, ok := resp.Object.(*rdap.Domain); ok {
  fmt.Printf("Handle=%s Domain=%s\n", domain.Handle, domain.LDHName)
}

Advanced usage:

This demonstrates custom FetchRoles, a custom Context, a custom HTTP client, a custom Bootstrapper, and a custom timeout.

// Nameserver query on rdap.nic.cz.
server, _ := url.Parse("https://rdap.nic.cz")
req := &rdap.Request{
  Type: rdap.NameserverRequest,
  Query: "a.ns.nic.cz",
  FetchRoles: []string{"all"},
  Timeout: time.Second * 45, // Custom timeout.

  Server: server,
}

req = req.WithContext(ctx) // Custom context (see https://blog.golang.org/context).

client := &rdap.Client{}
client.HTTP = &http.Client{} // Custom HTTP client.
client.Bootstrap = &bootstrap.Client{} // Custom bootstapper.

resp, err := client.Do(req)

if ns, ok := resp.Object.(*rdap.Nameserver); ok {
  fmt.Printf("Handle=%s Domain=%s\n", ns.Handle, ns.LDHName)
}

func (*Client) Do

func (c *Client) Do(req *Request) (*Response, error)

func (*Client) QueryAutnum

func (c *Client) QueryAutnum(autnum string) (*Autnum, error)

QueryAutnum makes an RDAP request for the Autonomous System Number (ASN) |autnum|.

|autnum| is an ASN string, e.g. "AS2856" or "5400".

Full contact information (where available) is provided. The timeout is 30s.

func (*Client) QueryDomain

func (c *Client) QueryDomain(domain string) (*Domain, error)

QueryDomain makes an RDAP request for the |domain|.

Full contact information (where available) is provided. The timeout is 30s.

func (*Client) QueryIP

func (c *Client) QueryIP(ip string) (*IPNetwork, error)

QueryIP makes an RDAP request for the IPv4/6 address |ip|, e.g. "192.0.2.0" or "2001:db8::".

Full contact information (where available) is provided. The timeout is 30s.

type ClientError

type ClientError struct {
	Type ClientErrorType
	Text string
}

func (ClientError) Error

func (c ClientError) Error() string

type ClientErrorType

type ClientErrorType uint
const (
	InputError ClientErrorType
	BootstrapNotSupported
	BootstrapNoMatch
	WrongResponseType
	NoWorkingServers
	ObjectDoesNotExist
	RDAPServerError
)

type Common

type Common struct {
	Lang string
}

Common contains fields which may appear anywhere in an RDAP response.

type DSData

type DSData struct {
	DecodeData *DecodeData

	Common
	KeyTag     *uint64
	Algorithm  *uint8
	Digest     string
	DigestType *uint8

	Events []Event
	Links  []Link
}

DSData is a subfield of Domain.

type DecodeData

type DecodeData struct {
	// contains filtered or unexported fields
}

DecodeData stores a snapshot of all fields in an RDAP object (in raw interface{} form), at the time of decoding. This allows the values of unknown fields to be retrieved.

DecodeData also stores minor warnings/errors generated during decoding.

DecodeData appears in each RDAP struct (e.g. rdap.Domain{}), and is populated during decoding. For manually constructed RDAP structs (d := &rdap.Domain{Handle: "x"}...), DecodeData is not relevant and can be ignored.

The snapshot values are entirely independent from other fields, and thus are not synchronised in any way.

func (DecodeData) Fields

func (r DecodeData) Fields() []string

Fields returns a list of all RDAP field names decoded.

This includes both known/unknown fields.

The names returned are the RDAP field names (not the Go field names), so "port43", not "Port43".

func (DecodeData) Notes

func (r DecodeData) Notes(name string) []string

Notes returns a list of minor warnings/errors encountered while decoding the field |name|.

|name| is the RDAP field name (not the Go field name), so "port43", not "Port43". For a full list of decoded field names, use Fields().

The warnings/errors returned look like: "invalid JSON type, expecting float".

func (DecodeData) String

func (r DecodeData) String() string

TODO (temporary, using for spew output)

func (DecodeData) UnknownFields

func (r DecodeData) UnknownFields() []string

UnknownFields returns a list of unknown RDAP fields decoded.

func (DecodeData) Value

func (r DecodeData) Value(name string) interface{}

Value returns the value of the field |name| as an interface{}.

|name| is the RDAP field name (not the Go field name), so "port43", not "Port43". For a full list of decoded field names, use Fields().

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder decodes an RDAP response (https://tools.ietf.org/html/rfc7483) into a Go value.

An RDAP response describes an object such as a Domain (data resembling "whois example.com"), or an IP Network (data resembling "whois 2001:db8::"). For a live example, see https://rdap.nic.cz/domain/ctk.cz.

To decode an RDAP response:

jsonBlob := []byte(`
  {
    "objectClassName": "domain",
    "rdapConformance": ["rdap_level_0"],
    "handle":          "EXAMPLECOM",
    "ldhName":         "example.com",
    "entities":        []
  }
`)

d := rdap.NewDecoder(jsonBlob)
result, err := d.Decode()

if err != nil {
  if domain, ok := result.(*rdap.Domain); ok {
    fmt.Printf("Domain name = %s\n", domain.LDHName)
  }
}

RDAP responses are decoded into the following types:

&rdap.Error{}                   - Responses with an errorCode value.
&rdap.Autnum{}                  - Responses with objectClassName="autnum".
&rdap.Domain{}                  - Responses with objectClassName="domain".
&rdap.Entity{}                  - Responses with objectClassName="entity".
&rdap.IPNetwork{}               - Responses with objectClassName="ip network".
&rdap.Nameserver{}              - Responses with objectClassName="nameserver".
&rdap.DomainSearchResults{}     - Responses with a domainSearchResults array.
&rdap.EntitySearchResults{}     - Responses with a entitySearchResults array.
&rdap.NameserverSearchResults{} - Responses with a nameserverSearchResults array.
&rdap.Help{}                    - All other valid JSON responses.

Note that an RDAP server may return a different response type than expected.

The decoder supports and stores unknown RDAP fields. See the DecodeData documentation for accessing them.

Decoding is performed on a best-effort basis, with "minor error"s ignored. This avoids minor errors rendering a response undecodable.

func NewDecoder

func NewDecoder(jsonBlob []byte, opts ...DecoderOption) *Decoder

NewDecoder creates a new Decoder to decode the RDAP response |jsonBlob|.

|opts| is an optional list of DecoderOptions.

func (*Decoder) Decode

func (d *Decoder) Decode() (interface{}, error)

Decode decodes the JSON document. On success, one of several values is returned.

The possible results are:

&rdap.Error{}                   - Responses with an errorCode value.
&rdap.Autnum{}                  - Responses with objectClassName="autnum".
&rdap.Domain{}                  - Responses with objectClassName="domain".
&rdap.Entity{}                  - Responses with objectClassName="entity".
&rdap.IPNetwork{}               - Responses with objectClassName="ip network".
&rdap.Nameserver{}              - Responses with objectClassName="nameserver".
&rdap.DomainSearchResults{}     - Responses with a domainSearchResults array.
&rdap.EntitySearchResults{}     - Responses with a entitySearchResults array.
&rdap.NameserverSearchResults{} - Responses with a nameserverSearchResults array.
&rdap.Help{}                    - All other valid JSON responses.

On serious errors (e.g. JSON syntax error) an error is returned. Otherwise, decoding is performed on a best-effort basis, and "minor errors" (such as incorrect JSON types) are ignored. This avoids minor errors rendering the whole response undecodable.

Minor error messages (e.g. type conversions, type errors) are embedded within each result struct, see the DecodeData fields.

type DecoderError

type DecoderError struct {
	// contains filtered or unexported fields
}

DecoderError represents a fatal error encountered while decoding.

func (DecoderError) Error

func (d DecoderError) Error() string

type DecoderOption

type DecoderOption func(*Decoder)

DecoderOption sets a Decoder option.

type Domain

type Domain struct {
	DecodeData *DecodeData

	Common
	Conformance     []string `rdap:"rdapConformance"`
	ObjectClassName string

	Notices []Notice

	Handle      string
	LDHName     string `rdap:"ldhName"`
	UnicodeName string

	Variants []Variant

	Nameservers []Nameserver

	SecureDNS *SecureDNS

	Entities []Entity
	Status   []string

	PublicIDs []PublicID `rdap:"publicIds"`
	Remarks   []Remark
	Links     []Link
	Port43    string
	Events    []Event
	Network   *IPNetwork
}

Domain represents information about a DNS name and point of delegation.

Domain is a topmost RDAP response object.

type DomainSearchResults

type DomainSearchResults struct {
	DecodeData *DecodeData

	Common
	Conformance []string `rdap:"rdapConformance"`
	Notices     []Notice

	Domains []Domain `rdap:"domainSearchResults"`
}

DomainSearchResults represents a domain search response.

DomainSearchResults is a topmost RDAP response object.

type Entity

type Entity struct {
	DecodeData *DecodeData

	Common
	Conformance     []string `rdap:"rdapConformance"`
	ObjectClassName string
	Notices         []Notice

	Handle       string
	VCard        *VCard `rdap:"vcardArray"`
	Roles        []string
	PublicIDs    []PublicID `rdap:"publicIds"`
	Entities     []Entity
	Remarks      []Remark
	Links        []Link
	Events       []Event
	AsEventActor []Event
	Status       []string
	Port43       string
	Networks     []IPNetwork
	Autnums      []Autnum
}

Entity represents information of an organisation or person.

Entity is a topmost RDAP response object.

type EntitySearchResults

type EntitySearchResults struct {
	DecodeData *DecodeData

	Common
	Conformance []string `rdap:"rdapConformance"`
	Notices     []Notice

	Entities []Entity `rdap:"entitySearchResults"`
}

EntitySearchResults represents an entity search response.

EntitySearchResults is a topmost RDAP response object.

type Error

type Error struct {
	DecodeData *DecodeData

	Common
	Conformance []string `rdap:"rdapConformance"`

	Notices []Notice

	ErrorCode   *uint16
	Title       string
	Description []string
}

Error represents an error response.

Error is a topmost RDAP response object.

type Event

type Event struct {
	DecodeData *DecodeData

	Action string `rdap:"eventAction"`
	Actor  string `rdap:"eventActor"`
	Date   string `rdap:"eventDate"`
	Links  []Link
}

Event represents some event which has occured/may occur in the future..

https://tools.ietf.org/html/rfc7483#section-4.5

type HTTPResponse

type HTTPResponse struct {
	URL      string
	Response *http.Response
	Body     []byte
	Error    error
	Duration time.Duration
}

type Help

type Help struct {
	DecodeData *DecodeData

	Common
	Conformance []string `rdap:"rdapConformance"`
	Notices     []Notice
}

Help represents a help response.

Help is a topmost RDAP response object.

type IPAddressSet

type IPAddressSet struct {
	DecodeData *DecodeData

	Common
	V6 []string
	V4 []string
}

IPAddressSet is a subfield of Nameserver.

type IPNetwork

type IPNetwork struct {
	DecodeData *DecodeData

	Common
	Conformance     []string `rdap:"rdapConformance"`
	ObjectClassName string
	Notices         []Notice

	Handle       string
	StartAddress string
	EndAddress   string
	IPVersion    string `rdap:"ipVersion"`
	Name         string
	Type         string
	Country      string
	ParentHandle string
	Status       []string
	Entities     []Entity
	Remarks      []Remark
	Links        []Link
	Port43       string
	Events       []Event
}

IPNetwork represents information of an IP Network.

IPNetwork is a topmost RDAP response object.

type KeyData

type KeyData struct {
	DecodeData *DecodeData

	Flags     *uint16
	Protocol  *uint8
	Algorithm *uint8
	PublicKey string

	Events []Event
	Links  []Link
}
type Link struct {
	DecodeData *DecodeData

	Value    string
	Rel      string
	Href     string
	HrefLang []string `rdap:"hreflang"`
	Title    string
	Media    string
	Type     string
}

Link signifies a link another resource on the Internet.

https://tools.ietf.org/html/rfc7483#section-4.2

type Nameserver

type Nameserver struct {
	DecodeData *DecodeData

	Common
	Conformance     []string `rdap:"rdapConformance"`
	ObjectClassName string
	Notices         []Notice

	Handle      string
	LDHName     string `rdap:"ldhName"`
	UnicodeName string

	IPAddresses *IPAddressSet `rdap:"ipAddresses"`

	Entities []Entity
	Status   []string
	Remarks  []Remark
	Links    []Link
	Port43   string
	Events   []Event
}

Nameserver represents information of a DNS nameserver.

Nameserver is a topmost RDAP response object.

type NameserverSearchResults

type NameserverSearchResults struct {
	DecodeData *DecodeData

	Common
	Conformance []string `rdap:"rdapConformance"`
	Notices     []Notice

	Nameservers []Nameserver `rdap:"nameserverSearchResults"`
}

NameserverSearchResults represents a nameserver search response.

NameserverSearchResults is a topmost RDAP response object.

type Notice

type Notice struct {
	DecodeData *DecodeData

	Title       string
	Type        string
	Description []string
	Links       []Link
}

Notice contains information about the entire RDAP response.

https://tools.ietf.org/html/rfc7483#section-4.3

type Printer

type Printer struct {
	// Output io.Writer.
	//
	// Defaults to os.Stdout.
	Writer io.Writer

	// Character to ident responses with.
	//
	// Defaults to ' ' (space character).
	IndentChar rune

	// Number of characters per indentation.
	//
	// Defaults to 2.
	IndentSize uint

	// OmitNotices prevents RDAP Notices from being printed.
	OmitNotices bool

	// OmitNotices prevents RDAP Remarks from being printed.
	OmitRemarks bool

	// BriefOutput shortens the output by omitting various objects. These are:
	//
	// Conformance, Notices, Remarks, Events, Port43, Variants, SecureDNS.
	BriefOutput bool

	// BriefLinks causes Link objects to be printed as a single line (the link),
	// rather than as a multi-line object.
	BriefLinks bool
}

Printer formats RDAP response objects as human readable text, and writes them to an io.Writer.

The format resembles a WHOIS response.

func (*Printer) Print

func (p *Printer) Print(obj RDAPObject)

type PublicID

type PublicID struct {
	DecodeData *DecodeData

	Type       string
	Identifier string
}

PublicID maps a public identifier to an object class.

https://tools.ietf.org/html/rfc7483#section-4.8

type RDAPObject

type RDAPObject interface{}

type Remark

type Remark struct {
	DecodeData *DecodeData

	Title       string
	Type        string
	Description []string
	Links       []Link
}

Remark contains information about the containing RDAP object.

https://tools.ietf.org/html/rfc7483#section-4.3

type Request

type Request struct {
	// Request type.
	Type RequestType

	// Request query text.
	Query string

	// Optional URL query parameters to include in the RDAP request.
	//
	// These are added to the URL returned by URL().
	Params url.Values

	// Optional RDAP server URL.
	//
	// If present, specifies the RDAP server to execute the Request on.
	// Otherwise, nil enables bootstrapping.
	//
	// For Type=RawRequest, this specifies the full RDAP URL instead (with the
	// Query/Params fields not used).
	Server *url.URL

	// Optional list of contact roles. This enables additional HTTP requests for
	// these contact roles, to obtain full contact information.
	//
	// The common WHOIS contact roles are "registrant", "administrative", and
	// "billing".
	//
	// RDAP responses may contain full contact information (such as domain
	// registrant name & address), or just a URL to it. For convenience,
	// applications may prefer to receive the full contact information.
	//
	// The FetchRoles option enables additional HTTP requests for contact
	// information. Additional HTTP requests are made for URL-only contact roles
	// matching the FetchRoles list. Additional information is then merged into
	// the Response.
	//
	// Specify a list of contact roles for which additional HTTP requests may be
	// made. The default is no extra fetches. Use the special string "all" to
	// fetch all available contact information.
	FetchRoles []string

	// Maximum request duration before timeout.
	//
	// The default is no timeout.
	Timeout time.Duration
	// contains filtered or unexported fields
}

A Request represents an RDAP request.

req := &rdap.Request{
  Type: rdap.DomainRequest,
  Query: "example.cz",
}

RDAP supports many request types. These are:

RequestType                                | Bootstrapped? | HTTP request path       | Example Query
-------------------------------------------+---------------+-------------------------+----------------
rdap.AutnumRequest                         | Yes           | autnum/QUERY            | AS2846
rdap.DomainRequest                         | Yes           | domain/QUERY            | example.cz
rdap.EntityRequest                         | Experimental  | entity/QUERY            | 86860670-VRSN
rdap.HelpRequest                           | No            | help                    | N/A
rdap.IPRequest                             | Yes           | ip/QUERY                | 2001:db8::1
rdap.NameserverRequest                     | No            | nameserver/QUERY        | ns1.skip.org
                                           |               |                         |
rdap.DomainSearchRequest                   | No            | domains?name=QUERY      | exampl*.com
rdap.DomainSearchByNameserverRequest       | No            | domains?nsLdhName=QUERY | ns1.exampl*.com
rdap.DomainSearchByNameserverIPRequest     | No            | domains?nsIp=QUERY      | 192.0.2.0
rdap.NameserverSearchRequest               | No            | nameservers?name=QUERY  | ns1.exampl*.com
rdap.NameserverSearchByNameserverIPRequest | No            | nameservers?ip=QUERY    | 192.0.2.0
rdap.EntitySearchRequest                   | No            | entities?fn=QUERY       | ABC*-VRSN
rdap.EntitySearchByHandleRequest           | No            | entities?handle=QUERY   | ABC*-VRSN
                                           |               |                         |
rdap.RawRequest                            | N/A           | N/A                     | N/A

See https://tools.ietf.org/html/rfc7482 for more information on RDAP request types.

Requests are executed by a Client. To execute a Request, an RDAP server is required. The servers for Autnum, IP, and Domain queries are determined automatically via bootstrapping (a lookup at https://data.iana.org/rdap/).

For other Request types, you must specify the RDAP server:

// Nameserver query on rdap.nic.cz.
server, _ := url.Parse("https://rdap.nic.cz")
req := &rdap.Request{
  Type: rdap.NameserverRequest,
  Query: "a.ns.nic.cz",

  Server: server,
}

RawRequest is a special case for existing RDAP request URLs:

rdapURL, _ := url.Parse("https://rdap.example/mystery/query?ip=192.0.2.0")
req := &rdap.Request{
  Type: rdap.RawRequest,
  Server: rdapURL,
}

func NewAutnumRequest

func NewAutnumRequest(asn uint32) *Request

NewAutnumRequest creates a new Request for the AS number |asn|.

func NewAutoRequest

func NewAutoRequest(queryText string) *Request

NewAutoRequest creates a Request by guessing the type required for |queryText|.

The following types are suppported:

Returns a Request. Use r.Type to find the RequestType chosen.

func NewDomainRequest

func NewDomainRequest(domain string) *Request

NewDomainRequest creates a new Request for the domain name |domain|.

func NewEntityRequest

func NewEntityRequest(entity string) *Request

NewEntityRequest creates a new Request for the entity name |entity|.

The RDAP server must be specified.

func NewHelpRequest

func NewHelpRequest() *Request

NewHelpRequest creates a new help Request.

The RDAP server must be specified.

func NewIPNetRequest

func NewIPNetRequest(net *net.IPNet) *Request

NewIPNetRequest creates a new Request for the IP network |net|.

func NewIPRequest

func NewIPRequest(ip net.IP) *Request

NewIPRequest creates a new Request for the IP address |ip|.

func NewNameserverRequest

func NewNameserverRequest(nameserver string) *Request

NewNameserverRequest creates a new Request for the nameserver |nameserver|.

The RDAP server must be specified.

func NewRawRequest

func NewRawRequest(rdapURL *url.URL) *Request

NewRawRequest creates a Request from the URL |rdapURL|.

When a client executes the Request, it will fetch |rdapURL|.

func NewRequest

func NewRequest(requestType RequestType, query string) *Request

NewRequest creates a new Request with type |requestType| and |query| text.

Depending on the |requestType|, the RDAP server may need to be specified.

func (*Request) Context

func (r *Request) Context() context.Context

Context returns the Request's context.

The returned context is always non-nil; it defaults to the background context.

func (*Request) URL

func (r *Request) URL() *url.URL

URL constructs and returns the RDAP Request URL.

As an example:

server, _ := url.Parse("https://rdap.nic.cz")
req := &rdap.Request{
  Type: rdap.NameserverRequest,
  Query: "a.ns.nic.cz",

  Server: server,
}

fmt.Println(req.URL()) // Prints https://rdap.nic.cz/nameserver/a.ns.nic.cz.

Returns nil if the Server field is nil.

For Type=RawRequest, the Server field is returned unmodified.

func (*Request) WithContext

func (r *Request) WithContext(ctx context.Context) *Request

WithContext returns a copy of the Request, with Context |ctx|.

func (*Request) WithServer

func (r *Request) WithServer(server *url.URL) *Request

WithServer returns a copy of the Request, with the Server set to |server|.

type RequestType

type RequestType uint8

A RequestType specifies an RDAP request type.

const (
	AutnumRequest RequestType
	DomainRequest
	EntityRequest
	HelpRequest
	IPRequest
	NameserverRequest

	DomainSearchRequest
	DomainSearchByNameserverRequest
	DomainSearchByNameserverIPRequest
	NameserverSearchRequest
	NameserverSearchByNameserverIPRequest
	EntitySearchRequest
	EntitySearchByHandleRequest

	// RawRequest is a request with a fixed RDAP URL.
	RawRequest
)

func (RequestType) String

func (r RequestType) String() string

String returns the RequestType as a string. e.g. "autnum", "domain", "help".

type Response

type Response struct {
	Object          RDAPObject
	BootstrapAnswer *bootstrap.Answer
	HTTP            []*HTTPResponse
}

func (*Response) ToWhoisStyleResponse

func (r *Response) ToWhoisStyleResponse() *WhoisStyleResponse

type SecureDNS

type SecureDNS struct {
	DecodeData *DecodeData

	Common
	ZoneSigned       *bool
	DelegationSigned *bool
	MaxSigLife       *uint64
	DS               []DSData  `rdap:"dsData"`
	Keys             []KeyData `rdap:"keyData"`
}

SecureDNS is ia subfield of Domain.

type VCard

type VCard struct {
	Properties []*VCardProperty
}

VCard represents a vCard.

A vCard represents information about an individual or entity. It can include a name, telephone number, e-mail, delivery address, and other information.

There are several vCard text formats. This implementation encodes/decodes the jCard format used by RDAP, as defined in https://tools.ietf.org/html/rfc7095.

A jCard consists of an array of properties (e.g. "fn", "tel") describing the individual or entity. Properties may be repeated, e.g. to represent multiple telephone numbers. RFC6350 documents a set of standard properties.

RFC7095 describes the JSON document format, which looks like:

["vcard", [
  [
    ["version", {}, "text", "4.0"],
    ["fn", {}, "text", "Joe Appleseed"],
    ["tel", {
          "type":["work", "voice"],
        },
        "uri",
        "tel:+1-555-555-1234;ext=555"
    ],
    ...
  ]
]

func NewVCard

func NewVCard(jsonBlob []byte) (*VCard, error)

NewVCard creates a VCard from jsonBlob.

func (*VCard) Country

func (v *VCard) Country() string

Country returns the address country name.

This is the full country name.

Returns empty string if no address is present.

func (*VCard) Email

func (v *VCard) Email() string

Email returns the VCard's first email address.

Returns empty string if the VCard contains no email addresses.

func (*VCard) ExtendedAddress

func (v *VCard) ExtendedAddress() string

ExtendedAddress returns the "extended address", e.g. an apartment or suite number.

Returns empty string if no address is present.

func (*VCard) Fax

func (v *VCard) Fax() string

Fax returns the VCard's first fax number.

Returns empty string if the VCard contains no fax number.

func (*VCard) Get

func (v *VCard) Get(name string) []*VCardProperty

Get returns a list of the vCard Properties with VCardProperty name |name|.

func (*VCard) GetFirst

func (v *VCard) GetFirst(name string) *VCardProperty

GetFirst returns the first vCard Property with name |name|.

TODO(tfh): Implement "pref" ordering, instead of taking the first listed property?

func (*VCard) Locality

func (v *VCard) Locality() string

Locality returns the address locality.

Returns empty string if no address is present.

func (*VCard) Name

func (v *VCard) Name() string

Name returns the VCard's name. e.g. "John Smith".

func (*VCard) POBox

func (v *VCard) POBox() string

POBox returns the address's PO Box.

Returns empty string if no address is present.

func (*VCard) PostalCode

func (v *VCard) PostalCode() string

PostalCode returns the address postal code (e.g. zip code).

Returns empty string if no address is present.

func (*VCard) Region

func (v *VCard) Region() string

Region returns the address region (e.g. state or province).

Returns empty string if no address is present.

func (*VCard) StreetAddress

func (v *VCard) StreetAddress() string

StreetAddress returns the street address.

Returns empty string if no address is present.

func (*VCard) String

func (v *VCard) String() string

String returns the vCard as a multiline human readable string. For example:

vCard[
  version (type=text, parameters=map[]): [4.0]
  mixed (type=text, parameters=map[]): [abc true 42 <nil> [def false 43]]
]

This is intended for debugging only, and is not machine parsable.

func (*VCard) Tel

func (v *VCard) Tel() string

Tel returns the VCard's first (voice) telephone number.

Returns empty string if the VCard contains no suitable telephone number.

type VCardProperty

type VCardProperty struct {
	Name string

	// vCard parameters can be a string, or array of strings.
	//
	// To simplify our usage, single strings are represented as an array of
	// length one.
	Parameters map[string][]string
	Type       string

	// A property value can be a simple type (string/float64/bool/nil), or be
	// an array. Arrays can be nested, and can contain a mixture of types.
	//
	// Value is one of the following:
	//   * string
	//   * float64
	//   * bool
	//   * nil
	//   * []interface{}. Can contain a mixture of these five types.
	//
	// To retrieve the property value flattened into a []string, use Values().
	Value interface{}
}

VCardProperty represents a single vCard property.

Each vCard property has four fields, these are:

 Name   Parameters                  Type   Value
 -----  --------------------------  -----  -----------------------------
["tel", {"type":["work", "voice"]}, "uri", "tel:+1-555-555-1234;ext=555"]

func (*VCardProperty) String

func (p *VCardProperty) String() string

String returns the VCardProperty as a human readable string. For example:

mixed (type=text, parameters=map[]): [abc true 42 <nil> [def false 43]]

This is intended for debugging only, and is not machine parsable.

func (*VCardProperty) Values

func (p *VCardProperty) Values() []string

Values returns a simplified representation of the VCardProperty value.

This is convenient for accessing simple unstructured data (e.g. "fn", "tel").

The simplified []string representation is created by flattening the (potentially nested) VCardProperty value, and converting all values to strings.

type Variant

type Variant struct {
	DecodeData *DecodeData

	Common
	Relation     []string
	IDNTable     string `rdap:"idnTable"`
	VariantNames []VariantName
}

Variant is a subfield of Domain.

type VariantName

type VariantName struct {
	DecodeData *DecodeData

	Common
	LDHName     string `rdap:"ldhName"`
	UnicodeName string
}

VariantName is a subfield of Variant.

type WhoisStyleResponse

type WhoisStyleResponse struct {
	KeyDisplayOrder []string
	Data            map[string][]string
}

Directories

Path Synopsis
Package bootstrap implements an RDAP bootstrap client.
Package bootstrap implements an RDAP bootstrap client.
cache
Package cache implements RDAP Service Registry file caching.
Package cache implements RDAP Service Registry file caching.
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL