{"id":37119002,"url":"https://github.com/pixelbender/cycletls","last_synced_at":"2026-01-14T13:53:29.242Z","repository":{"id":180947312,"uuid":"665952393","full_name":"pixelbender/CycleTLS","owner":"pixelbender","description":"Spoof TLS/JA3 fingerprints in GO and Javascript ","archived":false,"fork":true,"pushed_at":"2023-07-13T12:08:46.000Z","size":32423,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2023-09-05T03:03:39.869Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"Danny-Dasilva/CycleTLS","license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pixelbender.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-07-13T11:17:27.000Z","updated_at":"2023-07-13T11:48:21.000Z","dependencies_parsed_at":"2023-07-13T12:47:03.679Z","dependency_job_id":null,"html_url":"https://github.com/pixelbender/CycleTLS","commit_stats":null,"previous_names":["pixelbender/cycletls"],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/pixelbender/CycleTLS","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelbender%2FCycleTLS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelbender%2FCycleTLS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelbender%2FCycleTLS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelbender%2FCycleTLS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pixelbender","download_url":"https://codeload.github.com/pixelbender/CycleTLS/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelbender%2FCycleTLS/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28422364,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T13:30:50.153Z","status":"ssl_error","status_checked_at":"2026-01-14T13:29:08.907Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T13:53:28.313Z","updated_at":"2026-01-14T13:53:29.233Z","avatar_url":"https://github.com/pixelbender.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# CycleTLS\n\n\n\n\u003cdiv align=\"center\"\u003e\n\t\u003cimg src=\"docs/media/Banner.svg\" alt=\"CycleTLS\"/\u003e\n\t\u003cbr\u003e\n\t\nCurrently a WIP and in Active development. See the ![Projects](https://github.com/pixelbender/CycleTLS/projects/1) Tab for more info\n\n\t\n\t\n\n![build](https://github.com/pixelbender/CycleTLS/actions/workflows/test_golang.yml/badge.svg)\n[![GoDoc](http://img.shields.io/badge/go-documentation-blue.svg)](http://godoc.org/github.com/pixelbender/CycleTLS/cycletls) \n[![license](https://img.shields.io/github/license/pixelbender/CycleTLS.svg)](https://github.com/pixelbender/CycleTLS/blob/main/LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/pixelbender/CycleTLS/cycletls)](https://goreportcard.com/report/github.com/pixelbender/CycleTLS/cycletls)\n[![npm version](https://img.shields.io/npm/v/cycletls.svg)](https://www.npmjs.org/package/cycletls)\n\u003c/div\u003e\n\nIf you have a API change or feature request feel free to open an [Issue](https://github.com/pixelbender/CycleTLS/issues/new/choose)\n\n\n\n# 🚀 Features\n\n- [High-performance](#-performance) Built-in goroutine pool used for handling asynchronous requests\n- Custom header ordering via [fhttp](https://github.com/useflyent/fhttp)\n- Proxy support\n- Ja3 Token configuration\n\n\nTable of contents\n=================\n\n\n* [Table of contents](#table-of-contents)\n* [Installation](#installation)\n* [Usage](#usage)\n\t* [QuickStart JS](#example-cycletls-request-for-typescript-and-javascript)\n\t* [Quickstart Golang](#example-cycletls-request-for-golang)\n\t* [Initializing CycleTLS](#creating-an-instance)\n\t* [API/Methods](#cycletls-alias-methods)\n\t* [Request Config](#cycletls-request-config)\n\t* [Response Schema](#cycletls-response-schema)\n\t* [Multiple Requests Example](#multiple-requests-example-for-typescript-and-javascript)\n* [Local Setup](#dev-setup)\n* [QA](#questions)\n* [LICENSE](#license)\n\n## Dependencies\n\n```\nnode ^v14.0\ngolang ^v1.16x\n```\n\n## Installation\n\nNode Js\n\n```bash\n$ npm install cycletls\n```\n\nGolang\n\n```bash\n$ go get github.com/pixelbender/CycleTLS/cycletls \n```\n\n# Usage \n\n## Example CycleTLS Request for Typescript and Javascript\n\nYou can run this test in `tests/simple.test.ts`\n\n```js\n\nconst initCycleTLS = require('cycletls');\n// Typescript: import initCycleTLS from 'cycletls';\n\n(async () =\u003e {\n  // Initiate CycleTLS\n  const cycleTLS = await initCycleTLS();\n\n  // Send request\n  const response = await cycleTLS('https://ja3er.com/json', {\n    body: '',\n    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',\n    userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0',\n    proxy: 'http://username:password@hostname.com:443'\n  }, 'get');\n\n  console.log(response);\n\n  // Cleanly exit CycleTLS\n  cycleTLS.exit();\n\n})();\n\n```\n\n## Example CycleTLS Request for Golang\n\n```go\npackage main\n\nimport (\n\t\"log\"\n\n\t\"github.com/pixelbender/CycleTLS/cycletls\"\n)\n\nfunc main() {\n\n\tclient := cycletls.Init()\n\n\tresponse, err := client.Do(\"https://ja3er.com/json\", cycletls.Options{\n\t\tBody : \"\",\n\t\tJa3: \"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\",\n\t\tUserAgent: \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0\",\n\t  }, \"GET\");\n\tif err != nil {\n\t\tlog.Print(\"Request Failed: \" + err.Error())\n\t}\n\tlog.Println(response)\n}\n\n```\n\n## Creating an instance\n\nIn order to create a `cycleTLS` instance, you can run the following:\n\n#### JavaScript\n\n```js\n// The initCycleTLS function spawns a Golang process that handles all requests concurrently via goroutine loops. \nconst initCycleTLS = require('cycletls');\n// import initCycleTLS from 'cycletls';\n\n// Async/Await method\nconst cycleTLS = await initCycleTLS();\n// .then method\ninitCycleTLS().then((cycleTLS) =\u003e {});\n\n```\n#### Golang\n\n```go\nimport (\n\t\"github.com/pixelbender/CycleTLS/cycletls\"\n)\n\n//The `Init` function initializes golang channels to process requests. \nclient := cycletls.Init()\n```\n\n\n## CycleTLS Alias Methods\n\nThe following methods exist in CycleTLS\n\n**cycleTLS(url, [config])**\n\n**cycleTLS.get(url, [config])**\n\n**cycleTLS.delete(url, [config])**\n\n**cycleTLS.head(url, [config])**\n\n**cycleTLS.options(url, [config])**\n\n**cycleTLS.post(url, [config])**\n\n**cycleTLS.put(url, config)**\n\n**cycleTLS.patch(url, [config])**\n\nUrl is not optional, config is optional\n\n## CycleTLS Request Config\n\n```js\n{\n  // URL for the request (required if not specified as an argument)\n  url: \"https://example.com\"\n  // Method for the request (\"head\" | \"get\" | \"post\" | \"put\" | \"delete\" | \"trace\" | \"options\" | \"connect\" | \"patch\")\n  method: \"get\" // Default method\n  // Custom headers to send\n  headers: { \"Authorization\": \"Bearer someexampletoken\" }\n  // Custom cookies to send\n  Cookies: [{\n    \"name\": \"key\",\n    \"value\": \"val\",\n    \"path\":  \"/docs\",\n    \"domain\":  \"google.com\",\n                \"expires\": \"Mon, 02-Jan-2022 15:04:05 EST\"\n    \"maxAge\": 90,\n    \"secure\": false,\n    \"httpOnly\": true,\n    \"sameSite\": \"Lax\"\t\t\n  }],\n  // Body to send with request (must be a string - cannot pass an object)\n  body: '',\n  // JA3 token to send with request\n  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',\n  // User agent for request\n  userAgent: 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0',\n  // Proxy to send request through (must be in the same format)\n  proxy: 'http://username:password@hostname.com:443',\n  // Amount of seconds before request timeout (default: 7)\n  timeout: 2,\n  // Toggle if CycleTLS should follow redirects\n  disableRedirect: true\n  // Custom header order to send with request (This value will overwrite default header order)\n  headerOrder: [\"cache-control\", \"connection\", \"host\"]\n}\n);\n\n```\n\n## CycleTLS Response Schema\n\n```js\n{\n  // Status code returned from server (Number)\n  status: 200,\n  // Body returned from the server (String)\n  body: \"\",\n  // Headers returned from the server (Object)\n  headers: {\n    \"some\": \"header\",\n    ...\n  }\n}\n);\n\n```\n\n\n\n## Multiple Requests Example for Typescript and Javascript\n\nIf CycleTLS is being used by in a JavaScript environment, CycleTLS will spawn a Golang process to handle requests. This Golang process handles requests `concurrently` in a worker pool. Due to this, CycleTLS returns response objects as soon as they are made available \n(in other terms, CycleTLS processes requests as they are received, but responses are returned asynchronously so they will NOT be returned in the order requested)\n\nIf you are using CycleTLS in JavaScript, it is necessary to exit out of the instance to prevent zombie processes. The example below shows one way to approach cleanly exiting CycleTLS if you need to process multiple requests (note: keep in mind that calling the `exit()` function will kill any requests in progress). If your workflow requires requests running the entire time the process runs, modules such as [exit-hook](https://www.npmjs.com/package/exit-hook) could serve as an alternative solution to cleanly exiting CycleTLS.\n\n```js\nconst initCycleTLS = require(\"cycletls\");\n// Typescript: import initCycleTLS from 'cycletls';\n\n// Defining custom JA3 token and user agenton multiple requests,\n  \"https://httpbin.org/user-agent\": {\n    ja3: ja3,\n    userAgent: userAgent,\n  },\n  \"http://httpbin.org/post\": {\n    body: '{\"field\":\"POST-VAL\"}',\n    method: \"POST\",\n  },\n  \"http://httpbin.org/cookies\": {\n    cookies: [\n      {\n        name: \"example1\",\n        value: \"aaaaaaa\",\n        expires: \"Mon, 02-Jan-2022 15:04:05 EST\",\n      },\n    ],\n  },\n};\n\n// Promises array of requests\nconst promises = [];\n\n// Anonymous async function\n(async () =\u003e {\n  // Initiate CycleTLS\n  const cycleTLS = await initCycleTLS();\n\n  // Loop through requestDict (Object) defined above\n  for (const url in requestDict) {\n    // Fetch configs from requestDict (Object)\n    const params = requestDict[url];\n\n    // Send request (note: no waiting)\n    const response = cycleTLS(\n      url, {\n        body: params.body ?? \"\", //?? is just setting defaults in this case\n        ja3: params.ja3 ?? ja3,\n        userAgent: params.userAgent ?? userAgent,\n        headers: params.headers,\n        cookies: params.cookies,\n      }, params.method ?? \"GET\");\n\n    // console.log the response object\n    response.then((out) =\u003e {\n      console.log(url, out);\n    });\n\n    // Push request to promise array\n    promises.push(response);\n  }\n\n  // Wait for all requests to execute successfully\n  Promise.all(promises).then(() =\u003e {\n    // Cleanly exit CycleTLS one all requests have been received\n    cycleTLS.exit();\n  });\n})();\n```\n\n\n\n# Dev Setup\n\nIf you would like to compile CycleTLS on your own, use the following commands:\n\nSet module-aware mode\n\n`go env -w  GO111MODULE=off`\n\nInstall golang dependencies\n\n`go get github.com/pixelbender/CycleTLS/cycletls`\n\ninstall npm packages\n\n`npm install`\n\n### To recompile index.ts in the src folder\n\n`npm run build`\n\n### To recompile Golang files in the golang folder\nWindows\n\n`npm run build:windows`\n\nLinux\n\n`npm run build:linux`\n\nMac\n\n`npm run build:mac:`\n\n## Questions\n\n### How do I set Cookies\n\u003cdetails\u003e\n\nThere are two simple ways to interface with cookies \n### Javascript Simple Cookie Configuration\n\n```js\nconst initCycleTLS = require(\"cycletls\");\n(async () =\u003e {\n  // Initiate cycleTLS\n  const cycleTLS = await initCycleTLS();\n  const response = await cycleTLS(\"https://httpbin.org/cookies\", {\n    cookies: {\n      cookie1: \"value1\",\n      cookie2: \"value2\",\n    },\n  });\n  console.log(response.body);\n  /* Expected\n  {\n    \"cookies\": {\n      \"cookie1\": \"value1\",\n      \"cookie2\": \"value2\"\n    }\n  }\n  */\n  cycleTLS.exit();\n})();\n```\n\nIn this simple example you can set the cookie `name` and `value` within an object\n\n\n### Javascript Complex Cookie Configuration\n\nIf you wish to have more fine grained control over cookie parameters you have access to the full underlying Go struct\n\nhere are the following values you can set\n\n```ts\nexport interface Cookie {\n  name: string;\n  value: string;\n  path?: string;\n  domain?: string;\n  expires?: string;\n  rawExpires?: string;\n  maxAge?: number;\n  secure?: boolean;\n  httpOnly?: boolean;\n  sameSite?: string;\n  unparsed?: string;\n}\n```\n\nyou can use them in a request as follows\n\n```js\nconst initCycleTLS = require(\"cycletls\");\n(async () =\u003e {\n  // Initiate cycleTLS\n  const cycleTLS = await initCycleTLS();\n  const complexCookies = [\n    {\n      name: \"cookie1\",\n      value: \"value1\",\n      domain: \"httpbin.org\",\n    },\n    {\n      name: \"cookie2\",\n      value: \"value2\",\n      domain: \"httpbin.org\",\n    },\n  ];\n\n  const response = await cycleTLS(\"https://httpbin.org/cookies\", {\n    cookies: complexCookies,\n  });\n\n  console.log(response.body);\n  /* Expected\n  {\n    \"cookies\": {\n      \"cookie1\": \"value1\",\n      \"cookie2\": \"value2\"\n    }\n  }\n  */\n  cycleTLS.exit();\n})();\n```\n\n\n### Golang Configure Cookies\n```golang\npackage main\n\nimport (\n    \"github.com/pixelbender/CycleTLS/cycletls\"\n)\n\nfunc main() {\n    resp, err := client.Do(\"https://httpbin.org/cookies\", cycletls.Options{\n\t\tBody:      \"\",\n\t\tJa3:       \"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\",\n\t\tUserAgent: \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0\",\n\t\tCookies: []cycletls.Cookie{{Name: \"cookie1\", Value: \"value1\"},\n\t\t\t{Name: \"cookie2\", Value: \"value2\"}},\n    }, \"GET\")\n    if err != nil {\n      log.Print(\"Request Failed: \" + err.Error())\n    }\n    log.Println(resp.Body)\n    /* Expected\n    {\n      \"cookies\": {\n        \"cookie1\": \"value1\", \n        \"cookie2\": \"value2\"\n      }\n      }\n    */\n    \n    //Altenatively if you want access to values within a map\n    log.Println(resp.JSONBody())\n    /* Expected\n    map[cookies:map[cookie1:value1 cookie2:value2]]\n    */\n}\n\n```\n\n\nFeel free to open an [Issue](https://github.com/pixelbender/CycleTLS/issues/new/choose) with a feature request for specific file type support. \n\u003c/details\u003e\n\n\n### How do I use CookieJar in CycleTLS?\n\n\u003cdetails\u003e\n\n```js\nconst initCycleTLS = require(\"cycletls\");\n\nconst tough = require(\"tough-cookie\");\nconst Cookie = tough.Cookie;\n\n(async () =\u003e {\n  // Initiate cycleTLS and CookieJar\n  const cycleTLS = await initCycleTLS();\n  const cookieJar = new tough.CookieJar();\n\n  // Capture a set cookie\n  const firstResponse = await cycleTLS.get(\n    \"https://httpbin.org/cookies/set?freeform=test\",\n    {\n      disableRedirect: true,\n    }\n  );\n  \n  // Now use the processCookies function to add the cookies from the response headers to the cookie jar\n  await processCookies(\n    firstResponse,\n    \"https://httpbin.org/cookies/set?freeform=test\",\n    cookieJar\n  );\n  // Now send a second to verify we have our cookies\n  const secondResponse = await cycleTLS.get(\"https://httpbin.org/cookies\", {\n    headers: {\n      cookie: await cookieJar.getCookieString(\"https://httpbin.org/cookies\"),\n    },\n  });\n  \n  //verify cookies were set\n  console.log(secondResponse.body)\n  /* Expected\n  {\n    \"cookies\": {\n      \"freeform\": \"test\"\n    }\n  }\n  */\n  cycleTLS.exit();\n})();\n\nasync function processCookies(response, url, cookieJar) {\n  if (response.headers[\"Set-Cookie\"] instanceof Array) {\n    response.headers[\"Set-Cookie\"].map(\n      async (cookieString) =\u003e await cookieJar.setCookie(cookieString, url)\n    );\n  } else {\n    await cookieJar.setCookie(response.headers[\"Set-Cookie\"], url);\n  }\n}\n```\n\n\n**Golang example coming soon** \n\n\u003c/details\u003e\n\n\n### How do I download images?\n\n\u003cdetails\u003e\n\nImages with a `Content-Type` header of the following types are base 64 encoded. \n\n**Supported Image Types**\n* `image/svg+xml`\n* `image/webp`\n* `image/jpeg`\n* `image/png`\n* `application/pdf`\n\nTo write them to a file you can use the below methods\n\n### Javascript Image Write to File\n```js\nconst initCycleTLS = require(\"cycletls\");\nvar fs = require(\"fs\");\n\n//Function to write image to a file\nconst writeImage = (filename, data) =\u003e {\n  let writeStream = fs.createWriteStream(filename);\n\n  // write some data with a base64 encoding\n  writeStream.write(data, \"base64\");\n  writeStream.on(\"finish\", () =\u003e {\n    console.log(`wrote to file ${filename}`);\n  });\n  \n  // close the stream\n  writeStream.end();\n};\n\n(async () =\u003e {\n  const cycleTLS = await initCycleTLS();\n  // try {\n\n  const jpegImage = await cycleTLS(\"http://httpbin.org/image/jpeg\", {\n    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\",\n    userAgent:\n      \"Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:87.0) Gecko/20100101 Firefox/87.0\",\n  });\n  //Write Image\n  writeImage(\"test.jpeg\", jpegImage.body);\n\n  cycleTLS.exit();\n})();\n\n```\n### Golang Image Write to File\n```golang\npackage main\n\nimport (\n    \"encoding/base64\"\n    \"os\"\n    \"github.com/pixelbender/CycleTLS/cycletls\"\n)\n\nfunc main() {\n\n    client := cycletls.Init()\n    response, err := client.Do(\"http://httpbin.org/image/jpeg\", cycletls.Options{\n      Body:      \"\",\n      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\",\n      UserAgent: \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.106 Safari/537.36\",\n    }, \"GET\")\n    // Decode Base64\n    dec, err := base64.StdEncoding.DecodeString(response.Body)\n    if err != nil {\n        panic(err)\n    }\n    //create file to write\n    f, err := os.Create(\"test.jpeg\")\n    if err != nil {\n        panic(err)\n    }\n    defer f.Close()\n    //write b64 to file\n    if _, err := f.Write(dec); err != nil {\n        panic(err)\n    }\n    if err := f.Sync(); err != nil {\n        panic(err)\n    }\n}\n\n```\n\n\nAdditional file type support is planned.\n\nFeel free to open an [Issue](https://github.com/pixelbender/CycleTLS/issues/new/choose) with a feature request for specific file type support. \n\u003c/details\u003e\n\n### Cross Compiling for other platforms\n\u003cdetails\u003e\n\nNatively the 3 Operating System types `linux`, `darwin` , `windows`  should cover most use cases.\n\t\nYou can use the built in Golang cross compiling commands `go build` to compile for another operating system. \n\nAs an example for linux arm you need to pass in the `GOOS` and `GOARCH` arguments\n\n```bash\n$ GOOS=linux GOARCH=arm go build -o ./dist/index ./golang \u0026\u0026 chmod +x ./dist/index\n```\n\nWith the above command you can simply run `./index` and CycleTLS should function as intended.\n\nUse this [gist](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63) for different Operating Systems that support cross-compilation and feel free to open an [Issue](https://github.com/pixelbender/CycleTLS/issues/new/choose) with a feature request for your specific operating system use case. \n\n\u003c/details\u003e\n\n## LICENSE\n### GPL3 LICENSE SYNOPSIS\n\n**_TL;DR_*** Here's what the GPL3 license entails:\n\n```markdown\n1. Anyone can copy, modify and distribute this software.\n2. You have to include the license and copyright notice with each and every distribution.\n3. You can use this software privately.\n4. You can use this software for commercial purposes.\n5. Source code MUST be made available when the software is distributed.\n6. Any modifications of this code base MUST be distributed with the same license, GPLv3.\n7. This software is provided without warranty.\n8. The software author or license can not be held liable for any damages inflicted by the software.\n```\n\nMore information on about the [LICENSE can be found here](http://choosealicense.com/licenses/gpl-3.0/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelbender%2Fcycletls","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpixelbender%2Fcycletls","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelbender%2Fcycletls/lists"}