CycleTLS

CycleTLS

自定义TLS指纹模拟的高性能工具

CycleTLS是一款高性能TLS指纹模拟工具,支持自定义JA3指纹、HTTP头顺序和用户代理。它采用goroutine池处理异步请求,支持代理,并提供JavaScript和Go语言API。CycleTLS能够精确模拟不同浏览器的TLS行为,可用于网络测试和安全研究。作为一个开源项目,CycleTLS为开发者提供了灵活的网络通信模拟功能。

CycleTLSTLSHTTPGolangNode.jsGithub开源项目

CycleTLS

<div align="center"> <img src="https://yellow-cdn.veclightyear.com/835a84d5/566c9cd5-e921-49e0-aa72-00b525d498d1.png" alt="CycleTLS"/> <br>

接受社区支持和PR

构建 GoDoc 许可证 Go 报告卡 npm 版本 <a href="https://discord.gg/gsmxMHrwhu"> <img src="https://img.shields.io/discord/1100945880888115200?logo=discord" alt="在 Discord 上聊天"></a>

</div>

如果您有API更改或功能请求,请随时开启一个问题

🚀 特性

  • 高性能 内置的goroutine池用于处理异步请求
  • 通过fhttp实现自定义头部排序
  • 代理支持 | Socks4, Socks5, Socks5h
  • Ja3 Token配置

目录

依赖

node ^v16.0
golang ^v1.21x

安装

Node Js

$ npm install cycletls

Golang

$ go get github.com/Danny-Dasilva/CycleTLS/cycletls

用法

TypeScript和JavaScript的CycleTLS请求示例

您可以在tests/simple.test.ts中运行此测试

const initCycleTLS = require('cycletls'); // TypeScript: import initCycleTLS from 'cycletls'; (async () => { // 初始化CycleTLS const cycleTLS = await initCycleTLS(); // 发送请求 const response = await cycleTLS('https://ja3er.com/json', { body: '', ja3: '771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0', userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0', proxy: 'http://username:password@hostname.com:443', }, 'get'); console.log(response); // 清理退出CycleTLS cycleTLS.exit(); })();

Golang的CycleTLS请求示例

package main import ( "log" "github.com/Danny-Dasilva/CycleTLS/cycletls" ) func main() { client := cycletls.Init() response, err := client.Do("https://ja3er.com/json", cycletls.Options{ Body : "", Ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0", UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0", }, "GET"); if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(response) }

使用自定义http.Client的示例

<details>
import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" http "github.com/Danny-Dasilva/fhttp" // 注意这是net/http的替代品 ) func main() { ja3 := "771,52393-52392-52244-52243-49195-49199-49196-49200-49171-49172-156-157-47-53-10,65281-0-23-35-13-5-18-16-30032-11-10,29-23-24,0" ua := "Chrome Version 57.0.2987.110 (64-bit) Linux" cycleClient := &http.Client{ Transport: cycletls.NewTransport(ja3, ua), } resp, err := cycleClient.Get("https://tls.peet.ws/") ... }
</details>

创建实例

要创建cycleTLS实例,您可以运行以下代码:

JavaScript

// initCycleTLS函数会生成一个Golang进程,通过goroutine循环并发处理所有请求。 const initCycleTLS = require('cycletls'); // import initCycleTLS from 'cycletls'; // 异步/等待方法 const cycleTLS = await initCycleTLS(); // .then方法 initCycleTLS().then((cycleTLS) => {});

Golang

import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" ) //`Init`函数初始化golang通道以处理请求。 client := cycletls.Init()

CycleTLS 别名方法

CycleTLS 中存在以下方法:

cycleTLS(url, [config])

cycleTLS.get(url, [config])

cycleTLS.delete(url, [config])

cycleTLS.head(url, [config])

cycleTLS.options(url, [config])

cycleTLS.post(url, [config])

cycleTLS.put(url, config)

cycleTLS.patch(url, [config])

url 是必需的,config 是可选的

CycleTLS 请求配置

{ // 请求的 URL(如果未作为参数指定,则为必需) url: "https://example.com" // 请求的方法("head" | "get" | "post" | "put" | "delete" | "trace" | "options" | "connect" | "patch") method: "get" // 默认方法 // 要发送的自定义头部 headers: { "Authorization": "Bearer someexampletoken" } // 要发送的自定义 Cookie Cookies: [{ "name": "key", "value": "val", "path": "/docs", "domain": "google.com", "expires": "Mon, 02-Jan-2022 15:04:05 EST" "maxAge": 90, "secure": false, "httpOnly": true, "sameSite": "Lax" }], // 要随请求发送的正文(必须是字符串 - 不能传递对象) body: '', // 要随请求发送的 JA3 令牌 ja3: '771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0', // 请求的用户代理 userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0', // 发送请求时使用的代理(必须是相同的格式) proxy: 'http://username:password@hostname.com:443', // 请求超时前的秒数(默认:7) timeout: 2, // 切换 CycleTLS 是否应该跟随重定向 disableRedirect: true, // 要随请求发送的自定义头部顺序(此值将覆盖默认头部顺序) headerOrder: ["cache-control", "connection", "host"], // 切换 CycleTLS 是否应该跳过证书验证(如果 InsecureSkipVerify 为 true,TLS 接受服务器提供的任何证书和该证书中的任何主机名) insecureSkipVerify: false // 强制 CycleTLS 执行 HTTP1 握手 forceHTTP1: false }

CycleTLS 响应模式

{ // 服务器返回的状态码(数字) status: 200, // 服务器返回的正文(字符串) body: "", // 服务器返回的头部(对象) headers: { "some": "header", ... }, // 服务器返回的最终 URL(字符串)。当重定向激活时,此字段很有用。 finalUrl: "https://final.url/" }

TypeScript 和 JavaScript 的多个请求示例

如果 CycleTLS 在 JavaScript 环境中使用,CycleTLS 将生成一个 Golang 进程来处理请求。这个 Golang 进程在工作池中并发处理请求。因此,CycleTLS 在响应对象可用时立即返回它们(换句话说,CycleTLS 按接收顺序处理请求,但响应异步返回,所以它们不会按请求顺序返回)

如果你在 JavaScript 中使用 CycleTLS,有必要退出实例以防止僵尸进程。下面的示例展示了一种在需要处理多个请求时清理退出 CycleTLS 的方法(注意:请记住,调用 exit() 函数将终止所有正在进行的请求)。如果你的工作流程需要在整个进程运行期间保持请求运行,像 exit-hook 这样的模块可以作为清理退出 CycleTLS 的替代解决方案。

const initCycleTLS = require("cycletls"); // TypeScript: import initCycleTLS from 'cycletls'; // 在多个请求上定义自定义 JA3 令牌和用户代理 const ja3 = "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0"; const userAgent = "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0"; // 请求字典 const requestDict = { "https://httpbin.org/get": {}, "https://httpbin.org/user-agent": { ja3: ja3, userAgent: userAgent, }, "http://httpbin.org/post": { body: '{"field":"POST-VAL"}', method: "POST", }, "http://httpbin.org/cookies": { cookies: [ { name: "example1", value: "aaaaaaa", expires: "Mon, 02-Jan-2022 15:04:05 EST", }, ], }, }; // 请求的 Promise 数组 const promises = []; // 匿名异步函数 (async () => { // 初始化 CycleTLS const cycleTLS = await initCycleTLS(); // 遍历上面定义的 requestDict(对象) for (const url in requestDict) { // 从 requestDict(对象)获取配置 const params = requestDict[url]; // 发送请求(注意:不等待) const response = cycleTLS( url, { body: params.body ?? "", // ?? 在这里只是设置默认值 ja3: params.ja3 ?? ja3, userAgent: params.userAgent ?? userAgent, headers: params.headers, cookies: params.cookies, }, params.method ?? "GET"); // 打印响应对象 response.then((out) => { console.log(url, out); }); // 将请求推送到 Promise 数组 promises.push(response); } // 等待所有请求成功执行 Promise.all(promises).then(() => { // 在收到所有请求后清理退出 CycleTLS cycleTLS.exit(); }); })();

Golang 的多个请求示例

对于 golang 包,通常期望用户实现工作池或任何其他形式的 goroutine/异步处理。这个包包含一个内置的 Queue 方法,它利用工作池/通道来处理针对一组 URL 的长时间运行的异步请求。

package main import ( "log" cycletls "github.com/Danny-Dasilva/CycleTLS/cycletls" ) // 静态变量 var ( ja3 = "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0" userAgent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36" ) // RequestConfig 保存每个请求的配置。 type RequestConfig struct { URL string Method string Options cycletls.Options } func main() { client := cycletls.Init(true) // 初始化工作池

// 定义请求 requests := []RequestConfig{ { URL: "http://httpbin.org/delay/4", Method: "GET", Options: cycletls.Options{ Ja3: ja3, UserAgent: userAgent, }, }, { URL: "http://httpbin.org/post", Method: "POST", Options: cycletls.Options{ Body: {"field":"POST-VAL"}, Ja3: ja3, UserAgent: userAgent, }, }, { URL: "http://httpbin.org/cookies", Method: "GET", Options: cycletls.Options{ Ja3: ja3, UserAgent: userAgent, Cookies: []cycletls.Cookie{ { Name: "example1", Value: "aaaaaaa", }, }, }, }, }

// 将请求加入队列
for _, req := range requests {
	client.Queue(req.URL, req.Options, req.Method)
}

// 异步读取响应,一旦可用就立即返回
// 它们会在处理完成后立即返回
// 例如,延迟3秒的请求将最后返回
for i := 0; i < len(requests); i++ {
	response := <-client.RespChan
	log.Println("响应:", response)
}

// 关闭客户端
client.Close()

}


# 开发设置

如果您想自己编译CycleTLS,请使用以下命令:

设置模块感知模式
`go env -w  GO111MODULE=off`

安装Golang依赖
`go get github.com/Danny-Dasilva/CycleTLS/cycletls`

安装npm包(此命令会处理上述步骤)

`npm install`

### 重新编译src文件夹中的index.ts

`npm run build`

### 重新编译golang文件夹中的Golang文件

全部

`npm run build:go`

Windows

`npm run build:go:windows:amd64`

Linux

`npm run build:go:linux:amd64`

Mac

`npm run build:go:mac:arm64`


您可以在`package.json`中查看可用的编译选项

## 问题

### 如何设置Cookies
<details>

有两种简单的方法来操作cookies 
### JavaScript简单Cookie配置

```js
const initCycleTLS = require("cycletls");
(async () => {
  // 初始化cycleTLS
  const cycleTLS = await initCycleTLS();
  const response = await cycleTLS("https://httpbin.org/cookies", {
    cookies: {
      cookie1: "value1",
      cookie2: "value2",
    },
  });
  console.log(response.body);
  /* 预期输出
  {
    "cookies": {
      "cookie1": "value1",
      "cookie2": "value2"
    }
  }
  */
  cycleTLS.exit();
})();

在这个简单的例子中,您可以在一个对象中设置cookie的namevalue

JavaScript复杂Cookie配置

如果您希望对cookie参数有更精细的控制,您可以访问完整的底层Go结构

以下是您可以设置的值:

export interface Cookie { name: string; value: string; path?: string; domain?: string; expires?: string; rawExpires?: string; maxAge?: number; secure?: boolean; httpOnly?: boolean; sameSite?: string; unparsed?: string; }

您可以在请求中如下使用它们:

const initCycleTLS = require("cycletls"); (async () => { // 初始化cycleTLS const cycleTLS = await initCycleTLS(); const complexCookies = [ { name: "cookie1", value: "value1", domain: "httpbin.org", }, { name: "cookie2", value: "value2", domain: "httpbin.org", }, ]; const response = await cycleTLS("https://httpbin.org/cookies", { cookies: complexCookies, }); console.log(response.body); /* 预期输出 { "cookies": { "cookie1": "value1", "cookie2": "value2" } } */ cycleTLS.exit(); })();

Golang配置Cookies

package main import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" ) func main() { resp, err := client.Do("https://httpbin.org/cookies", cycletls.Options{ Body: "", Ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0", UserAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0", Cookies: []cycletls.Cookie{{Name: "cookie1", Value: "value1"}, {Name: "cookie2", Value: "value2"}}, }, "GET") if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(resp.Body) /* 预期输出 { "cookies": { "cookie1": "value1", "cookie2": "value2" } } */ //或者,如果您想访问映射中的值 log.Println(resp.JSONBody()) /* 预期输出 map[cookies:map[cookie1:value1 cookie2:value2]] */ }

如果您需要特定文件类型支持的功能请求,请随时在Issue中提出。

</details>

如何在CycleTLS中使用CookieJar?

<details>

JS中的CookieJar

const initCycleTLS = require("cycletls"); const tough = require("tough-cookie"); const Cookie = tough.Cookie; (async () => { // 初始化cycleTLS和CookieJar const cycleTLS = await initCycleTLS(); const cookieJar = new tough.CookieJar(); // 捕获设置的cookie const firstResponse = await cycleTLS.get( "https://httpbin.org/cookies/set?freeform=test", { disableRedirect: true, } ); // 现在使用processCookies函数将响应头中的cookies添加到cookie jar中 await processCookies( firstResponse, "https://httpbin.org/cookies/set?freeform=test", cookieJar ); // 现在发送第二个请求以验证我们是否有cookies const secondResponse = await cycleTLS.get("https://httpbin.org/cookies", { headers: { cookie: await cookieJar.getCookieString("https://httpbin.org/cookies"), }, }); //验证cookies是否已设置 console.log(secondResponse.body) /* 预期输出 { "cookies": { "freeform": "test" } } */ cycleTLS.exit(); })(); 异步函数 processCookies(response, url, cookieJar) { 如果 response.headers["Set-Cookie"] 是一个数组 { response.headers["Set-Cookie"].map( 异步 (cookieString) => 等待 cookieJar.setCookie(cookieString, url) ); } 否则 { 等待 cookieJar.setCookie(response.headers["Set-Cookie"], url); } } ### Golang中的CookieJar ```go package main import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" "log" "net/http/cookiejar" "net/url" "strings" ) func main() { client := cycletls.Init() jar, err := cookiejar.New(nil) if err != nil { log.Fatal(err) } // 第一个请求设置cookie firstResponse, err := client.Do("https://httpbin.org/cookies/set?a=1&b=2&c=3", cycletls.Options{ Body: "", Ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0", UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36", DisableRedirect: true, }, "GET") if err != nil { log.Fatal(err) } firstURL, _ := url.Parse(firstResponse.FinalUrl) jar.SetCookies( firstURL, firstResponse.Cookies) // 第二个请求验证cookies,包含第一个响应中的cookies secondResponse, err := client.Do("https://httpbin.org/cookies", cycletls.Options{ Body: "", Ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513,29-23-24,0", UserAgent: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.54 Safari/537.36", Headers: map[string]string{ "Cookie": getHeadersFromJar(jar, firstURL), }, }, "GET") if err != nil { log.Fatal(err) } log.Println("第二个响应体:", secondResponse.Body) } func getHeadersFromJar(jar *cookiejar.Jar, url *url.URL) string { cookies := jar.Cookies(url) var cookieStrs []string for _, cookie := range cookies { cookieStrs = append(cookieStrs, cookie.Name+"="+cookie.Value) } return strings.Join(cookieStrs, "; ") }

如何在CycleTLS中发送multipart/form-data

Javascript文本form-data

const initCycleTLS = require("cycletls"); const FormData = require('form-data'); (async () => { const cycleTLS = await initCycleTLS(); const formData = new FormData(); formData.append("key1", "value1"); formData.append("key2", "value2"); const response = await cycleTLS('http://httpbin.org/post', { body: formData, headers: { 'Content-Type': 'multipart/form-data', }, }, 'post'); console.log(response); cycleTLS.exit(); })();

Javascript文件form-data

const initCycleTLS = require("cycletls"); const FormData = require('form-data'); const fs = require('fs'); (async () => { const cycleTLS = await initCycleTLS(); const formData = new FormData(); const fileStream = fs.createReadStream("../go.mod"); formData.append('file', fileStream); const response = await cycleTLS('http://httpbin.org/post', { body: formData, headers: { 'Content-Type': 'multipart/form-data', }, }, 'post'); console.log(response); cycleTLS.exit(); })();

Golang文本form-data

package main import ( "bytes" "github.com/Danny-Dasilva/CycleTLS/cycletls" "log" "mime/multipart" ) func main() { client := cycletls.Init() // 准备一个buffer来写入我们的multipart表单 var requestBody bytes.Buffer multipartWriter := multipart.NewWriter(&requestBody) // 添加表单字段 multipartWriter.WriteField("key1", "value1") multipartWriter.WriteField("key2", "value2") contentType := multipartWriter.FormDataContentType() // 在发出请求之前关闭writer multipartWriter.Close() response, err := client.Do("http://httpbin.org/post", cycletls.Options{ Body: requestBody.String(), Headers: map[string]string{ "Content-Type": contentType, }, }, "POST") if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(response.Body) }

Golang文件上传form-data

package main import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" "bytes" "io" "log" "mime/multipart" "os" ) func main() { client := cycletls.Init() // 准备一个buffer来写入我们的multipart表单 var requestBody bytes.Buffer multipartWriter := multipart.NewWriter(&requestBody) // 添加一个文件 fileWriter, err := multipartWriter.CreateFormFile("fieldname", "filename") if err != nil { log.Fatal("CreateFormFile错误: ", err) } // 打开你想上传的文件 file, err := os.Open("path/to/your/file") if err != nil { log.Fatal("文件打开错误: ", err) } defer file.Close() // 将文件复制到multipart writer _, err = io.Copy(fileWriter, file) if err != nil { log.Fatal("文件复制错误: ", err) } // 在发出请求之前关闭writer contentType := multipartWriter.FormDataContentType() multipartWriter.Close() response, err := client.Do("http://httpbin.org/post", cycletls.Options{ Body: requestBody.String(), Headers: map[string]string{ "Content-Type": contentType, }, }, "POST") if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(response.Body) }

如果需要,可以为golang添加编码辅助函数到仓库中

如何发送application/x-www-form-urlencoded POST请求

Javascript application/x-www-form-urlencoded 表单

const initCycleTLS = require("cycletls"); (async () => { const cycleTLS = await initCycleTLS(); const urlEncodedData = new URLSearchParams(); urlEncodedData.append('key1', 'value1'); urlEncodedData.append('key2', 'value2'); const response = await cycleTLS('http://httpbin.org/post', { body: urlEncodedData, headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, }, 'post'); console.log(response); cycleTLS.exit(); })();

Golang application/x-www-form-urlencoded 表单

package main import ( "log" "net/url" "github.com/Danny-Dasilva/CycleTLS/cycletls" ) func main() { client := cycletls.Init() // 准备表单数据 form := url.Values{} form.Add("key1", "value1") form.Add("key2", "value2") response, err := client.Do("http://httpbin.org/post", cycletls.Options{ Body: form.Encode(), Headers: map[string]string{ "Content-Type": "application/x-www-form-urlencoded", }, }, "POST") if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(response.Body) }
</details>

如何下载图片?

<details>

具有以下类型的 Content-Type 头的图片会被 base64 编码。

支持的图片类型

  • image/svg+xml
  • image/webp
  • image/jpeg
  • image/png
  • application/pdf

要将它们写入文件,你可以使用以下方法

Javascript 将图片写入文件

const initCycleTLS = require("cycletls"); var fs = require("fs"); // 将图片写入文件的函数 const writeImage = (filename, data) => { let writeStream = fs.createWriteStream(filename); // 以 base64 编码写入一些数据 writeStream.write(data, "base64"); writeStream.on("finish", () => { console.log(`写入文件 ${filename}`); }); // 关闭流 writeStream.end(); }; (async () => { const cycleTLS = await initCycleTLS(); // try { const jpegImage = await cycleTLS("http://httpbin.org/image/jpeg", { ja3: "771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0", userAgent: "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0", }); // 写入图片 writeImage("test.jpeg", jpegImage.body); cycleTLS.exit(); })();

Golang 将图片写入文件

package main import ( "encoding/base64" "os" "github.com/Danny-Dasilva/CycleTLS/cycletls" ) func main() { client := cycletls.Init() response, err := client.Do("http://httpbin.org/image/jpeg", cycletls.Options{ Body: "", Ja3: "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0", UserAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36", }, "GET") // 解码 Base64 dec, err := base64.StdEncoding.DecodeString(response.Body) if err != nil { panic(err) } // 创建文件以写入 f, err := os.Create("test.jpeg") if err != nil { panic(err) } defer f.Close() // 将 b64 写入文件 if _, err := f.Write(dec); err != nil { panic(err) } if err := f.Sync(); err != nil { panic(err) } }

计划增加对其他文件类型的支持。

欢迎通过提交Issue来请求支持特定文件类型。

</details>

如何设置/强制使用 HTTP1

<details>

在 golang 中,在 Options 中设置 ForceHTTP1

package main import ( "github.com/Danny-Dasilva/CycleTLS/cycletls" "log" ) func main() { client := cycletls.Init() response, err := client.Do("https://tls.peet.ws/api/all", cycletls.Options{ ForceHTTP1: true, }, "GET") if err != nil { log.Print("请求失败: " + err.Error()) } log.Println(response.Body,) //你可以在响应中验证 HTTP_Version }

在 JS/TS 中,在 Options 中设置 forceHTTP1

const initCycleTLS = require('cycletls'); // Typescript: import initCycleTLS from 'cycletls'; (async () => { const cycleTLS = await initCycleTLS(); const response = await cycleTLS('https://ja3er.com/json', { body: '', ja3: '771,4865-4867-4866-49195-49199-52393-52392-49196-49200-49162-49161-49171-49172-51-57-47-53-10,0-23-65281-10-11-35-16-5-51-43-13-45-28-21,29-23-24-25-256-257,0', userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0', forceHTTP1: false, //设置此字段 }); console.log(response); //你可以在响应中验证 HTTP_Version cycleTLS.exit(); })();
</details>

交叉编译适用于其他平台

<details>

原生支持的三种操作系统类型 linuxdarwinwindows 应该涵盖了大多数使用场景。

你可以使用内置的 Golang 交叉编译命令 go build 来为其他操作系统编译。

例如,对于 linux arm,你需要传入 GOOSGOARCH 参数

$ GOOS=linux GOARCH=arm go build -o ./dist/index ./golang && chmod +x ./dist/index

使用上述命令,你只需运行 ./index,CycleTLS 就应该按预期运行。

使用这个 gist 查看支持交叉编译的不同操作系统,如果你有特定操作系统的使用需求,欢迎通过提交 Issue 来请求新功能。

</details>

许可证

GPL3 许可证概要

总结 GPL3许可证的主要内容如下:

1. 任何人都可以复制、修改和分发此软件。 2. 每次分发时必须包含许可证和版权声明。 3. 您可以私下使用此软件。 4. 您可以将此软件用于商业目的。 5. 分发软件时必须提供源代码。 6. 对此代码库的任何修改必须以相同的许可证(GPLv3)分发。 7. 此软件不提供任何保证。 8. 软件作者或许可方不对软件造成的任何损害承担责任。

有关许可证的更多信息可以在这里找到

编辑推荐精选

Trae

Trae

字节跳动发布的AI编程神器IDE

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

咔片PPT

咔片PPT

AI助力,做PPT更简单!

咔片是一款轻量化在线演示设计工具,借助 AI 技术,实现从内容生成到智能设计的一站式 PPT 制作服务。支持多种文档格式导入生成 PPT,提供海量模板、智能美化、素材替换等功能,适用于销售、教师、学生等各类人群,能高效制作出高品质 PPT,满足不同场景演示需求。

讯飞绘文

讯飞绘文

选题、配图、成文,一站式创作,让内容运营更高效

讯飞绘文,一个AI集成平台,支持写作、选题、配图、排版和发布。高效生成适用于各类媒体的定制内容,加速品牌传播,提升内容营销效果。

热门AI辅助写作AI工具讯飞绘文内容运营AI创作个性化文章多平台分发AI助手
材料星

材料星

专业的AI公文写作平台,公文写作神器

AI 材料星,专业的 AI 公文写作辅助平台,为体制内工作人员提供高效的公文写作解决方案。拥有海量公文文库、9 大核心 AI 功能,支持 30 + 文稿类型生成,助力快速完成领导讲话、工作总结、述职报告等材料,提升办公效率,是体制打工人的得力写作神器。

openai-agents-python

openai-agents-python

OpenAI Agents SDK,助力开发者便捷使用 OpenAI 相关功能。

openai-agents-python 是 OpenAI 推出的一款强大 Python SDK,它为开发者提供了与 OpenAI 模型交互的高效工具,支持工具调用、结果处理、追踪等功能,涵盖多种应用场景,如研究助手、财务研究等,能显著提升开发效率,让开发者更轻松地利用 OpenAI 的技术优势。

下拉加载更多