Golang中使用openRDAP查询GitHub数据的求助指南

Golang中使用openRDAP查询GitHub数据的求助指南 我正在查看这个 openRDAP GitHub 仓库 https://github.com/openrdap/rdap,并可能在我正在做的一些工作中使用它。我试图遵循 client.go 文件中 advanced usage 部分第 45 到 70 行的说明(这里是链接 https://github.com/openrdap/rdap/blob/master/client.go),并使用服务器 https://rdap.markmonitor.com/rdap 进行一个域名查询(以 google.com 为例)。以下是我的代码,但得到了 No RDAP servers responded successfully (tried 1 server(s)) 错误。在他们的命令行界面中,例如 rdap -s https://rdap.markmonitor.com/rdap google.com,这是可以正常工作的,现在我想用代码来实现这个功能,却遇到了错误。有什么想法吗?

package main

import (
	_ "context"
	"fmt"
	"github.com/openrdap/rdap"
	"github.com/openrdap/rdap/bootstrap"
	"net/url"
	"time"
)

func main() {
	// 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.markmonitor.com/rdap")
	  req := &rdap.Request{
	    Type: rdap.DomainRequest,
	    Query: "google.com",
	    FetchRoles: []string{"all"},
	    Timeout: time.Second * 45, // Custom timeout.

	    Server: server,
	  }

	  //req = req.WithContext(context.Context) // 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 err != nil {
	  	fmt.Println(err.Error())
	  }

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

更多关于Golang中使用openRDAP查询GitHub数据的求助指南的实战教程也可以访问 https://www.itying.com/category-94-b0.html

6 回复

感谢 @hollowaykeanho 的检查。如果我有所发现或收到开发者的回复,我会通知你。

更多关于Golang中使用openRDAP查询GitHub数据的求助指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


感谢 @hollowaykeanho 的检查。我已经为开发者创建了一个工单。

如果你下载那个仓库并运行 rdap -s https://rdap.markmonitor.com/rdap google.com,它是可以工作的。我想知道我应该在哪里/如何检查带有 -s 参数的那个命令的代码?是在 CLI 部分吗?

// 代码部分保持原样,此处仅为示例占位。实际转换中,原HTML内容中未提供具体的Go代码块。
// 如果原内容包含类似 <pre><code>...</code></pre> 的Go代码,它们会被正确包裹。

jameswang2015: 运行 rdap -s https://rdap.markmonitor.com/rdap google.com 是有效的。

我这边也是同样的结果。这样的话,第一点 rdap 客户端这边有些情况 应该是对的。在配置过程中,确实发生了一些我们目前尚未察觉的情况。

jameswang2015: 想知道我应该在哪里/如何查看带 -s 参数命令的代码?是在 CLI 部分吗?

目前,我们的行动方案要么是自己研究代码(我已经在做了),要么等待开发团队回答你的问题。

你可以从 cmd 应用程序开始顺着线索查找。它会引导你到 cli.go,然后从那里继续向前。请在方便的时候随时进行。😄

该RDAP服务使用默认的RDAP服务器(称为引导程序)来响应每个请求(针对域名、IP、自治系统有多种类型的请求)。它也应该支持使用自定义服务器来响应查询,这个使用自定义服务器而非默认引导服务器的功能正是我感兴趣且目前遇到困难的地方。关于这个默认引导程序和自定义服务器的更多信息,请参考:https://github.com/openrdap/rdap/blob/master/bootstrap/client.go。

在我的代码中,我在 server, _ := url.Parse("https://rdap.markmonitor.com/rdap") 中提供了自定义服务器的URL,并且我希望使用该服务器来响应针对 google.comDomain 查询。顺便提一下,如果你在网页浏览器中输入 https://rdap.markmonitor.com/rdap/domain/google.com,你可以看到预期的结果。但在代码中这不起作用。

也许我误解了提供自定义服务器URL的方式?是否应该通过 &bootstrap.Client{} 来完成?

谢谢

在我这边测试了一段代码。运行正常。

代码
package main

import (
	"context"
	"fmt"
	"net/http"
	"time"

	"github.com/openrdap/rdap"
	"github.com/openrdap/rdap/bootstrap"
)

func simpleQuery(s string) *rdap.Domain {
	client := &rdap.Client{}

	domain, err := client.QueryDomain(s)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return nil
	}

	return domain
}

func customizeQuery(ctx context.Context,
	c *http.Client,
	b *bootstrap.Client,
	s string) *rdap.Domain {
	req := &rdap.Request{
		Type:       rdap.DomainRequest,
		Query:      s,
		FetchRoles: []string{"all"},
		Timeout:    45 * time.Second,
	}
	req = req.WithContext(ctx)

	client := &rdap.Client{}
	client.HTTP = c
	client.Bootstrap = b

	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("Error: %v\n", err)
		return nil
	}

	if d, ok := resp.Object.(*rdap.Domain); ok {
		return d
	}
	return nil
}

// MAINS

func basicMain() {
	d := simpleQuery("google.com")
	if d == nil {
		return
	}

	fmt.Printf("BASIC: Handle=%s Domain=%s\n", d.Handle, d.LDHName)
}

func advancedMain() {
	ctx, cancel := context.WithTimeout(context.TODO(), 45*time.Second)
	defer cancel()

	c := &http.Client{
		Timeout: 60 * time.Second,
	}

	b := &bootstrap.Client{}
	// read up to customize bootstrap

	d := customizeQuery(ctx, c, b, "google.com")
	if d == nil {
		return
	}

	fmt.Printf("ADV  : Handle=%s Domain=%s\n", d.Handle, d.LDHName)
}

func main() {
	basicMain()
	advancedMain()
}
// Output:
// BASIC: Handle=2138514_DOMAIN_COM-VRSN Domain=GOOGLE.COM
// ADV  : Handle=2138514_DOMAIN_COM-VRSN Domain=GOOGLE.COM

我注意到以下几点可能会导致问题:

  1. 基础版本执行的是域名查询,而高级版本执行的是名称服务器查询。从你对高级代码的最终检查来看,你将其转换为了域名类型,而不是名称服务器类型。
  2. 我实际上省略了 url.Parse,因为在我看来执行双重查询没有意义(免责声明:我不是内容专家)。
  3. 可用的请求类型有很多,所以在继续之前请务必理解整个包。链接:https://github.com/openrdap/rdap/blob/master/request.go
  4. 另一件让我觉得不合理的事情是到处设置超时(http客户端,然后又是rdap客户端)。我认为rdap已经准备就绪,你可以直接用它进行查询,无需过多定制。

在你的代码中,主要问题是Server字段的设置方式不正确。rdap.RequestServer字段期望的是一个字符串类型的URL,而不是*url.URL类型。此外,直接指定服务器时,不需要使用Bootstrapper

以下是修正后的代码示例:

package main

import (
	"fmt"
	"github.com/openrdap/rdap"
	"time"
)

func main() {
	req := &rdap.Request{
		Type:       rdap.DomainRequest,
		Query:      "google.com",
		FetchRoles: []string{"all"},
		Timeout:    time.Second * 45,
		Server:     "https://rdap.markmonitor.com/rdap", // 直接使用字符串URL
	}

	client := &rdap.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error:", err.Error())
		return
	}

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

如果你想要更接近rdap命令行工具的行为,可以使用bootstrap来查找服务器,而不是直接指定:

package main

import (
	"fmt"
	"github.com/openrdap/rdap"
	"github.com/openrdap/rdap/bootstrap"
	"time"
)

func main() {
	req := &rdap.Request{
		Type:       rdap.DomainRequest,
		Query:      "google.com",
		FetchRoles: []string{"all"},
		Timeout:    time.Second * 45,
	}

	client := &rdap.Client{}
	client.Bootstrap = &bootstrap.Client{
		BootstrapURL: "https://rdap.markmonitor.com/rdap",
	}

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Error:", err.Error())
		return
	}

	if ns, ok := resp.Object.(*rdap.Domain); ok {
		fmt.Printf("Handle=%s Domain=%s\n", ns.Handle, ns.LDHName)
		// 打印更多域名信息
		fmt.Printf("Nameservers: %v\n", ns.Nameservers)
		fmt.Printf("Status: %v\n", ns.Status)
		fmt.Printf("Events: %v\n", ns.Events)
	} else {
		fmt.Println("Unexpected response type")
	}
}

如果问题仍然存在,可以检查网络连接和服务器状态:

package main

import (
	"fmt"
	"net/http"
	"time"
	"github.com/openrdap/rdap"
)

func main() {
	// 测试服务器可达性
	httpClient := &http.Client{Timeout: time.Second * 10}
	resp, err := httpClient.Get("https://rdap.markmonitor.com/rdap/domain/google.com")
	if err != nil {
		fmt.Println("Server test failed:", err)
		return
	}
	defer resp.Body.Close()
	
	fmt.Println("Server response status:", resp.Status)

	// RDAP查询
	req := &rdap.Request{
		Type:       rdap.DomainRequest,
		Query:      "google.com",
		FetchRoles: []string{"all"},
		Timeout:    time.Second * 45,
		Server:     "https://rdap.markmonitor.com/rdap",
	}

	client := &rdap.Client{}
	rdapResp, err := client.Do(req)
	if err != nil {
		fmt.Println("RDAP query error:", err.Error())
		return
	}

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

确保你的网络环境可以访问rdap.markmonitor.com服务器,并且该服务器确实支持RDAP查询。有些RDAP服务器可能需要特定的路径格式或查询参数。

回到顶部