# Table of Contents - [TLS-Client | Open Source Oasis](#tls-client-open-source-oasis) - [Supported and tested Client Profiles | Open Source Oasis](#supported-and-tested-client-profiles-open-source-oasis) - [Installation & Quick Usage | Open Source Oasis](#installation-quick-usage-open-source-oasis) - [Cookiejar | Open Source Oasis](#cookiejar-open-source-oasis) - [Client Options | Open Source Oasis](#client-options-open-source-oasis) - [Request Headers | Open Source Oasis](#request-headers-open-source-oasis) - [Defaults | Open Source Oasis](#defaults-open-source-oasis) - [Pseudo Header Order | Open Source Oasis](#pseudo-header-order-open-source-oasis) - [Response Body Encoding / Decoding | Open Source Oasis](#response-body-encoding-decoding-open-source-oasis) - [Certificate Pinning | Open Source Oasis](#certificate-pinning-open-source-oasis) - [Custom Client Profile | Open Source Oasis](#custom-client-profile-open-source-oasis) - [Examples | Open Source Oasis](#examples-open-source-oasis) - [Shared Library | Open Source Oasis](#shared-library-open-source-oasis) - [Node Version | Open Source Oasis](#node-version-open-source-oasis) - [Downloads | Open Source Oasis](#downloads-open-source-oasis) - [Protocol Racing | Open Source Oasis](#protocol-racing-open-source-oasis) - [WebSocket | Open Source Oasis](#websocket-open-source-oasis) - [Build from source | Open Source Oasis](#build-from-source-open-source-oasis) - [Proxies | Open Source Oasis](#proxies-open-source-oasis) - [Exposed Methods | Open Source Oasis](#exposed-methods-open-source-oasis) - [JavaScript | Open Source Oasis](#javascript-open-source-oasis) - [Examples | Open Source Oasis](#examples-open-source-oasis) - [Python | Open Source Oasis](#python-open-source-oasis) - [TypeScript | Open Source Oasis](#typescript-open-source-oasis) - [Examples | Open Source Oasis](#examples-open-source-oasis) - [Examples | Open Source Oasis](#examples-open-source-oasis) - [C# | Open Source Oasis](#c-open-source-oasis) - [Examples | Open Source Oasis](#examples-open-source-oasis) - [Defaults | Open Source Oasis](#defaults-open-source-oasis) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Memory Issues | Open Source Oasis](#memory-issues-open-source-oasis) - [Standalone API Application | Open Source Oasis](#standalone-api-application-open-source-oasis) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Antibots & Captchas | Open Source Oasis](#antibots-captchas-open-source-oasis) - [Download | Open Source Oasis](#download-open-source-oasis) - [Build from source | Open Source Oasis](#build-from-source-open-source-oasis) - [Configuration & Start | Open Source Oasis](#configuration-start-open-source-oasis) - [Response | Open Source Oasis](#response-open-source-oasis) - [Payload | Open Source Oasis](#payload-open-source-oasis) - [Endpoints | Open Source Oasis](#endpoints-open-source-oasis) - [Defaults | Open Source Oasis](#defaults-open-source-oasis) - [Attention | Open Source Oasis](#attention-open-source-oasis) - [How to get support | Open Source Oasis](#how-to-get-support-open-source-oasis) - [Payload | Open Source Oasis](#payload-open-source-oasis) - [Response | Open Source Oasis](#response-open-source-oasis) - [Further Information | Open Source Oasis](#further-information-open-source-oasis) - [Proxies | Open Source Oasis](#proxies-open-source-oasis) - [Community Projects | Open Source Oasis](#community-projects-open-source-oasis) - [Contributing | Open Source Oasis](#contributing-open-source-oasis) - [Frequently Asked Questions / Errors | Open Source Oasis](#frequently-asked-questions-errors-open-source-oasis) - [Community Support | Open Source Oasis](#community-support-open-source-oasis) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) - [Unknown](#unknown) --- # TLS-Client | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme.md) . Preface[](https://bogdanfinn.gitbook.io/open-source-oasis#preface) ------------------------------------------------------------------- This TLS Client is built upon [https://github.com/Carcraftz/fhttp](https://github.com/Carcraftz/fhttp) and [https://github.com/Carcraftz/utls](https://github.com/Carcraftz/utls) as well as [https://github.com/refraction-networking/utls](https://github.com/refraction-networking/utls) . Big thanks to all contributors so far. Sadly it seems that the original repositories are not maintained anymore and the original \`utls\` repository is not enough without custom modifications. What is TLS Fingerprinting?[](https://bogdanfinn.gitbook.io/open-source-oasis#what-is-tls-fingerprinting) ---------------------------------------------------------------------------------------------------------- Some people think it is enough to change the user-agent header of a request to let the server think that the client requesting a resource is a specific browser. Nowadays this is not enough, because the server might use a technique to detect the client browser which is called TLS Fingerprinting. Even tho this article is about TLS Fingerprinting in NodeJS it well describes the technique in detail: [https://httptoolkit.tech/blog/tls-fingerprinting-node-js/#how-does-tls-fingerprinting-work](https://httptoolkit.tech/blog/tls-fingerprinting-node-js/#how-does-tls-fingerprinting-work) Why is this library needed?[](https://bogdanfinn.gitbook.io/open-source-oasis#why-is-this-library-needed) ---------------------------------------------------------------------------------------------------------- With this library you are able to create a http client implementing an interface which is similar to golangs net/http client interface. This TLS Client allows you to specify the client profile (Browser) you want to use, when requesting a server. The interface of the HTTP Client looks like the following and extends the base net/http Client interface by some useful functions. Most likely you will use the `Do()` function like you did before with golangs net/http Client. Copy type HttpClient interface { GetCookies(u *url.URL) []*http.Cookie SetCookies(u *url.URL, cookies []*http.Cookie) SetCookieJar(jar http.CookieJar) GetCookieJar() http.CookieJar SetProxy(proxyUrl string) error GetProxy() string SetFollowRedirect(followRedirect bool) GetFollowRedirect() bool CloseIdleConnections() Do(req *http.Request) (*http.Response, error) Get(url string) (resp *http.Response, err error) Head(url string) (resp *http.Response, err error) Post(url, contentType string, body io.Reader) (resp *http.Response, err error) GetBandwidthTracker() bandwidth.BandwidthTracker GetDialer() proxy.ContextDialer GetTLSDialer() TLSDialerFunc } The methods should be more or less self explanatory. [NextSupported and tested Client Profiles](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles) Last updated 7 months ago * [Preface](https://bogdanfinn.gitbook.io/open-source-oasis#preface) * [What is TLS Fingerprinting?](https://bogdanfinn.gitbook.io/open-source-oasis#what-is-tls-fingerprinting) * [Why is this library needed?](https://bogdanfinn.gitbook.io/open-source-oasis#why-is-this-library-needed) --- # Supported and tested Client Profiles | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles.md) . ### Internal Client Profiles[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles#internal-client-profiles) The internal client profiles were created and tested by myself. Of course that does not mean they are 100% correct. But i tested them more precise then the contributed profiles. 1. Chrome * 103 (chrome\_103) * 104 (chrome\_104) * 105 (chrome\_105) * 106 (chrome\_106) * 107 (chrome\_107) * 108 (chrome\_108) * 109 (chrome\_109) * 110 (chrome\_110) * 111 (chrome\_111) * 112 (chrome\_112) * 116 with PSK (chrome\_116\_PSK) * 116 with PSK and PQ (chrome\_116\_PSK\_PQ) * 117 (chrome\_117) * 120 (chrome\_120) * 124 (chrome\_124) * 133 (chrome\_133) * 133 with PSK (chrome\_133\_PSK) * 144 (chrome\_144) * 144 with PSK (chrome\_144\_PSK) * 146 (chrome\_146) * 146 with PSK (chrome\_146\_PSK) * 150 (chrome\_150) * 150 with PSK (chrome\_150\_PSK) * 152 (chrome\_152) * 152 with PSK (chrome\_152\_PSK) 2. Brave * 146 (brave\_146) * 146 with PSK (brave\_146\_PSK) 3. Safari * 15.6.1 (safari\_15\_6\_1) * 16.0 (safari\_16\_0) 4. iOS (Safari) * 15.5 (safari\_ios\_15\_5) * 15.6 (safari\_ios\_15\_6) * 16.0 (safari\_ios\_16\_0) * 17.0 (safari\_ios\_17\_0) * 18.0 (safari\_ios\_18\_0) * 18.5 (safari\_ios\_18\_5) * 26.0 (safari\_ios\_26\_0) 5. iPadOS (Safari) * 15.6 (safari\_ipad\_15\_6) 6. Firefox * 102 (firefox\_102) * 104 (firefox\_104) * 105 (firefox\_105) * 106 (firefox\_106) * 108 (firefox\_108) * 110 (firefox\_110) * 117 (firefox\_117) 7. Opera * 89 (opera\_89) * 90 (opera\_90) * 91 (opera\_91) 8. Custom Clients * Zalando iOS Mobile (zalando\_ios\_mobile) * Nike IOS Mobile (nike\_ios\_mobile) * Cloudscraper * MMS IOS (mms\_ios or mms\_ios\_1) * MMS IOS 2 (mms\_ios\_2) * MMS IOS 3 (mms\_ios\_3) * Mesh IOS (mesh\_ios or mesh\_ios\_1) * Confirmed IOS (confirmed\_ios) ### Contributed Client Profiles[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles#contributed-client-profiles) The contributed client profiles are contributed by people from the community. They are not precisely tested like the internal ones. Please be aware that they might have issues. 1. Chrome * 130 with PSK (chrome\_130\_PSK) * 131 (chrome\_131) * 131 with PSK (chrome\_131\_PSK) 2. OkHttp4 * Android 7 (okhttp4\_android\_7) * Android 8 (okhttp4\_android\_8) * Android 9 (okhttp4\_android\_9) * Android 10 (okhttp4\_android\_10) * Android 11 (okhttp4\_android\_11) * Android 12 (okhttp4\_android\_12) * Android 13 (okhttp4\_android\_13) 3. Custom Clients * Zalando Android Mobile (zalando\_android\_mobile) * Nike Android Mobile (nike\_android\_mobile) * Mesh IOS 2 (mesh\_ios\_2) * Mesh Android (mesh\_android or mesh\_android\_1) * Mesh Android 2 (mesh\_android\_2) * Confirmed Android (confirmed\_android) 4. Firefox * 120 (firefox\_120) * 123 (firefox\_123) * 132 (firefox\_132) * 133 (firefox\_133) * 135 (firefox\_135) * 146 with PSK (firefox\_146\_PSK) * 147 (firefox\_147) * 147 with PSK (firefox\_147\_PSK) * 148 (firefox\_148) You can also provide your own client. See the examples how to do that. All Clients support Random TLS Extension Order by setting the option on the HTTP client itself `WithRandomTLSExtensionOrder()`. This is needed for Chrome 107+. #### Shared Library & Standalone Api[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles#shared-library-and-standalone-api) When working with the Shared Library or Standalone API you need to set `"withRandomExtensionOrder":true` [PreviousTLS-Client](https://bogdanfinn.gitbook.io/open-source-oasis) [NextInstallation & Quick Usage](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage) Last updated 2 days ago * [Internal Client Profiles](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles#internal-client-profiles) * [Contributed Client Profiles](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles#contributed-client-profiles) --- # Installation & Quick Usage | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage.md) . Installation[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage#installation) ----------------------------------------------------------------------------------------------------------------- Copy go get -u github.com/bogdanfinn/tls-client // or specific version: // go get github.com/bogdanfinn/tls-client@v1.7.2 Some users have trouble when using `go get -u`. If this is the case for you please cleanup your go.mod file and do a `go get` with a specific version like described above in the commented out code. I would recommend to check the Github tags for the latest version and install that one explicit. Quick Usage Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage#quick-usage-example) ------------------------------------------------------------------------------------------------------------------------------- Copy package main import ( "fmt" "io" "log" http "github.com/bogdanfinn/fhttp" "github.com/bogdanfinn/tls-client/profiles" tls_client "github.com/bogdanfinn/tls-client" ) func main() { jar := tls_client.NewCookieJar() options := []tls_client.HttpClientOption{ tls_client.WithTimeoutSeconds(30), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithNotFollowRedirects(), tls_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument //tls_client.WithProxyUrl("http://user:pass@host:port"), //tls_client.WithInsecureSkipVerify(), } client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) if err != nil { log.Println(err) return } req, err := http.NewRequest(http.MethodGet, "https://tls.peet.ws/api/all", nil) if err != nil { log.Println(err) return } req.Header = http.Header{ "accept": {"*/*"}, "accept-language": {"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"}, "user-agent": {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"}, http.HeaderOrderKey: { "accept", "accept-language", "user-agent", }, } resp, err := client.Do(req) if err != nil { log.Println(err) return } defer resp.Body.Close() log.Println(fmt.Sprintf("status code: %d", resp.StatusCode)) readBytes, err := io.ReadAll(resp.Body) if err != nil { log.Println(err) return } log.Println(string(readBytes)) } For more configured clients check this documentation or use your own custom client. See provided examples how to use a complete custom TLS client. [PreviousSupported and tested Client Profiles](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles) [NextClient Options](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options) Last updated 8 hours ago * [Installation](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage#installation) * [Quick Usage Example](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage#quick-usage-example) --- # Cookiejar | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar.md) . Since version 1.0.0 the TLS-Client uses the custom cookiejar implemented which can be found here: [https://github.com/bogdanfinn/tls-client/blob/master/jar.go](https://github.com/bogdanfinn/tls-client/blob/master/jar.go) Before it was more or less golangs default cookiejar: [https://github.com/bogdanfinn/fhttp/blob/master/cookiejar/jar.go](https://github.com/bogdanfinn/fhttp/blob/master/cookiejar/jar.go) The custom cookiejar is designed for some specific (sneaker)botting related use cases when it comes to cookie overwriting or sharing cookies across different TLD. Often these use cases were about overwriting exisiting cookies in the jar with newer values or something like that. When using the TLS-Client in go you can easilly switch between both jars just by instantiating the specific cookiejar you need: #### Default Go Cookiejar[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar#default-go-cookiejar) Copy jar, _ := cookiejar.New(nil) options := []tls_client.HttpClientOption{ tls_client.WithCookieJar(jar), } client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) #### Custom Cookiejar[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar#custom-cookiejar) Copy jar := tls_client.NewCookieJar() options := []tls_client.HttpClientOption{ tls_client.WithCookieJar(jar), } client, err := tls_client.NewHttpClient(logger, options...) #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar#shared-library-and-standalone-api) If you are using the shared library or standalone api you can either completely deactiavte cookie jar handling by setting `"withoutCookieJar"` to `true` or you can switch to the default Go cookiejar by setting `"withDefaultCookieJar"` to `true`. By default the Custom Cookiejar will always be used. ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar#example) A runnable version is in [`./example/cookies`](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies) . [PreviousClient Options](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options) [NextDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults) Last updated 8 hours ago --- # Client Options | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options.md) . When instantiating the TLS client you can define various options which are documented here: * WithClientProfile Copy WithClientProfile configures a TLS client to use the specified client profile. * WithForceHttp1 Copy WithForceHttp1 configures a client to force HTTP/1.1 as the used protocol. * WithDisableHttp3 Copy WithDisableHttp3 configures a client to disable HTTP 3 as the used protocol. Will most likely fall back to HTTP 2 * WithDisableSessionTickets Copy WithDisableSessionTickets configures a client to disable TLS session ticket caching and resumption. Session resumption is only used by profiles that support it (those sending a PSK extension). For those, the client keeps a session cache and can resume a TLS session instead of doing a full handshake. Disable it if you want every connection to perform a full handshake. * WithInsecureSkipVerify Copy WithInsecureSkipVerify configures a client to skip SSL certificate verification. * WithTransportOptions Copy WithTransportOptions configures a client to use the specified transport options. The `TransportOptions` struct supports the following fields for client certificate authentication: Copy tls_client.WithTransportOptions(&tls_client.TransportOptions{ // Certificates is a list of client TLS certificates for mutual TLS (mTLS). // Load certificates with tls.LoadX509KeyPair or tls.X509KeyPair. Certificates: []tls.Certificate{clientCert}, }) * WithProxyUrl Copy WithProxyUrl configures a HTTP client to use the specified proxy URL. proxyUrl should be formatted as: "http://user:pass@host:port" HTTP, HTTPS, SOCKS4 and SOCKS5 proxies are supported. If you also enable `WithProtocolRacing()` the proxy has to be a `socks5://` or `socks5h://` proxy, because HTTP/3 runs over UDP and only SOCKS5 can tunnel it (via UDP ASSOCIATE). Any other scheme is rejected with an error. See [Protocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) . * WithCharlesProxy Copy WithCharlesProxy configures the HTTP client to use a local running charles as proxy. host and port can be empty, then default 127.0.0.1 and port 8888 will be used * WithCookieJar Copy WithCookieJar configures a HTTP client to use the specified cookie jar. * WithServerNameOverwrite Copy WithServerNameOverwrite configures a TLS client to overwrite the server name being used for certificate verification and in the client hello. This option does only work properly if WithInsecureSkipVerify is set to true in addition * WithTimeoutMilliseconds Copy WithTimeoutMilliseconds configures a hard deadline for the entire request lifecycle. This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data. - Use 0 to disable the deadline (unlimited) for large downloads or long-polling. - Default is 30000 milliseconds (30 seconds). * WithTimeoutSeconds Copy WithTimeoutSeconds configures a hard deadline for the entire request lifecycle. This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data. - Use 0 to disable the deadline (unlimited) for large downloads or long-polling. - Default is 30 seconds. * WithTimeout Copy WithTimeout configures an HTTP client to use the specified request timeout. timeout is the request timeout in seconds. Deprecated: use either WithTimeoutSeconds or WithTimeoutMilliseconds * WithNotFollowRedirects Copy WithNotFollowRedirects configures an HTTP client to not follow HTTP redirects. * WithCustomRedirectFunc Copy WithCustomRedirectFunc configures an HTTP client to use a custom redirect func. The redirect func have to look like that: func(req *http.Request, via []*http.Request) error Please only provide a custom redirect function if you know what you are doing. Check docs on net/http.Client CheckRedirect * WithRandomTLSExtensionOrder Copy WithRandomTLSExtensionOrder configures a TLS client to randomize the order of TLS extensions being sent in the ClientHello. Placement of GREASE and padding is fixed and will not be affected by this. * WithCertificatePinning Copy WithCertificatePinning enables SSL Pinning for the client and will throw an error if the SSL Pin is not matched. Please refer to https://github.com/tam7t/hpkp/#examples in order to see how to generate pins. The certificatePins are a map with the host as key. You can provide a BadPinHandlerFunc or nil as second argument. This function will be executed once a bad ssl pin is detected. * WithDebug Copy WithDebug configures a client to log debugging information. * WithLocalAddr Copy WithLocalAddr configures an HTTP client to use the specified local address. * WithDisableIPV4 Copy WithDisableIPV4 configures a dialer to use tcp6 network argument * WithDisableIPV6 Copy WithDisableIPV6 configures a dialer to use tcp4 network argument * WithCatchPanics Copy WithCatchPanics configures a client to catch all go panics happening during a request and not print the stacktrace. * WithDefaultHeaders Copy WithDefaultHeaders configures a client to use a set of default headers if none are specified on the request. * WithConnectHeaders Copy WithConnectHeaders configures a client to use the specified headers for the CONNECT request * WithProtocolRacing Copy WithProtocolRacing configures a client to race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel. Similar to Chrome's "Happy Eyeballs" approach, this starts both connection types simultaneously and uses whichever connects first. The client will remember which protocol worked for each host and use it directly on subsequent requests. This option is ignored if WithForceHttp1 or WithDisableHttp3 is set. When combined with a proxy, the proxy has to be a `socks5://` or `socks5h://` proxy that supports UDP ASSOCIATE. Any other proxy scheme is rejected with an error, because it could only carry the HTTP/2 leg and would let the HTTP/3 leg bypass the proxy. * WithBandwidthTracker Copy WithBandwidthTracker configures a client to track the bandwidth used by the client. You can retrieve the tracker via GetBandwidthTracker() and call GetTotalBandwidth(), GetWriteBytes(), GetReadBytes() or Reset() on it. * WithDialer Copy WithDialer configures an HTTP client to use the specified dialer. This allows the use of a custom DNS resolver. * WithProxyDialerFactory Copy WithProxyDialerFactory configures an HTTP client to use a custom proxyDialerFactory instead of the default newConnectDialer(). This allows to implement custom proxy dialer use cases. * WithDialContext Copy WithDialContext sets a custom dialer for TCP connections, allowing advanced networking (Zero-DNS, socket tagging, DPI bypass). WARNING: This overrides built-in proxy settings. If you need a proxy, you must handle the CONNECT handshake manually. Example: Copy client, err := tls_client.NewHttpClient( tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithDialContext(func(ctx context.Context, network, addr string) (net.Conn, error) { // Custom dialing logic here return net.Dial(network, addr) }), ) * WithPreHook Copy WithPreHook adds a pre-request hook that is called before each request is sent. Multiple hooks can be added and they will be executed in the order they were added. If any hook returns an error, the request is aborted and subsequent hooks are not called. To continue hook execution despite an error, wrap your error with ErrContinueHooks. The hook function signature is: Copy type PreRequestHookFunc func(req *http.Request) error Example: Copy client, err := tls_client.NewHttpClient( tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithPreHook(func(req *http.Request) error { req.Header.Set("X-Custom-Header", "my-value") return nil }), ) You can also add hooks at runtime using `client.AddPreRequestHook(hook)`. * WithPostHook Copy WithPostHook adds a post-response hook that is called after each request completes. Multiple hooks can be added and they will be executed in the order they were added. Hooks receive a PostResponseContext containing the request, response, and any error that occurred. If a hook returns an error, subsequent hooks are not called (unless wrapped with ErrContinueHooks). The hook function signature and context struct are: Copy type PostResponseContext struct { Request *http.Request Response *http.Response Error error // Non-nil if request failed } type PostResponseHookFunc func(ctx *PostResponseContext) error Example: Copy client, err := tls_client.NewHttpClient( tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithPostHook(func(ctx *tls_client.PostResponseContext) error { if ctx.Error != nil { log.Printf("Request failed: %v", ctx.Error) } else { log.Printf("Response status: %d", ctx.Response.StatusCode) } return nil }), ) You can also add hooks at runtime using `client.AddPostResponseHook(hook)`. * ErrContinueHooks Copy ErrContinueHooks can be returned (or wrapped) by a hook function to signal that the error should be logged but hook execution should continue to the next hook. By default any error returned from a hook aborts subsequent hooks (and for pre-hooks, the request). Example: Copy tls_client.WithPreHook(func(req *http.Request) error { // This error will be logged but subsequent hooks and the request will continue return fmt.Errorf("something went wrong: %w", tls_client.ErrContinueHooks) }) #### Examples[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options#examples) Several of the options above have a runnable example of their own: Option Example `WithProtocolRacing` [`./example/protocol_racing`](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol_racing) `WithDisableSessionTickets` [`./example/session_tickets`](https://github.com/bogdanfinn/tls-client/tree/master/example/session_tickets) `WithBandwidthTracker` [`./example/bandwidth`](https://github.com/bogdanfinn/tls-client/tree/master/example/bandwidth) `WithPreHook` / `WithPostHook` / `ErrContinueHooks` [`./example/hooks`](https://github.com/bogdanfinn/tls-client/tree/master/example/hooks) `WithCertificatePinning` [`./example/certificate_pinning`](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate_pinning) `WithClientProfile` [`./example/custom_profile`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_profile) , [`./example/custom_spec`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_spec) `WithProxyUrl` [`./example/proxy`](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy) `WithNotFollowRedirects` [`./example/redirects`](https://github.com/bogdanfinn/tls-client/tree/master/example/redirects) `WithCookieJar` [`./example/cookies`](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies) `WithTransportOptions` [`./example/concurrency`](https://github.com/bogdanfinn/tls-client/tree/master/example/concurrency) `WithForceHttp1` [`./example/websocket`](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket) , [`./example/decompress`](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress) The full list is on the [Examples](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples) page. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options#shared-library-and-standalone-api) When using the shared library or standalone api you can find almost every client option as a separate field to turn on / turn off or configure in the request payload. Please take a look at the Documentation about the [Payload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) . [PreviousInstallation & Quick Usage](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage) [NextCookiejar](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar) Last updated 8 hours ago --- # Request Headers | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers.md) . ### Header Sorting[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#header-sorting) You can sort your request headers per request by just providing a special header key (`"Header-Order:"`) with a list of header keys as sort order. Please keep in mind that it does not matter if your header keys are uppercase or all lowercase. For the header order **you have to define the header keys in the order list all lowercase.** Copy req.Header = http.Header{ "header4": {`value4`}, "header2": {"value2"}, "header1": {"value1"}, "header3": {"value3"}, "Header-Order:": { "header1", "header2", "header3", "header4", }, } The header order is applied for HTTP/1.1, HTTP/2 and HTTP/3 requests alike. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#shared-library-and-standalone-api) When you are using the shared library or the standalone api this works exactly the same. You can provide the header order with the same Header Order key. ### Header Key Capitalization[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#header-key-capitalization) Sometimes people are confused when to write header keys all lowercase and when to write them with first uppercase letter. For HTTP2 requests header keys are usually all lowercase. For HTTP1 Requests header keys are usually first uppercase letter. Just as a rule of thumb: `"accept-encoding"` => HTTP2 `"Accept-Encoding"` => HTTP1 ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#example) A runnable version is in [`./example/headers`](https://github.com/bogdanfinn/tls-client/tree/master/example/headers) . [PreviousDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults) [NextPseudo Header Order](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order) Last updated 8 hours ago * [Header Sorting](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#header-sorting) * [Header Key Capitalization](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#header-key-capitalization) * [Example](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers#example) --- # Defaults | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults.md) . If you call `ProvideDefaultClient()` you will receive a TLS-Client instance with the following settings * 30 seconds timeout * Chrome 150 as profile * Random TLS Extension order enabled * Follow Redirects disabled * Idle Connections will be closed after 90 seconds [PreviousCookiejar](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar) [NextRequest Headers](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers) Last updated 2 days ago --- # Pseudo Header Order | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order.md) . Pseudo headers are the following headers: `":method"`, `":authority"`, `":scheme"`, `":path"` and the order of them varies per client profile. Therefore you can define the order of the pseudo headers on the (custom-)client Profile. Copy pseudoHeaderOrder := []string{ ":method", ":authority", ":scheme", ":path", } customClientProfile := tls_client.NewClientProfile(tls.ClientHelloID{ Client: "MyCustomProfile", Version: "1", Seed: nil, SpecFactory: specFunc, }, settings, settingsOrder, pseudoHeaderOrder, connectionFlow, nil, nil) #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order#shared-library-and-standalone-api) You will see on the CustomClient object [payload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) that you can define the order as a list of strings. [PreviousRequest Headers](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers) [NextProxies](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies) Last updated 2 years ago --- # Response Body Encoding / Decoding | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding.md) . If you are specifying `accept-encoding` header yourself and you are on a `http1` connection than you have to take care of the response body decompression yourself. It is not done automatically. Only if you are **not** adding `accept-encoding` header then the library adds it for you if not explicit disabled and also handles the decompression automatically. On `http2` the automatic decompression should always be in place according to the `content-type` Header on the Response. `DecompressBody` is an exported function you can use. See the following example on how do decompress the response body manually Copy req, err := http.NewRequest(http.MethodGet, "https://tls.browserleaks.com/json", nil) if err != nil { log.Println(err) goreturn } req.Header = http.Header{ "accept": {"*/*"}, "accept-encoding": {"gzip"}, "accept-language": {"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"}, "user-agent": {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"}, http.HeaderOrderKey: { "accept", "accept-encoding", "accept-language", "user-agent", }, } resp, err := client.Do(req) if err != nil { log.Println(err) return } defer resp.Body.Close() decomBody := http.DecompressBody(resp) all, err := ioutil.ReadAll(decomBody) if err != nil { log.Println(err) return } log.Println(string(all)) It is possible to disable the automatic decompression on http2 by adding the following option to the http client #### Automatic Charset Detection[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding#automatic-charset-detection) When using the shared library or standalone API, the response body charset is automatically detected and decoded based on the `Content-Type` response header (e.g. `charset=euc-kr`, `charset=shift_jis`, etc.). This means you no longer need to handle specific encodings manually — the correct character encoding is applied automatically for all text responses. This behavior is active whenever `isByteResponse` is `false` (the default). If you need the raw bytes, set `isByteResponse: true`. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding#shared-library-and-standalone-api) When you are using the shared library or standalone api application the response body will always be decompressed and the charset will be automatically detected and decoded. ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding#example) A runnable version is in [`./example/decompress`](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress) . [PreviousCertificate Pinning](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning) [NextCustom Client Profile](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile) Last updated 8 hours ago Copy tls_client.WithTransportOptions(&tls_client.TransportOptions{ DisableCompression: true, }), --- # Certificate Pinning | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning.md) . You can enable certificate pinning for a TLS-Client instance. You need to provide a map of pins by host when you create the client. See the example code below Copy pins := map[string][]string{ "bstn.com": { "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=", "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=", "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=", }, } options := []tls_client.HttpClientOption{ tls_client.WithCertificatePinning(pins, tls_client.DefaultBadPinHandler), } client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) This example code shows how to enabled certificate pinning for bstn.com. Next to it you can supply a BadPinHandler function as second argument for the WithCertificatePinning option. The default BadPinHandler looks like this. This function will be executed when a bad pin is detected: Copy var DefaultBadPinHandler = func(req *http.Request) { fmt.Println("this is the default bad pin handler") } #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning#shared-library-and-standalone-api) When using the shared library you can supply certificate pinning settings via the `"certificatePinningHosts"` field. This should look similar to this: #### Wildcards[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning#wildcards) You can define wildcards for subdomains for example like this #### How to generate pins?[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning#how-to-generate-pins) You can easilly generate pins with this helpful tool: [https://github.com/tam7t/hpkp](https://github.com/tam7t/hpkp) Just install the tool and run the following command against the site you want to generate pins for: ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning#example) A runnable version is in [`./example/certificate_pinning`](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate_pinning) . [PreviousProxies](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies) [NextResponse Body Encoding / Decoding](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding) Last updated 8 hours ago Copy "certificatePinningHosts": { "bstn.com": [\ "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=",\ "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=",\ "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=",\ ], }, Copy pins := map[string][]string{ "*.bstn.com": { "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=", "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=", "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=", }, } options := []tls_client.HttpClientOption{ tls_client.WithCertificatePinning(pins, tls_client.DefaultBadPinHandler), } client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), options...) Copy hpkp-pins -server=bstn.com:443 --- # Custom Client Profile | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile.md) . **You should know at least a bit about TLS Fingerprints in order to know what you are doing here and what is minimum required.** You can build complete custom clients which consist of different things. When we look at the factory method we see that you need to provide the following information: * A clientHelloId which holds the `ClientHelloSpecFactory`. More about that later. * A key value map of http2 settings * A list of http2 settings for the order * A list of [pseudo headers](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order) for the order * A value for the connection flow * A slice of http2 priority settings * A optional header priority setting * A stream id and whether plain `http://` is allowed * The http3 counterparts: a settings map, their order, the priority param, the pseudo header order and whether to send GREASE frames The last two groups can be left at their zero values (`0`, `false`, `nil`). A profile without http3 settings simply has no HTTP/3 fingerprint, which only matters once the client actually speaks HTTP/3 - see [Protocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) . Copy func NewClientProfile(clientHelloId tls.ClientHelloID, settings map[http2.SettingID]uint32, settingsOrder []http2.SettingID, pseudoHeaderOrder []string, connectionFlow uint32, priorities []http2.Priority, headerPriority *http2.PriorityParam, streamID uint32, allowHTTP bool, http3Settings map[uint64]uint64, http3SettingsOrder []uint64, http3PriorityParam uint32, http3PseudoHeaderOrder []string, http3SendGreaseFrames bool) ClientProfile { return ClientProfile{ clientHelloId: clientHelloId, settings: settings, settingsOrder: settingsOrder, pseudoHeaderOrder: pseudoHeaderOrder, connectionFlow: connectionFlow, priorities: priorities, headerPriority: headerPriority, streamID: streamID, allowHTTP: allowHTTP, http3Settings: http3Settings, http3SettingsOrder: http3SettingsOrder, http3PriorityParam: http3PriorityParam, http3PseudoHeaderOrder: http3PseudoHeaderOrder, http3SendGreaseFrames: http3SendGreaseFrames, } } Note that `NewClientProfile` lives in the `profiles` package, so you call it as `profiles.NewClientProfile(...)`. You can create a `ClientHelloSpecFactory` out of a ja3 string by calling GetSpecFactoryFromJa3String. You need to provide in addition the following information, as these can't be derived from the ja3 string: * A list of supported signature algorithms * A list of supported delegated credentials algorithms * A list of supported TLS versions * A list of supported key share curves * A list of certificate compression algorithms * A value for the RecordSizeLimit Extension, as a `uint16` * The payload for the trust\_anchors extension, if your ja3 string lists extension `51764` Chrome 150 and later also advertise the ML-DSA codepoints, and Chrome 152 puts a GREASE value first, so a fingerprint imitating those versions needs `"GREASE"`, `"MLDSA44"`, `"MLDSA65"` or `"MLDSA87"` in the signature algorithm list. utls replaces the GREASE placeholder with a value drawn per connection, exactly as it does for the bundled profiles. #### The trust\_anchors extension (51764)[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile#the-trust_anchors-extension-51764) Chromium sends the trust\_anchors extension from Chrome 144 on. A ja3 string names extension IDs but carries no extension data, so when your ja3 string contains `51764` the payload has to come alongside it as a hex string. Leaving it empty in that case fails with an error naming the parameter. Take the value from the `data` field of the `Unknown extension 51764` entry in a browser fingerprint; it already starts at the 16-bit list length. `"0000"` is an empty anchor list. Of the shipped profiles, `chrome_146` and `chrome_146_PSK` send that empty list, while `chrome_152` and `chrome_152_PSK` send a captured 186 byte payload of 28 anchor IDs. The other profiles do not send the extension at all. The IDs are reordered once per spec factory, because Chromium writes them in hash set iteration order, which holds for the life of a browser process and differs between processes. `profiles.BuildTrustAnchorsPayload` does that on its own if you build the extension by hand. At the end you can just build the complete custom profile by providing all the above mentioned information. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile#shared-library-and-standalone-api) It is also possible to define custom client profiles when working with the shared library or the standalone api. For that you are not calling functions but provide all the information on the request payload that the TLS client is able to build the client profile out of it. Instead of the `"tlsClientIdentifier"` you can provide on the request payload the `"customTlsClient"`. Only `"ja3String"` is really required; every other field falls back to a zero value. The setting names in `"h2Settings"` / `"h2SettingsOrder"` and `"h3Settings"` / `"h3SettingsOrder"` have to be spelled as below, unknown names are ignored. #### Examples[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile#examples) * [`./example/custom_profile`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_profile) builds the profile from a JA3 string, including the `trust_anchors` payload and the ML-DSA / GREASE signature algorithms Chrome 150 and later send. * [`./example/custom_spec`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_spec) builds the `tls.ClientHelloSpec` by hand, which is the way to go when an extension needs data a JA3 string cannot carry - PSK and ALPS, for instance. [PreviousResponse Body Encoding / Decoding](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding) [NextWebSocket](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket) Last updated 8 hours ago Copy ja3 := "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-10-11-13-16-23-43-51-65281-45-21,29-23-24,0" ssa := []string{"ECDSAWithP256AndSHA256", "PSSWithSHA256", "PKCS1WithSHA256", "ECDSAWithP384AndSHA384", "PSSWithSHA384", "PKCS1WithSHA384", "PSSWithSHA512", "PKCS1WithSHA512"} dca := []string{"ECDSAWithP256AndSHA256", "PSSWithSHA256", "PKCS1WithSHA256", "ECDSAWithP384AndSHA384", "PSSWithSHA384", "PKCS1WithSHA384", "PSSWithSHA512", "PKCS1WithSHA512"} sv := []string{"GREASE", "1.3", "1.2"} sc := []string{"GREASE", "X25519"} alpnProtocols := []string{"h2", "http/1.1"} alpsProtocols := []string{"h2"} ccs := []tls_client.CandidateCipherSuites{ { KdfId: "HKDF_SHA256", AeadId: "AEAD_AES_128_GCM", }, { KdfId: "HKDF_SHA256", AeadId: "AEAD_CHACHA20_POLY1305", }, } cp := []uint16{128, 160, 192, 224} certCompressionAlgos := []string{"zlib"} recordSizeLimit := uint16(0) trustAnchorsPayload := "" // hex payload, only needed if the ja3 string lists extension 51764 specFunc, err := tls_client.GetSpecFactoryFromJa3String(ja3, ssa, dca, sv, sc, alpnProtocols, alpsProtocols, ccs, cp, certCompressionAlgos, recordSizeLimit, trustAnchorsPayload) Copy specFunc, err := tls_client.GetSpecFactoryFromJa3String(ja3, ssa, dca, sv, sc, alpnProtocols, alpsProtocols, ccs, cp, certCompressionAlgos, recordSizeLimit, trustAnchorsPayload) if err != nil { log.Println(err.Error()) return } settings := map[http2.SettingID]uint32{ http2.SettingHeaderTableSize: 65536, http2.SettingMaxConcurrentStreams: 1000, http2.SettingInitialWindowSize: 6291456, http2.SettingMaxHeaderListSize: 262144, } settingsOrder := []http2.SettingID{ http2.SettingHeaderTableSize, http2.SettingMaxConcurrentStreams, http2.SettingInitialWindowSize, http2.SettingMaxHeaderListSize, } pseudoHeaderOrder := []string{ ":method", ":authority", ":scheme", ":path", } connectionFlow := uint32(15663105) customClientProfile := profiles.NewClientProfile(tls.ClientHelloID{ Client: "MyCustomProfile", Version: "1", Seed: nil, SpecFactory: specFunc, }, settings, settingsOrder, pseudoHeaderOrder, connectionFlow, nil, // priorities nil, // headerPriority 0, // streamID false, // allowHTTP nil, // http3Settings nil, // http3SettingsOrder 0, // http3PriorityParam nil, // http3PseudoHeaderOrder false, // http3SendGreaseFrames ) client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), tls_client.WithClientProfile(customClientProfile)) if err != nil { log.Println(err.Error()) return } Copy { "customTlsClient": { "ja3String": "771,2570-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,2570-29-23-24,0", "trustAnchorsPayload": "", "h2Settings": { "HEADER_TABLE_SIZE": 65536, "MAX_CONCURRENT_STREAMS": 1000, "INITIAL_WINDOW_SIZE": 6291456, "MAX_HEADER_LIST_SIZE": 262144 }, "h2SettingsOrder": [\ "HEADER_TABLE_SIZE",\ "MAX_CONCURRENT_STREAMS",\ "INITIAL_WINDOW_SIZE",\ "MAX_HEADER_LIST_SIZE"\ ], "supportedSignatureAlgorithms": [\ "ECDSAWithP256AndSHA256",\ "PSSWithSHA256",\ "PKCS1WithSHA256",\ "ECDSAWithP384AndSHA384",\ "PSSWithSHA384",\ "PKCS1WithSHA384",\ "PSSWithSHA512",\ "PKCS1WithSHA512"\ ], "supportedDelegatedCredentialsAlgorithms": [], "supportedVersions": ["GREASE", "1.3", "1.2"], "keyShareCurves": ["GREASE", "X25519"], "alpnProtocols": ["h2", "http/1.1"], "alpsProtocols": ["h2"], "certCompressionAlgos": ["brotli"], "recordSizeLimit": 0, "ECHCandidatePayloads": [], "ECHCandidateCipherSuites": [], "pseudoHeaderOrder": [\ ":method",\ ":authority",\ ":scheme",\ ":path"\ ], "connectionFlow": 15663105, "streamId": 0, "allowHttp": false, "priorityFrames": [\ {\ "streamID": 1,\ "priorityParam": {\ "streamDep": 1,\ "exclusive": true,\ "weight": 1\ }\ }\ ], "headerPriority": { "streamDep": 1, "exclusive": true, "weight": 1 }, "h3Settings": { "QPACK_MAX_TABLE_CAPACITY": 65536, "MAX_FIELD_SECTION_SIZE": 262144, "QPACK_BLOCKED_STREAMS": 100, "H3_DATAGRAM": 1 }, "h3SettingsOrder": [\ "QPACK_MAX_TABLE_CAPACITY",\ "MAX_FIELD_SECTION_SIZE",\ "QPACK_BLOCKED_STREAMS",\ "H3_DATAGRAM"\ ], "h3PseudoHeaderOrder": [\ ":method",\ ":authority",\ ":scheme",\ ":path"\ ], "h3PriorityParam": 984832, "h3SendGreaseFrames": true } } --- # Examples | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples.md) . Every example is one focused, standalone program under `./example//` in the repository, runnable with `go run ./example/` and meant to be copied from directly. ### Requests[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#requests) * [`./example/basic`](https://github.com/bogdanfinn/tls-client/tree/master/example/basic) - GET Request * [`./example/post`](https://github.com/bogdanfinn/tls-client/tree/master/example/post) - POST Request * [`./example/headers`](https://github.com/bogdanfinn/tls-client/tree/master/example/headers) - Custom Headers & [Header Order](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers) * [`./example/cookies`](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies) - [Cookie Jar](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar) * [`./example/redirects`](https://github.com/bogdanfinn/tls-client/tree/master/example/redirects) - Switching the Redirect Following Behavior * [`./example/download`](https://github.com/bogdanfinn/tls-client/tree/master/example/download) - Downloading Image / Files * [`./example/decompress`](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress) - Manual [Response Body Decompression](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding) ### Fingerprints[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#fingerprints) * [`./example/custom_profile`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_profile) - [Custom Client Profile](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile) from a JA3 string, including the `trust_anchors` payload * [`./example/custom_spec`](https://github.com/bogdanfinn/tls-client/tree/master/example/custom_spec) - Hand built `ClientHelloSpec` for extensions a JA3 string cannot express (PSK, ALPS) * [`./example/session_tickets`](https://github.com/bogdanfinn/tls-client/tree/master/example/session_tickets) - Disabling TLS Session Tickets ### Connection[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#connection) * [`./example/proxy`](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy) - [Proxy](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies) & Proxy Rotation * [`./example/protocol_racing`](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol_racing) - [Protocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) (HTTP/3 vs HTTP/2) and its SOCKS5 requirement * [`./example/websocket`](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket) - [WebSocket](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket) with the client's TLS fingerprint * [`./example/certificate_pinning`](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate_pinning) - [Certificate Pinning](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning) ### Concurrency[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#concurrency) * [`./example/concurrency`](https://github.com/bogdanfinn/tls-client/tree/master/example/concurrency) - One client shared by many goroutines, decoding every response, with heap statistics and an optional pprof heap profile * [`./example/client_per_worker`](https://github.com/bogdanfinn/tls-client/tree/master/example/client_per_worker) - The same setup with a client per worker instead of a shared one, counting the dials that a shared client would have avoided * [`./example/connection_reuse`](https://github.com/bogdanfinn/tls-client/tree/master/example/connection_reuse) - Verifies that one TCP connection is reused across requests, counting dials and cross-checking with `httptrace` ### Observability[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#observability) * [`./example/bandwidth`](https://github.com/bogdanfinn/tls-client/tree/master/example/bandwidth) - Bandwidth Tracking * [`./example/hooks`](https://github.com/bogdanfinn/tls-client/tree/master/example/hooks) - Pre-Request & Post-Response Hooks For the shared library and the standalone API the same topics are covered per language under `cffi_dist/`, see the [JavaScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples) , [Python](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples) , [TypeScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples) and [C#](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples) example pages. [PreviousProtocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) [NextShared Library](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library) Last updated 7 hours ago * [Requests](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#requests) * [Fingerprints](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#fingerprints) * [Connection](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#connection) * [Concurrency](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#concurrency) * [Observability](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples#observability) --- # Shared Library | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library.md) . [Node Version](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version) [Downloads](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads) [Build from source](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source) [Exposed Methods](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods) [JavaScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript) [Python](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python) [TypeScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript) [C#](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c) [Defaults](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults) [Payload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) [Response](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response) [Memory Issues](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues) [PreviousExamples](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples) [NextNode Version](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version) Last updated 2 years ago --- # Node Version | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version.md) . Some users experienced issues when using the shared library with NodeJS14 or lower. It is recommended to use at least NodeJS16. [PreviousShared Library](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library) [NextDownloads](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads) Last updated 3 years ago --- # Downloads | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads.md) . Here you can find the latest prebuilt shared library. Older versions before 1.3.8 can be found in the Github history of the repository: [https://github.com/bogdanfinn/tls-client/releases](https://github.com/bogdanfinn/tls-client/releases) [PreviousNode Version](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version) [NextBuild from source](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source) Last updated 7 months ago --- # Protocol Racing | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing.md) . Protocol Racing allows the TLS-Client to race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel, similar to Chrome's "Happy Eyeballs" approach. Both connection types are started simultaneously and whichever connects first is used. The client remembers which protocol worked for each host and uses it directly on subsequent requests. If the cached protocol fails, the client falls back to racing again. ### How it works[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#how-it-works) 1. On the first request to a host, both HTTP/3 and HTTP/2 connections are started in parallel. 2. HTTP/2 is delayed by 300ms (same as Chrome) to give HTTP/3 a slight head start. 3. Whichever protocol succeeds first is used for the request. 4. The winning protocol is cached for the host and used directly on future requests. 5. If the cached protocol fails, the cache is cleared and racing restarts. ### Usage (Go)[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#usage-go) Copy client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithProtocolRacing(), ) ### Using Protocol Racing with a Proxy[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#using-protocol-racing-with-a-proxy) The HTTP/2 leg of the race runs over TCP, the HTTP/3 leg runs over QUIC, which is UDP. A proxy therefore has to be able to carry UDP, and of the supported proxy schemes only SOCKS5 can, through UDP ASSOCIATE. So when you combine protocol racing with a proxy, that proxy has to be a `socks5://` or `socks5h://` proxy **and the proxy server has to support UDP ASSOCIATE**. Not every SOCKS5 provider enables it. Any other proxy scheme is rejected with an error, both when the client is created and when you call `SetProxy` later. That is deliberate: an HTTP or SOCKS4 proxy can only carry the HTTP/2 leg, so the HTTP/3 leg would go out directly and expose your real IP address without any visible sign that it happened. If you have to use an HTTP proxy, disable protocol racing or HTTP/3: ### Configuration Constraints[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#configuration-constraints) Protocol Racing cannot be used in combination with certain other options. The following configurations are invalid and will result in an error: * `WithProtocolRacing()` + `WithDisableHttp3()` — Racing requires HTTP/3 to be enabled. * `WithProtocolRacing()` + `WithForceHttp1()` — Racing requires HTTP/2 and HTTP/3. * `WithProtocolRacing()` + a non-SOCKS5 proxy — Only SOCKS5 can tunnel the UDP traffic HTTP/3 needs. * `WithDisableIPV4()` + `WithDisableIPV6()` — Cannot disable both IP versions. * `WithCertificatePinning()` + `WithInsecureSkipVerify()` — Certificate pinning is incompatible with skipping verification. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#shared-library-and-standalone-api) When using the shared library or standalone API, set `"withProtocolRacing": true` in the request payload to enable protocol racing. The same configuration constraints apply, including the SOCKS5 requirement when a `"proxyUrl"` is set. ### Known Issues[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#known-issues) Two limitations apply to protocol racing as of version 1.16.0. Both only affect clients that actually use HTTP/3, so a client without protocol racing is unaffected. #### Most profiles have no HTTP/3 fingerprint[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#most-profiles-have-no-http-3-fingerprint) Only five of the shipped profiles carry HTTP/3 settings: `chrome_144`, `chrome_144_PSK`, `firefox_147`, `firefox_147_PSK` and `firefox_148`. Every other profile falls back to a minimal SETTINGS frame, so its HTTP/3 fingerprint does not resemble the browser it imitates: The TLS and HTTP/2 fingerprints of those profiles are unaffected; this is only about the HTTP/3 SETTINGS frame, the GREASE setting and the priority parameter. If the HTTP/3 fingerprint matters for your target, use one of the five profiles above, or turn HTTP/3 off with `WithDisableHttp3()` so the request goes over HTTP/2 with a correct fingerprint. #### Data race between the two racing legs[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#data-race-between-the-two-racing-legs) Both legs of a race are handed the same `*http.Request`. The HTTP/3 transport writes to its header map while the HTTP/2 transport reads from it, which the Go race detector reports as a data race. It is unlikely to be observed on an occasional request but shows up reliably when many requests race at the same time, and a concurrent map access can crash the process. If you send a high volume of concurrent requests, prefer `WithDisableHttp3()` until this is fixed. ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#example) A runnable version of everything above, including the rejected proxy schemes, is in [`./example/protocol_racing`](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol_racing) . [PreviousWebSocket](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket) [NextExamples](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples) Last updated 7 hours ago * [How it works](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#how-it-works) * [Usage (Go)](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#usage-go) * [Using Protocol Racing with a Proxy](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#using-protocol-racing-with-a-proxy) * [Configuration Constraints](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#configuration-constraints) * [Known Issues](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#known-issues) * [Example](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing#example) Copy client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithProtocolRacing(), tls_client.WithProxyUrl("socks5://user:pass@host:port"), ) Copy client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithDisableHttp3(), tls_client.WithProxyUrl("http://user:pass@host:port"), ) Copy chrome_144 1:65536;6:262144;7:100;51:1;GREASE|GREASE|984832|m,a,s,p chrome_150 51:1|m,a,s,p chrome_152 51:1|m,a,s,p firefox_147 1:65536;7:20;727725890:0;16765559:1;51:1;8:1|GREASE|m,s,a,p --- # WebSocket | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket.md) . The TLS-Client supports WebSocket connections with the same TLS fingerprinting as regular HTTP requests. This ensures consistent fingerprinting across both HTTP and WebSocket connections. **Important:** WebSocket connections require HTTP/1.1. You **must** use `WithForceHttp1()` when creating the HTTP client. ### Usage (Go)[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#usage-go) Copy // Create HTTP client with ForceHttp1 (required for WebSocket!) client, err := tls_client.NewHttpClient(tls_client.NewNoopLogger(), tls_client.WithClientProfile(profiles.Chrome_150), tls_client.WithForceHttp1(), ) // Create WebSocket with optional header ordering headers := http.Header{ "User-Agent": {"MyBot/1.0"}, http.HeaderOrderKey: {"host", "upgrade", "connection", "user-agent"}, } ws, err := tls_client.NewWebsocket(nil, tls_client.WithUrl("wss://example.com/ws"), tls_client.WithTlsClient(client), tls_client.WithHeaders(headers), ) conn, err := ws.Connect(context.Background()) defer conn.Close() ### WebSocket Options[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#websocket-options) * WithUrl * WithTlsClient * WithHeaders * WithReadBufferSize * WithWriteBufferSize * WithHandshakeTimeoutMilliseconds * WithCookiejar ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#example) A runnable version is in [`./example/websocket`](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket) . [PreviousCustom Client Profile](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile) [NextProtocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) Last updated 7 hours ago * [Usage (Go)](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#usage-go) * [WebSocket Options](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#websocket-options) * [Example](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket#example) Copy WithUrl sets the WebSocket URL to connect to. Required. Copy WithTlsClient sets the tls-client HttpClient to use for the WebSocket connection. The underlying dialer from this client will be used to establish the connection, preserving TLS fingerprinting and other client configurations. Required. Copy WithHeaders sets the HTTP headers to send during the WebSocket handshake. You can use the http.HeaderOrderKey to control header ordering. Copy WithReadBufferSize sets the read buffer size for the WebSocket connection. Copy WithWriteBufferSize sets the write buffer size for the WebSocket connection. Copy WithHandshakeTimeoutMilliseconds sets the timeout for the WebSocket handshake in milliseconds. Copy WithCookiejar sets the cookie jar to use for the WebSocket connection. --- # Build from source | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source.md) . When you want to build the shared libraries from source you can just run the following script: `cffi_dist/build.sh SOME_BUILD_IDENTIFIER` and it should build the binaries for you. [PreviousDownloads](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads) [NextExposed Methods](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods) Last updated 3 years ago --- # Proxies | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies.md) . Proxies can be used by either setting them as client option `WithProxyUrl` when creating the TLS client or calling `SetProxy` on an exisiting client instance. A proxy should be formatted like this: `http://username:password@host:port` or `socks5://username:password@host:port` If you are using rotating Proxies (proxies with a static URL) then make sure to always call SetProxy with the same proxy again to let the client reconnect to the Proxy Server and receive a new IP-Address. ### Proxies and HTTP/3[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies#proxies-and-http-3) HTTP/3 runs over QUIC, which is UDP. An HTTP or SOCKS4 proxy can only carry TCP, so it cannot tunnel HTTP/3 at all. Only SOCKS5 can, through UDP ASSOCIATE. That is why a client with `WithProtocolRacing()` enabled requires a `socks5://` or `socks5h://` proxy whose server supports UDP ASSOCIATE. Any other scheme is rejected with an error, both when creating the client and when calling `SetProxy`. Without that check the HTTP/2 leg would go through the proxy while the HTTP/3 leg went out directly and exposed your real IP address. Clients without protocol racing are unaffected and work with every supported proxy scheme. #### Shared Library & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies#shared-library-and-standalone-api) When you are using the shared library or the standalone api you can supply a proxy in the `"proxyUrl"` field and set `"isRotatingProxy"` to `true` or `false`. ### Example[](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies#example) A runnable version, including switching the proxy on an existing client, is in [`./example/proxy`](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy) . For protocol racing over a proxy see [Protocol Racing](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing) and [`./example/protocol_racing`](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol_racing) . [PreviousPseudo Header Order](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order) [NextCertificate Pinning](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning) Last updated 8 hours ago * [Proxies and HTTP/3](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies#proxies-and-http-3) * [Example](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies#example) --- # Exposed Methods | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods.md) . The shared library exposes the following endpoints / methods you can call. The payload is always a JSON string expect for the `freeMemory` method. You will find the methods also in use in the examples. #### request(payload: string) => string[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#request-payload-string-greater-than-string) This is the basic method you will use to do requests. For full detailed documentation about the payload please take a look at [Payload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) . As you see here on other methods you have to turn the JSON Object into a JSON string before supplying it as the payload parameter. #### getCookiesFromSession(payload: string) => string[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#getcookiesfromsession-payload-string-greater-than-string) Get all cookies which are in the provided session for a given URL. The payload should look like this: Copy "{\"sessionId\": \"someExistingSessionId\", \"url\": \"urlToGetCookiesFor\"}" #### addCookiesToSession(payload: string) => string[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#addcookiestosession-payload-string-greater-than-string) Add manual cookies to an existing session. The payload should look like this: Copy "{\"sessionId\": \"someExistingSessionId\", \"url\": \"urlToAddCookiesFor\", \"cookies\": []}" #### freeMemory(responseId: string) => void[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#freememory-responseid-string-greater-than-void) Supply the `"id"` of a previous response as string in order to free the allocated memory of the previous response. #### destroyAll() => string[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#destroyall-greater-than-string) Destroy all existing sessions in order to release allocated memory. #### destroySession(payload: string) => string[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods#destroysession-payload-string-greater-than-string) Destroy a specific session in order to release allocated memory. The payload should look like this: Copy "{\"sessionId\": \"someExistingSessionId\"}" [PreviousBuild from source](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source) [NextJavaScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript) Last updated 3 years ago --- # JavaScript | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript.md) . [Examples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples) [PreviousExposed Methods](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods) [NextExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples) Last updated 3 years ago --- # Examples | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples.md) . Please take a look at the following NodeJS Code in the repository to see examples implemented: `cffi_dist/example_node/` We provide examples for the following use cases: * GET Request * POST Request * Image Download * Image Upload * Async Request * Custom Client * Use Cookies * Proxy Rotation * Switching the Redirect Following Behavior * Certificate Pinning * Use ffi-rs instead of ffi-napi [PreviousJavaScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript) [NextPython](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python) Last updated 15 hours ago --- # Python | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python.md) . [Examples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples) [PreviousExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples) [NextExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples) Last updated 3 years ago --- # TypeScript | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript.md) . [Examples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples) [PreviousExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples) [NextExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples) Last updated 3 years ago --- # Examples | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples.md) . Please take a look at the following Python Code in the repository to see examples implemented: `cffi_dist/example_python/` We provide examples for the following use cases: * GET Request * POST Request * Image Download * Image Upload * Async Request * Custom Client * Use Cookies * Proxy Rotation * Switching the Redirect Following Behavior * Certificate Pinning [PreviousPython](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python) [NextTypeScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript) Last updated 15 hours ago --- # Examples | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples.md) . Please take a look at the following Typescript Code in the repository to see examples implemented: `cffi_dist/example_typescript/src/samples/` We provide examples for the following use cases: * GET Request (`sync.ts`) * Async Request (`async.ts`) * POST Request (`post.ts`) * Use Cookies (`cookies.ts`) * Custom Client (`custom_client.ts`) * Proxy Rotation (`proxy.ts`) * Switching the Redirect Following Behavior (`redirects.ts`) * Certificate Pinning (`pinning.ts`) * Image Download (`download.ts`) Each sample can be run with its own npm script, e.g. `npm run start:post`. See `package.json` for the full list. `src/types.ts` mirrors the payload and response structs of the shared library, which live in `cffi_src/types.go` in the tls-client repository. Every field of the request payload, the `customTlsClient` definition and the transport options is typed there, including the HTTP/2 and HTTP/3 setting names as string unions. When you upgrade the shared library, check that go file for new fields. `src/client.ts` wraps the [exposed methods](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods) and frees the memory of every response for you, so you do not have to call `freeMemory` yourself. In general you can also take a look at the [JavaScript Examples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples) . The Typescript examples are more about how to define the types correctly and use them. [PreviousTypeScript](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript) [NextC#](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c) Last updated 9 hours ago --- # C# | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c.md) . [Examples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples) [PreviousExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples) [NextExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples) --- # Examples | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples.md) . Please take a look at the following C# code in the repository to see examples implemented: `cffi_dist/example_csharp/` `Requester.cs` shows loading and defining the shared library, plus a small session wrapper class. `Example.csproj` is a runnable console project (`dotnet run -- `) with a short, focused example per topic: * `basic` - GET Request * `post` - POST Request * `cookies` - Use Cookies * `custom_client` - Custom Client * `proxy` - Proxy Rotation * `redirects` - Switching the Redirect Following Behavior * `pinning` - Certificate Pinning * `download` - Image Download Adjust `LibraryPath` in `TlsClientLibrary.cs` to point at the shared library you downloaded for your OS/arch/version before running. [PreviousC#](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c) [NextDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults) Last updated 9 hours ago --- # Defaults | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults.md) . The client from the shared library uses the same default settings as the regular TLS client which are defined [here](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults) [PreviousExamples](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples) [NextPayload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) Last updated 2 years ago --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme.md). # TLS-Client ## Preface This TLS Client is built upon and as well as . Big thanks to all contributors so far. Sadly it seems that the original repositories are not maintained anymore and the original \\\`utls\\\` repository is not enough without custom modifications. ## What is TLS Fingerprinting? Some people think it is enough to change the user-agent header of a request to let the server think that the client requesting a resource is a specific browser. Nowadays this is not enough, because the server might use a technique to detect the client browser which is called TLS Fingerprinting. Even tho this article is about TLS Fingerprinting in NodeJS it well describes the technique in detail:\\ ## Why is this library needed? With this library you are able to create a http client implementing an interface which is similar to golangs net/http client interface. This TLS Client allows you to specify the client profile (Browser) you want to use, when requesting a server. The interface of the HTTP Client looks like the following and extends the base net/http Client interface by some useful functions. Most likely you will use the \`Do()\` function like you did before with golangs net/http Client. \`\`\`go type HttpClient interface { GetCookies(u \*url.URL) \[\]\*http.Cookie SetCookies(u \*url.URL, cookies \[\]\*http.Cookie) SetCookieJar(jar http.CookieJar) GetCookieJar() http.CookieJar SetProxy(proxyUrl string) error GetProxy() string SetFollowRedirect(followRedirect bool) GetFollowRedirect() bool CloseIdleConnections() Do(req \*http.Request) (\*http.Response, error) Get(url string) (resp \*http.Response, err error) Head(url string) (resp \*http.Response, err error) Post(url, contentType string, body io.Reader) (resp \*http.Response, err error) GetBandwidthTracker() bandwidth.BandwidthTracker GetDialer() proxy.ContextDialer GetTLSDialer() TLSDialerFunc } \`\`\` The methods should be more or less self explanatory. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers.md). # Request Headers ### Header Sorting You can sort your request headers per request by just providing a special header key (\`"Header-Order:"\`) with a list of header keys as sort order. Please keep in mind that it does not matter if your header keys are uppercase or all lowercase. For the header order \*\*you have to define the header keys in the order list all lowercase.\*\* \`\`\`go req.Header = http.Header{ "header4": {\`value4\`}, "header2": {"value2"}, "header1": {"value1"}, "header3": {"value3"}, "Header-Order:": { "header1", "header2", "header3", "header4", }, } \`\`\` The header order is applied for HTTP/1.1, HTTP/2 and HTTP/3 requests alike. #### Shared Library & Standalone API When you are using the shared library or the standalone api this works exactly the same. You can provide the header order with the same Header Order key. ### Header Key Capitalization Sometimes people are confused when to write header keys all lowercase and when to write them with first uppercase letter. For HTTP2 requests header keys are usually all lowercase. For HTTP1 Requests header keys are usually first uppercase letter. Just as a rule of thumb: \`"accept-encoding"\` => HTTP2 \`"Accept-Encoding"\` => HTTP1 ### Example A runnable version is in \[\`./example/headers\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/headers). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles.md). # Supported and tested Client Profiles ### Internal Client Profiles The internal client profiles were created and tested by myself. Of course that does not mean they are 100% correct. But i tested them more precise then the contributed profiles. 1. Chrome \* 103 (chrome\\\_103) \* 104 (chrome\\\_104) \* 105 (chrome\\\_105) \* 106 (chrome\\\_106) \* 107 (chrome\\\_107) \* 108 (chrome\\\_108) \* 109 (chrome\\\_109) \* 110 (chrome\\\_110) \* 111 (chrome\\\_111) \* 112 (chrome\\\_112) \* 116 with PSK (chrome\\\_116\\\_PSK) \* 116 with PSK and PQ (chrome\\\_116\\\_PSK\\\_PQ) \* 117 (chrome\\\_117) \* 120 (chrome\\\_120) \* 124 (chrome\\\_124) \* 133 (chrome\\\_133) \* 133 with PSK (chrome\\\_133\\\_PSK) \* 144 (chrome\\\_144) \* 144 with PSK (chrome\\\_144\\\_PSK) \* 146 (chrome\\\_146) \* 146 with PSK (chrome\\\_146\\\_PSK) \* 150 (chrome\\\_150) \* 150 with PSK (chrome\\\_150\\\_PSK) \* 152 (chrome\\\_152) \* 152 with PSK (chrome\\\_152\\\_PSK) 2. Brave \* 146 (brave\\\_146) \* 146 with PSK (brave\\\_146\\\_PSK) 3. Safari \* 15.6.1 (safari\\\_15\\\_6\\\_1) \* 16.0 (safari\\\_16\\\_0) 4. iOS (Safari) \* 15.5 (safari\\\_ios\\\_15\\\_5) \* 15.6 (safari\\\_ios\\\_15\\\_6) \* 16.0 (safari\\\_ios\\\_16\\\_0) \* 17.0 (safari\\\_ios\\\_17\\\_0) \* 18.0 (safari\\\_ios\\\_18\\\_0) \* 18.5 (safari\\\_ios\\\_18\\\_5) \* 26.0 (safari\\\_ios\\\_26\\\_0) 5. iPadOS (Safari) \* 15.6 (safari\\\_ipad\\\_15\\\_6) 6. Firefox \* 102 (firefox\\\_102) \* 104 (firefox\\\_104) \* 105 (firefox\\\_105) \* 106 (firefox\\\_106) \* 108 (firefox\\\_108) \* 110 (firefox\\\_110) \* 117 (firefox\\\_117) 7. Opera \* 89 (opera\\\_89) \* 90 (opera\\\_90) \* 91 (opera\\\_91) 8. Custom Clients \* Zalando iOS Mobile (zalando\\\_ios\\\_mobile) \* Nike IOS Mobile (nike\\\_ios\\\_mobile) \* Cloudscraper \* MMS IOS (mms\\\_ios or mms\\\_ios\\\_1) \* MMS IOS 2 (mms\\\_ios\\\_2) \* MMS IOS 3 (mms\\\_ios\\\_3) \* Mesh IOS (mesh\\\_ios or mesh\\\_ios\\\_1) \* Confirmed IOS (confirmed\\\_ios) ### Contributed Client Profiles The contributed client profiles are contributed by people from the community. They are not precisely tested like the internal ones. Please be aware that they might have issues. 1. Chrome \* 130 with PSK (chrome\\\_130\\\_PSK) \* 131 (chrome\\\_131) \* 131 with PSK (chrome\\\_131\\\_PSK) 2. OkHttp4 \* Android 7 (okhttp4\\\_android\\\_7) \* Android 8 (okhttp4\\\_android\\\_8) \* Android 9 (okhttp4\\\_android\\\_9) \* Android 10 (okhttp4\\\_android\\\_10) \* Android 11 (okhttp4\\\_android\\\_11) \* Android 12 (okhttp4\\\_android\\\_12) \* Android 13 (okhttp4\\\_android\\\_13) 3. Custom Clients \* Zalando Android Mobile (zalando\\\_android\\\_mobile) \* Nike Android Mobile (nike\\\_android\\\_mobile) \* Mesh IOS 2 (mesh\\\_ios\\\_2) \* Mesh Android (mesh\\\_android or mesh\\\_android\\\_1) \* Mesh Android 2 (mesh\\\_android\\\_2) \* Confirmed Android (confirmed\\\_android) 4. Firefox \* 120 (firefox\\\_120) \* 123 (firefox\\\_123) \* 132 (firefox\\\_132) \* 133 (firefox\\\_133) \* 135 (firefox\\\_135) \* 146 with PSK (firefox\\\_146\\\_PSK) \* 147 (firefox\\\_147) \* 147 with PSK (firefox\\\_147\\\_PSK) \* 148 (firefox\\\_148) You can also provide your own client. See the examples how to do that. All Clients support Random TLS Extension Order by setting the option on the HTTP client itself \`WithRandomTLSExtensionOrder()\`.\\ This is needed for Chrome 107+. #### Shared Library & Standalone Api When working with the Shared Library or Standalone API you need to set \`"withRandomExtensionOrder":true\` --- # Unknown \# Open Source Oasis ## Open Source Oasis - \[TLS-Client\](https://bogdanfinn.gitbook.io/open-source-oasis/readme.md) - \[Supported and tested Client Profiles\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/supported-and-tested-client-profiles.md) - \[Installation & Quick Usage\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage.md) - \[Client Options\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options.md) - \[Cookiejar\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar.md) - \[Defaults\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults.md) - \[Request Headers\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/request-headers.md) - \[Pseudo Header Order\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order.md) - \[Proxies\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies.md) - \[Certificate Pinning\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning.md) - \[Response Body Encoding / Decoding\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding.md) - \[Custom Client Profile\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile.md) - \[WebSocket\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket.md) - \[Protocol Racing\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples.md) - \[Shared Library\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library.md) - \[Node Version\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version.md) - \[Downloads\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads.md) - \[Build from source\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source.md) - \[Exposed Methods\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods.md) - \[JavaScript\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples.md) - \[Python\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples.md) - \[TypeScript\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples.md) - \[C#\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples.md) - \[Defaults\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults.md) - \[Payload\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload.md) - \[Response\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response.md) - \[Memory Issues\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues.md) - \[Standalone API Application\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application.md) - \[Download\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/download.md) - \[Build from source\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/build-from-source.md) - \[Configuration & Start\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/configuration-and-start.md) - \[Endpoints\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints.md) - \[Defaults\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/defaults.md) - \[Attention\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/attention.md) - \[Payload\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/payload.md) - \[Response\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/response.md) - \[How to get support\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support.md) - \[Frequently Asked Questions / Errors\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors.md) - \[Community Support\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support.md) - \[Further Information\](https://bogdanfinn.gitbook.io/open-source-oasis/further-information.md) - \[Antibots & Captchas\](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas.md) - \[Proxies\](https://bogdanfinn.gitbook.io/open-source-oasis/proxies.md): For efficient web scparing it is mandatory to utilize good proxies. Here are a list of a few providers you could use. - \[Community Projects\](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects.md) - \[Contributing\](https://bogdanfinn.gitbook.io/open-source-oasis/contributing.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/pseudo-header-order.md). # Pseudo Header Order Pseudo headers are the following headers: \`":method"\`, \`":authority"\`, \`":scheme"\`, \`":path"\` and the order of them varies per client profile. Therefore you can define the order of the pseudo headers on the (custom-)client Profile. \`\`\`go pseudoHeaderOrder := \[\]string{ ":method", ":authority", ":scheme", ":path", } customClientProfile := tls\_client.NewClientProfile(tls.ClientHelloID{ Client: "MyCustomProfile", Version: "1", Seed: nil, SpecFactory: specFunc, }, settings, settingsOrder, pseudoHeaderOrder, connectionFlow, nil, nil) \`\`\` #### Shared Library & Standalone API You will see on the CustomClient object \[payload\](/open-source-oasis/shared-library/payload.md) that you can define the order as a list of strings. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/examples.md). # Examples Every example is one focused, standalone program under \`./example//\` in the repository, runnable with \`go run ./example/\` and meant to be copied from directly. ### Requests \* \[\`./example/basic\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/basic) - GET Request \* \[\`./example/post\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/post) - POST Request \* \[\`./example/headers\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/headers) - Custom Headers & \[Header Order\](/open-source-oasis/readme/request-headers.md) \* \[\`./example/cookies\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies) - \[Cookie Jar\](/open-source-oasis/readme/cookiejar.md) \* \[\`./example/redirects\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/redirects) - Switching the Redirect Following Behavior \* \[\`./example/download\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/download) - Downloading Image / Files \* \[\`./example/decompress\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress) - Manual \[Response Body Decompression\](/open-source-oasis/readme/response-body-encoding-decoding.md) ### Fingerprints \* \[\`./example/custom\_profile\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_profile) - \[Custom Client Profile\](/open-source-oasis/readme/custom-client-profile.md) from a JA3 string, including the \`trust\_anchors\` payload \* \[\`./example/custom\_spec\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_spec) - Hand built \`ClientHelloSpec\` for extensions a JA3 string cannot express (PSK, ALPS) \* \[\`./example/session\_tickets\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/session\_tickets) - Disabling TLS Session Tickets ### Connection \* \[\`./example/proxy\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy) - \[Proxy\](/open-source-oasis/readme/proxies.md) & Proxy Rotation \* \[\`./example/protocol\_racing\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol\_racing) - \[Protocol Racing\](/open-source-oasis/readme/protocol-racing.md) (HTTP/3 vs HTTP/2) and its SOCKS5 requirement \* \[\`./example/websocket\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket) - \[WebSocket\](/open-source-oasis/readme/websocket.md) with the client's TLS fingerprint \* \[\`./example/certificate\_pinning\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate\_pinning) - \[Certificate Pinning\](/open-source-oasis/readme/certificate-pinning.md) ### Concurrency \* \[\`./example/concurrency\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/concurrency) - One client shared by many goroutines, decoding every response, with heap statistics and an optional pprof heap profile \* \[\`./example/client\_per\_worker\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/client\_per\_worker) - The same setup with a client per worker instead of a shared one, counting the dials that a shared client would have avoided \* \[\`./example/connection\_reuse\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/connection\_reuse) - Verifies that one TCP connection is reused across requests, counting dials and cross-checking with \`httptrace\` ### Observability \* \[\`./example/bandwidth\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/bandwidth) - Bandwidth Tracking \* \[\`./example/hooks\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/hooks) - Pre-Request & Post-Response Hooks For the shared library and the standalone API the same topics are covered per language under \`cffi\_dist/\`, see the \[JavaScript\](/open-source-oasis/shared-library/javascript/examples.md), \[Python\](/open-source-oasis/shared-library/python/examples.md), \[TypeScript\](/open-source-oasis/shared-library/typescript/examples.md) and \[C#\](/open-source-oasis/shared-library/c/examples.md) example pages. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options.md). # Client Options When instantiating the TLS client you can define various options which are documented here: \* WithClientProfile \`\`\` WithClientProfile configures a TLS client to use the specified client profile. \`\`\` \* WithForceHttp1 \`\`\` WithForceHttp1 configures a client to force HTTP/1.1 as the used protocol. \`\`\` \* WithDisableHttp3 \`\`\` WithDisableHttp3 configures a client to disable HTTP 3 as the used protocol. Will most likely fall back to HTTP 2 \`\`\` \* WithDisableSessionTickets \`\`\` WithDisableSessionTickets configures a client to disable TLS session ticket caching and resumption. \`\`\` Session resumption is only used by profiles that support it (those sending a PSK extension). For those, the client keeps a session cache and can resume a TLS session instead of doing a full handshake. Disable it if you want every connection to perform a full handshake. \* WithInsecureSkipVerify \`\`\` WithInsecureSkipVerify configures a client to skip SSL certificate verification. \`\`\` \* WithTransportOptions \`\`\` WithTransportOptions configures a client to use the specified transport options. \`\`\` The \`TransportOptions\` struct supports the following fields for client certificate authentication: \`\`\`go tls\_client.WithTransportOptions(&tls\_client.TransportOptions{ // Certificates is a list of client TLS certificates for mutual TLS (mTLS). // Load certificates with tls.LoadX509KeyPair or tls.X509KeyPair. Certificates: \[\]tls.Certificate{clientCert}, }) \`\`\` \* WithProxyUrl \`\`\` WithProxyUrl configures a HTTP client to use the specified proxy URL. proxyUrl should be formatted as: "http://user:pass@host:port" \`\`\` HTTP, HTTPS, SOCKS4 and SOCKS5 proxies are supported. If you also enable \`WithProtocolRacing()\` the proxy has to be a \`socks5://\` or \`socks5h://\` proxy, because HTTP/3 runs over UDP and only SOCKS5 can tunnel it (via UDP ASSOCIATE). Any other scheme is rejected with an error. See \[Protocol Racing\](/open-source-oasis/readme/protocol-racing.md). \* WithCharlesProxy \`\`\` WithCharlesProxy configures the HTTP client to use a local running charles as proxy. host and port can be empty, then default 127.0.0.1 and port 8888 will be used \`\`\` \* WithCookieJar \`\`\` WithCookieJar configures a HTTP client to use the specified cookie jar. \`\`\` \* WithServerNameOverwrite \`\`\` WithServerNameOverwrite configures a TLS client to overwrite the server name being used for certificate verification and in the client hello. This option does only work properly if WithInsecureSkipVerify is set to true in addition \`\`\` \* WithTimeoutMilliseconds \`\`\` WithTimeoutMilliseconds configures a hard deadline for the entire request lifecycle. This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data. - Use 0 to disable the deadline (unlimited) for large downloads or long-polling. - Default is 30000 milliseconds (30 seconds). \`\`\` \* WithTimeoutSeconds \`\`\` WithTimeoutSeconds configures a hard deadline for the entire request lifecycle. This includes connection time, redirects, and reading the response body. WARNING: If the timer expires, the connection is forcibly closed, even if you are actively downloading data. - Use 0 to disable the deadline (unlimited) for large downloads or long-polling. - Default is 30 seconds. \`\`\` \* WithTimeout \`\`\` WithTimeout configures an HTTP client to use the specified request timeout. timeout is the request timeout in seconds. Deprecated: use either WithTimeoutSeconds or WithTimeoutMilliseconds \`\`\` \* WithNotFollowRedirects \`\`\` WithNotFollowRedirects configures an HTTP client to not follow HTTP redirects. \`\`\` \* WithCustomRedirectFunc \`\`\` WithCustomRedirectFunc configures an HTTP client to use a custom redirect func. The redirect func have to look like that: func(req \*http.Request, via \[\]\*http.Request) error Please only provide a custom redirect function if you know what you are doing. Check docs on net/http.Client CheckRedirect \`\`\` \* WithRandomTLSExtensionOrder \`\`\` WithRandomTLSExtensionOrder configures a TLS client to randomize the order of TLS extensions being sent in the ClientHello. Placement of GREASE and padding is fixed and will not be affected by this. \`\`\` \* WithCertificatePinning \`\`\` WithCertificatePinning enables SSL Pinning for the client and will throw an error if the SSL Pin is not matched. Please refer to https://github.com/tam7t/hpkp/#examples in order to see how to generate pins. The certificatePins are a map with the host as key. You can provide a BadPinHandlerFunc or nil as second argument. This function will be executed once a bad ssl pin is detected. \`\`\` \* WithDebug \`\`\` WithDebug configures a client to log debugging information. \`\`\` \* WithLocalAddr \`\`\` WithLocalAddr configures an HTTP client to use the specified local address. \`\`\` \* WithDisableIPV4 \`\`\` WithDisableIPV4 configures a dialer to use tcp6 network argument \`\`\` \* WithDisableIPV6 \`\`\` WithDisableIPV6 configures a dialer to use tcp4 network argument \`\`\` \* WithCatchPanics \`\`\` WithCatchPanics configures a client to catch all go panics happening during a request and not print the stacktrace. \`\`\` \* WithDefaultHeaders \`\`\` WithDefaultHeaders configures a client to use a set of default headers if none are specified on the request. \`\`\` \* WithConnectHeaders \`\`\` WithConnectHeaders configures a client to use the specified headers for the CONNECT request \`\`\` \* WithProtocolRacing \`\`\` WithProtocolRacing configures a client to race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel. Similar to Chrome's "Happy Eyeballs" approach, this starts both connection types simultaneously and uses whichever connects first. The client will remember which protocol worked for each host and use it directly on subsequent requests. This option is ignored if WithForceHttp1 or WithDisableHttp3 is set. \`\`\` When combined with a proxy, the proxy has to be a \`socks5://\` or \`socks5h://\` proxy that supports UDP ASSOCIATE. Any other proxy scheme is rejected with an error, because it could only carry the HTTP/2 leg and would let the HTTP/3 leg bypass the proxy. \* WithBandwidthTracker \`\`\` WithBandwidthTracker configures a client to track the bandwidth used by the client. You can retrieve the tracker via GetBandwidthTracker() and call GetTotalBandwidth(), GetWriteBytes(), GetReadBytes() or Reset() on it. \`\`\` \* WithDialer \`\`\` WithDialer configures an HTTP client to use the specified dialer. This allows the use of a custom DNS resolver. \`\`\` \* WithProxyDialerFactory \`\`\` WithProxyDialerFactory configures an HTTP client to use a custom proxyDialerFactory instead of the default newConnectDialer(). This allows to implement custom proxy dialer use cases. \`\`\` \* WithDialContext \`\`\` WithDialContext sets a custom dialer for TCP connections, allowing advanced networking (Zero-DNS, socket tagging, DPI bypass). WARNING: This overrides built-in proxy settings. If you need a proxy, you must handle the CONNECT handshake manually. \`\`\` Example: \`\`\`go client, err := tls\_client.NewHttpClient( tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithDialContext(func(ctx context.Context, network, addr string) (net.Conn, error) { // Custom dialing logic here return net.Dial(network, addr) }), ) \`\`\` \* WithPreHook \`\`\` WithPreHook adds a pre-request hook that is called before each request is sent. Multiple hooks can be added and they will be executed in the order they were added. If any hook returns an error, the request is aborted and subsequent hooks are not called. To continue hook execution despite an error, wrap your error with ErrContinueHooks. \`\`\` The hook function signature is: \`\`\`go type PreRequestHookFunc func(req \*http.Request) error \`\`\` Example: \`\`\`go client, err := tls\_client.NewHttpClient( tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithPreHook(func(req \*http.Request) error { req.Header.Set("X-Custom-Header", "my-value") return nil }), ) \`\`\` You can also add hooks at runtime using \`client.AddPreRequestHook(hook)\`. \* WithPostHook \`\`\` WithPostHook adds a post-response hook that is called after each request completes. Multiple hooks can be added and they will be executed in the order they were added. Hooks receive a PostResponseContext containing the request, response, and any error that occurred. If a hook returns an error, subsequent hooks are not called (unless wrapped with ErrContinueHooks). \`\`\` The hook function signature and context struct are: \`\`\`go type PostResponseContext struct { Request \*http.Request Response \*http.Response Error error // Non-nil if request failed } type PostResponseHookFunc func(ctx \*PostResponseContext) error \`\`\` Example: \`\`\`go client, err := tls\_client.NewHttpClient( tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithPostHook(func(ctx \*tls\_client.PostResponseContext) error { if ctx.Error != nil { log.Printf("Request failed: %v", ctx.Error) } else { log.Printf("Response status: %d", ctx.Response.StatusCode) } return nil }), ) \`\`\` You can also add hooks at runtime using \`client.AddPostResponseHook(hook)\`. \* ErrContinueHooks \`\`\` ErrContinueHooks can be returned (or wrapped) by a hook function to signal that the error should be logged but hook execution should continue to the next hook. By default any error returned from a hook aborts subsequent hooks (and for pre-hooks, the request). \`\`\` Example: \`\`\`go tls\_client.WithPreHook(func(req \*http.Request) error { // This error will be logged but subsequent hooks and the request will continue return fmt.Errorf("something went wrong: %w", tls\_client.ErrContinueHooks) }) \`\`\` #### Examples Several of the options above have a runnable example of their own: | Option | Example | | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | \`WithProtocolRacing\` | \[\`./example/protocol\_racing\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol\_racing) | | \`WithDisableSessionTickets\` | \[\`./example/session\_tickets\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/session\_tickets) | | \`WithBandwidthTracker\` | \[\`./example/bandwidth\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/bandwidth) | | \`WithPreHook\` / \`WithPostHook\` / \`ErrContinueHooks\` | \[\`./example/hooks\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/hooks) | | \`WithCertificatePinning\` | \[\`./example/certificate\_pinning\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate\_pinning) | | \`WithClientProfile\` | \[\`./example/custom\_profile\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_profile), \[\`./example/custom\_spec\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_spec) | | \`WithProxyUrl\` | \[\`./example/proxy\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy) | | \`WithNotFollowRedirects\` | \[\`./example/redirects\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/redirects) | | \`WithCookieJar\` | \[\`./example/cookies\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies) | | \`WithTransportOptions\` | \[\`./example/concurrency\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/concurrency) | | \`WithForceHttp1\` | \[\`./example/websocket\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket), \[\`./example/decompress\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress) | The full list is on the \[Examples\](/open-source-oasis/readme/examples.md) page. #### Shared Library & Standalone API When using the shared library or standalone api you can find almost every client option as a separate field to turn on / turn off or configure in the request payload. Please take a look at the Documentation about the \[Payload\](/open-source-oasis/shared-library/payload.md). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/cookiejar.md). # Cookiejar Since version 1.0.0 the TLS-Client uses the custom cookiejar implemented which can be found here: \\ Before it was more or less golangs default cookiejar: The custom cookiejar is designed for some specific (sneaker)botting related use cases when it comes to cookie overwriting or sharing cookies across different TLD. Often these use cases were about overwriting exisiting cookies in the jar with newer values or something like that. When using the TLS-Client in go you can easilly switch between both jars just by instantiating the specific cookiejar you need: #### Default Go Cookiejar \`\`\` jar, \_ := cookiejar.New(nil) options := \[\]tls\_client.HttpClientOption{ tls\_client.WithCookieJar(jar), } client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), options...) \`\`\` #### Custom Cookiejar \`\`\` jar := tls\_client.NewCookieJar() options := \[\]tls\_client.HttpClientOption{ tls\_client.WithCookieJar(jar), } client, err := tls\_client.NewHttpClient(logger, options...) \`\`\` #### Shared Library & Standalone API If you are using the shared library or standalone api you can either completely deactiavte cookie jar handling by setting \`"withoutCookieJar"\` to \`true\` or you can switch to the default Go cookiejar by setting \`"withDefaultCookieJar"\` to \`true\`. By default the Custom Cookiejar will always be used. ### Example A runnable version is in \[\`./example/cookies\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/cookies). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/defaults.md). # Defaults If you call \`ProvideDefaultClient()\` you will receive a TLS-Client instance with the following settings \* 30 seconds timeout \* Chrome 150 as profile \* Random TLS Extension order enabled \* Follow Redirects disabled \* Idle Connections will be closed after 90 seconds --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding.md). # Response Body Encoding / Decoding If you are specifying \`accept-encoding\` header yourself and you are on a \`http1\` connection than you have to take care of the response body decompression yourself. It is not done automatically. Only if you are \*\*not\*\* adding \`accept-encoding\` header then the library adds it for you if not explicit disabled and also handles the decompression automatically. On \`http2\` the automatic decompression should always be in place according to the \`content-type\` Header on the Response. \`DecompressBody\` is an exported function you can use. See the following example on how do decompress the response body manually \`\`\`go req, err := http.NewRequest(http.MethodGet, "https://tls.browserleaks.com/json", nil) if err != nil { log.Println(err) goreturn } req.Header = http.Header{ "accept": {"\*/\*"}, "accept-encoding": {"gzip"}, "accept-language": {"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"}, "user-agent": {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_15\_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"}, http.HeaderOrderKey: { "accept", "accept-encoding", "accept-language", "user-agent", }, } resp, err := client.Do(req) if err != nil { log.Println(err) return } defer resp.Body.Close() decomBody := http.DecompressBody(resp) all, err := ioutil.ReadAll(decomBody) if err != nil { log.Println(err) return } log.Println(string(all)) \`\`\` It is possible to disable the automatic decompression on http2 by adding the following option to the http client \`\`\`go tls\_client.WithTransportOptions(&tls\_client.TransportOptions{ DisableCompression: true, }), \`\`\` #### Automatic Charset Detection When using the shared library or standalone API, the response body charset is automatically detected and decoded based on the \`Content-Type\` response header (e.g. \`charset=euc-kr\`, \`charset=shift\_jis\`, etc.). This means you no longer need to handle specific encodings manually — the correct character encoding is applied automatically for all text responses. This behavior is active whenever \`isByteResponse\` is \`false\` (the default). If you need the raw bytes, set \`isByteResponse: true\`. #### Shared Library & Standalone API When you are using the shared library or standalone api application the response body will always be decompressed and the charset will be automatically detected and decoded. ### Example A runnable version is in \[\`./example/decompress\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/decompress). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/certificate-pinning.md). # Certificate Pinning You can enable certificate pinning for a TLS-Client instance. You need to provide a map of pins by host when you create the client. See the example code below \`\`\` pins := map\[string\]\[\]string{ "bstn.com": { "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=", "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=", "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=", }, } options := \[\]tls\_client.HttpClientOption{ tls\_client.WithCertificatePinning(pins, tls\_client.DefaultBadPinHandler), } client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), options...) \`\`\` This example code shows how to enabled certificate pinning for bstn.com. Next to it you can supply a BadPinHandler function as second argument for the WithCertificatePinning option. The default BadPinHandler looks like this. This function will be executed when a bad pin is detected: \`\`\` var DefaultBadPinHandler = func(req \*http.Request) { fmt.Println("this is the default bad pin handler") } \`\`\` #### Shared Library & Standalone API When using the shared library you can supply certificate pinning settings via the \`"certificatePinningHosts"\` field. This should look similar to this: \`\`\` "certificatePinningHosts": { "bstn.com": \[\ "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=",\ "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=",\ "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=",\ \], }, \`\`\` #### Wildcards You can define wildcards for subdomains for example like this \`\`\` pins := map\[string\]\[\]string{ "\*.bstn.com": { "NQvy9sFS99nBqk/nZCUF44hFhshrkvxqYtfrZq3i+Ww=", "4a6cPehI7OG6cuDZka5NDZ7FR8a60d3auda+sKfg4Ng=", "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4=", }, } options := \[\]tls\_client.HttpClientOption{ tls\_client.WithCertificatePinning(pins, tls\_client.DefaultBadPinHandler), } client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), options...) \`\`\` #### How to generate pins? You can easilly generate pins with this helpful tool: \\ Just install the tool and run the following command against the site you want to generate pins for: \`\`\` hpkp-pins -server=bstn.com:443 \`\`\` ### Example A runnable version is in \[\`./example/certificate\_pinning\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/certificate\_pinning). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/custom-client-profile.md). # Custom Client Profile \*\*You should know at least a bit about TLS Fingerprints in order to know what you are doing here and what is minimum required.\*\* You can build complete custom clients which consist of different things. When we look at the factory method we see that you need to provide the following information: \* A clientHelloId which holds the \`ClientHelloSpecFactory\`. More about that later. \* A key value map of http2 settings \* A list of http2 settings for the order \* A list of \[pseudo headers\](/open-source-oasis/readme/pseudo-header-order.md) for the order \* A value for the connection flow \* A slice of http2 priority settings \* A optional header priority setting \* A stream id and whether plain \`http://\` is allowed \* The http3 counterparts: a settings map, their order, the priority param, the pseudo header order and whether to send GREASE frames The last two groups can be left at their zero values (\`0\`, \`false\`, \`nil\`). A profile without http3 settings simply has no HTTP/3 fingerprint, which only matters once the client actually speaks HTTP/3 - see \[Protocol Racing\](/open-source-oasis/readme/protocol-racing.md). \`\`\`go func NewClientProfile(clientHelloId tls.ClientHelloID, settings map\[http2.SettingID\]uint32, settingsOrder \[\]http2.SettingID, pseudoHeaderOrder \[\]string, connectionFlow uint32, priorities \[\]http2.Priority, headerPriority \*http2.PriorityParam, streamID uint32, allowHTTP bool, http3Settings map\[uint64\]uint64, http3SettingsOrder \[\]uint64, http3PriorityParam uint32, http3PseudoHeaderOrder \[\]string, http3SendGreaseFrames bool) ClientProfile { return ClientProfile{ clientHelloId: clientHelloId, settings: settings, settingsOrder: settingsOrder, pseudoHeaderOrder: pseudoHeaderOrder, connectionFlow: connectionFlow, priorities: priorities, headerPriority: headerPriority, streamID: streamID, allowHTTP: allowHTTP, http3Settings: http3Settings, http3SettingsOrder: http3SettingsOrder, http3PriorityParam: http3PriorityParam, http3PseudoHeaderOrder: http3PseudoHeaderOrder, http3SendGreaseFrames: http3SendGreaseFrames, } } \`\`\` Note that \`NewClientProfile\` lives in the \`profiles\` package, so you call it as \`profiles.NewClientProfile(...)\`. You can create a \`ClientHelloSpecFactory\` out of a ja3 string by calling GetSpecFactoryFromJa3String. You need to provide in addition the following information, as these can't be derived from the ja3 string: \* A list of supported signature algorithms \* A list of supported delegated credentials algorithms \* A list of supported TLS versions \* A list of supported key share curves \* A list of certificate compression algorithms \* A value for the RecordSizeLimit Extension, as a \`uint16\` \* The payload for the trust\\\_anchors extension, if your ja3 string lists extension \`51764\` \`\`\`go ja3 := "771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-10-11-13-16-23-43-51-65281-45-21,29-23-24,0" ssa := \[\]string{"ECDSAWithP256AndSHA256", "PSSWithSHA256", "PKCS1WithSHA256", "ECDSAWithP384AndSHA384", "PSSWithSHA384", "PKCS1WithSHA384", "PSSWithSHA512", "PKCS1WithSHA512"} dca := \[\]string{"ECDSAWithP256AndSHA256", "PSSWithSHA256", "PKCS1WithSHA256", "ECDSAWithP384AndSHA384", "PSSWithSHA384", "PKCS1WithSHA384", "PSSWithSHA512", "PKCS1WithSHA512"} sv := \[\]string{"GREASE", "1.3", "1.2"} sc := \[\]string{"GREASE", "X25519"} alpnProtocols := \[\]string{"h2", "http/1.1"} alpsProtocols := \[\]string{"h2"} ccs := \[\]tls\_client.CandidateCipherSuites{ { KdfId: "HKDF\_SHA256", AeadId: "AEAD\_AES\_128\_GCM", }, { KdfId: "HKDF\_SHA256", AeadId: "AEAD\_CHACHA20\_POLY1305", }, } cp := \[\]uint16{128, 160, 192, 224} certCompressionAlgos := \[\]string{"zlib"} recordSizeLimit := uint16(0) trustAnchorsPayload := "" // hex payload, only needed if the ja3 string lists extension 51764 specFunc, err := tls\_client.GetSpecFactoryFromJa3String(ja3, ssa, dca, sv, sc, alpnProtocols, alpsProtocols, ccs, cp, certCompressionAlgos, recordSizeLimit, trustAnchorsPayload) \`\`\` Chrome 150 and later also advertise the ML-DSA codepoints, and Chrome 152 puts a GREASE value first, so a fingerprint imitating those versions needs \`"GREASE"\`, \`"MLDSA44"\`, \`"MLDSA65"\` or \`"MLDSA87"\` in the signature algorithm list. utls replaces the GREASE placeholder with a value drawn per connection, exactly as it does for the bundled profiles. #### The trust\\\_anchors extension (51764) Chromium sends the trust\\\_anchors extension from Chrome 144 on. A ja3 string names extension IDs but carries no extension data, so when your ja3 string contains \`51764\` the payload has to come alongside it as a hex string. Leaving it empty in that case fails with an error naming the parameter. Take the value from the \`data\` field of the \`Unknown extension 51764\` entry in a browser fingerprint; it already starts at the 16-bit list length. \`"0000"\` is an empty anchor list. Of the shipped profiles, \`chrome\_146\` and \`chrome\_146\_PSK\` send that empty list, while \`chrome\_152\` and \`chrome\_152\_PSK\` send a captured 186 byte payload of 28 anchor IDs. The other profiles do not send the extension at all. The IDs are reordered once per spec factory, because Chromium writes them in hash set iteration order, which holds for the life of a browser process and differs between processes. \`profiles.BuildTrustAnchorsPayload\` does that on its own if you build the extension by hand. At the end you can just build the complete custom profile by providing all the above mentioned information. \`\`\`go specFunc, err := tls\_client.GetSpecFactoryFromJa3String(ja3, ssa, dca, sv, sc, alpnProtocols, alpsProtocols, ccs, cp, certCompressionAlgos, recordSizeLimit, trustAnchorsPayload) if err != nil { log.Println(err.Error()) return } settings := map\[http2.SettingID\]uint32{ http2.SettingHeaderTableSize: 65536, http2.SettingMaxConcurrentStreams: 1000, http2.SettingInitialWindowSize: 6291456, http2.SettingMaxHeaderListSize: 262144, } settingsOrder := \[\]http2.SettingID{ http2.SettingHeaderTableSize, http2.SettingMaxConcurrentStreams, http2.SettingInitialWindowSize, http2.SettingMaxHeaderListSize, } pseudoHeaderOrder := \[\]string{ ":method", ":authority", ":scheme", ":path", } connectionFlow := uint32(15663105) customClientProfile := profiles.NewClientProfile(tls.ClientHelloID{ Client: "MyCustomProfile", Version: "1", Seed: nil, SpecFactory: specFunc, }, settings, settingsOrder, pseudoHeaderOrder, connectionFlow, nil, // priorities nil, // headerPriority 0, // streamID false, // allowHTTP nil, // http3Settings nil, // http3SettingsOrder 0, // http3PriorityParam nil, // http3PseudoHeaderOrder false, // http3SendGreaseFrames ) client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(customClientProfile)) if err != nil { log.Println(err.Error()) return } \`\`\` #### Shared Library & Standalone API It is also possible to define custom client profiles when working with the shared library or the standalone api. For that you are not calling functions but provide all the information on the request payload that the TLS client is able to build the client profile out of it. Instead of the \`"tlsClientIdentifier"\` you can provide on the request payload the \`"customTlsClient"\`. Only \`"ja3String"\` is really required; every other field falls back to a zero value. The setting names in \`"h2Settings"\` / \`"h2SettingsOrder"\` and \`"h3Settings"\` / \`"h3SettingsOrder"\` have to be spelled as below, unknown names are ignored. \`\`\`json { "customTlsClient": { "ja3String": "771,2570-4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,2570-0-23-65281-10-11-35-16-5-13-18-51-45-43-27-17513-2570-21,2570-29-23-24,0", "trustAnchorsPayload": "", "h2Settings": { "HEADER\_TABLE\_SIZE": 65536, "MAX\_CONCURRENT\_STREAMS": 1000, "INITIAL\_WINDOW\_SIZE": 6291456, "MAX\_HEADER\_LIST\_SIZE": 262144 }, "h2SettingsOrder": \[\ "HEADER\_TABLE\_SIZE",\ "MAX\_CONCURRENT\_STREAMS",\ "INITIAL\_WINDOW\_SIZE",\ "MAX\_HEADER\_LIST\_SIZE"\ \], "supportedSignatureAlgorithms": \[\ "ECDSAWithP256AndSHA256",\ "PSSWithSHA256",\ "PKCS1WithSHA256",\ "ECDSAWithP384AndSHA384",\ "PSSWithSHA384",\ "PKCS1WithSHA384",\ "PSSWithSHA512",\ "PKCS1WithSHA512"\ \], "supportedDelegatedCredentialsAlgorithms": \[\], "supportedVersions": \["GREASE", "1.3", "1.2"\], "keyShareCurves": \["GREASE", "X25519"\], "alpnProtocols": \["h2", "http/1.1"\], "alpsProtocols": \["h2"\], "certCompressionAlgos": \["brotli"\], "recordSizeLimit": 0, "ECHCandidatePayloads": \[\], "ECHCandidateCipherSuites": \[\], "pseudoHeaderOrder": \[\ ":method",\ ":authority",\ ":scheme",\ ":path"\ \], "connectionFlow": 15663105, "streamId": 0, "allowHttp": false, "priorityFrames": \[\ {\ "streamID": 1,\ "priorityParam": {\ "streamDep": 1,\ "exclusive": true,\ "weight": 1\ }\ }\ \], "headerPriority": { "streamDep": 1, "exclusive": true, "weight": 1 }, "h3Settings": { "QPACK\_MAX\_TABLE\_CAPACITY": 65536, "MAX\_FIELD\_SECTION\_SIZE": 262144, "QPACK\_BLOCKED\_STREAMS": 100, "H3\_DATAGRAM": 1 }, "h3SettingsOrder": \[\ "QPACK\_MAX\_TABLE\_CAPACITY",\ "MAX\_FIELD\_SECTION\_SIZE",\ "QPACK\_BLOCKED\_STREAMS",\ "H3\_DATAGRAM"\ \], "h3PseudoHeaderOrder": \[\ ":method",\ ":authority",\ ":scheme",\ ":path"\ \], "h3PriorityParam": 984832, "h3SendGreaseFrames": true } } \`\`\` #### Examples \* \[\`./example/custom\_profile\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_profile) builds the profile from a JA3 string, including the \`trust\_anchors\` payload and the ML-DSA / GREASE signature algorithms Chrome 150 and later send. \* \[\`./example/custom\_spec\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/custom\_spec) builds the \`tls.ClientHelloSpec\` by hand, which is the way to go when an extension needs data a JA3 string cannot carry - PSK and ALPS, for instance. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library.md). # Shared Library - \[Node Version\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version.md) - \[Downloads\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads.md) - \[Build from source\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source.md) - \[Exposed Methods\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods.md) - \[JavaScript\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples.md) - \[Python\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples.md) - \[TypeScript\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples.md) - \[C#\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c.md) - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples.md) - \[Defaults\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults.md) - \[Payload\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload.md) - \[Response\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response.md) - \[Memory Issues\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/installation-and-quick-usage.md). # Installation & Quick Usage ## Installation \`\`\`go go get -u github.com/bogdanfinn/tls-client // or specific version: // go get github.com/bogdanfinn/tls-client@v1.7.2 \`\`\` Some users have trouble when using \`go get -u\`. If this is the case for you please cleanup your go.mod file and do a \`go get\` with a specific version like described above in the commented out code. I would recommend to check the Github tags for the latest version and install that one explicit. ## Quick Usage Example \`\`\`go package main import ( "fmt" "io" "log" http "github.com/bogdanfinn/fhttp" "github.com/bogdanfinn/tls-client/profiles" tls\_client "github.com/bogdanfinn/tls-client" ) func main() { jar := tls\_client.NewCookieJar() options := \[\]tls\_client.HttpClientOption{ tls\_client.WithTimeoutSeconds(30), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithNotFollowRedirects(), tls\_client.WithCookieJar(jar), // create cookieJar instance and pass it as argument //tls\_client.WithProxyUrl("http://user:pass@host:port"), //tls\_client.WithInsecureSkipVerify(), } client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), options...) if err != nil { log.Println(err) return } req, err := http.NewRequest(http.MethodGet, "https://tls.peet.ws/api/all", nil) if err != nil { log.Println(err) return } req.Header = http.Header{ "accept": {"\*/\*"}, "accept-language": {"de-DE,de;q=0.9,en-US;q=0.8,en;q=0.7"}, "user-agent": {"Mozilla/5.0 (Macintosh; Intel Mac OS X 10\_15\_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36"}, http.HeaderOrderKey: { "accept", "accept-language", "user-agent", }, } resp, err := client.Do(req) if err != nil { log.Println(err) return } defer resp.Body.Close() log.Println(fmt.Sprintf("status code: %d", resp.StatusCode)) readBytes, err := io.ReadAll(resp.Body) if err != nil { log.Println(err) return } log.Println(string(readBytes)) } \`\`\` For more configured clients check this documentation or use your own custom client. See provided examples how to use a complete custom TLS client. --- # Memory Issues | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues.md) . #### Go TLS Client & Standalone API[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues#go-tls-client-and-standalone-api) For the pure go implementation there is no real possibility to run into memory leak issues, except of the fact that you implemented your request handling badly and the references to your objects are never really freed that the go garbage collection can not clean up the used memory. If you are running into memory leak issues with the Go client or the standalone api please double check your request handling in order so see if you are doing things not as recommended (for example not closing or deferred closing the response body inside an infinite loop) #### Shared Library[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues#shared-library) If you are using the shared library there is potential to run into memory leak issues. Luckily you can avoid that by following a couple simple steps. By design there is memory allocated for every response coming from the go implementation (shared library) to the invoking application (python, node, etc.). The caller has to free the memory when he is done with handling the response. otherwise the memory will never be freed and you run into memory issues. On every response from the shared library you will see an `"id"` property. You can pass the value from the `"id"` field as parameter to the `freeMemory()` call of the shared library. Copy const response = tlsClientLibrary.request(JSON.stringify(requestPayload)); const responseObject = JSON.parse(response) tlsClientLibrary.freeMemory(responseObject.id) // free memory Copy response = request(dumps(request_payload).encode('utf-8')) response_bytes = ctypes.string_at(response) response_string = response_bytes.decode('utf-8') response_object = loads(response_string) freeMemory(response_object['id'].encode('utf-8')) [PreviousResponse](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response) [NextStandalone API Application](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application) Last updated 2 years ago --- # Standalone API Application | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application.md) . The standalone API Application can be found here: [https://github.com/bogdanfinn/tls-client-api](https://github.com/bogdanfinn/tls-client-api) This is an application which is using [gosoline](https://github.com/justtrackio/gosoline) and [TLS-Client](https://github.com/bogdanfinn/tls-client) to run a simple request forwarding service with the option to use specific TLS fingerprints which are implemented in [TLS-client](https://github.com/bogdanfinn/tls-client) . [PreviousMemory Issues](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues) [NextDownload](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/download) Last updated 3 years ago --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/node-version.md). # Node Version Some users experienced issues when using the shared library with NodeJS14 or lower. It is recommended to use at least NodeJS16. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript.md). # JavaScript - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/exposed-methods.md). # Exposed Methods The shared library exposes the following endpoints / methods you can call. The payload is always a JSON string expect for the \`freeMemory\` method. You will find the methods also in use in the examples. #### request(payload: string) => string This is the basic method you will use to do requests. For full detailed documentation about the payload please take a look at \[Payload\](/open-source-oasis/shared-library/payload.md). As you see here on other methods you have to turn the JSON Object into a JSON string before supplying it as the payload parameter. #### getCookiesFromSession(payload: string) => string Get all cookies which are in the provided session for a given URL. The payload should look like this: \`\`\`json "{\\"sessionId\\": \\"someExistingSessionId\\", \\"url\\": \\"urlToGetCookiesFor\\"}" \`\`\` #### addCookiesToSession(payload: string) => string Add manual cookies to an existing session. The payload should look like this: \`\`\`json "{\\"sessionId\\": \\"someExistingSessionId\\", \\"url\\": \\"urlToAddCookiesFor\\", \\"cookies\\": \[\]}" \`\`\` #### freeMemory(responseId: string) => void Supply the \`"id"\` of a previous response as string in order to free the allocated memory of the previous response. #### destroyAll() => string Destroy all existing sessions in order to release allocated memory. #### destroySession(payload: string) => string Destroy a specific session in order to release allocated memory. The payload should look like this: \`\`\`json "{\\"sessionId\\": \\"someExistingSessionId\\"}" \`\`\` --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/build-from-source.md). # Build from source When you want to build the shared libraries from source you can just run the following script: \`cffi\_dist/build.sh SOME\_BUILD\_IDENTIFIER\` and it should build the binaries for you. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/protocol-racing.md). # Protocol Racing Protocol Racing allows the TLS-Client to race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel, similar to Chrome's "Happy Eyeballs" approach. Both connection types are started simultaneously and whichever connects first is used. The client remembers which protocol worked for each host and uses it directly on subsequent requests. If the cached protocol fails, the client falls back to racing again. ### How it works 1. On the first request to a host, both HTTP/3 and HTTP/2 connections are started in parallel. 2. HTTP/2 is delayed by 300ms (same as Chrome) to give HTTP/3 a slight head start. 3. Whichever protocol succeeds first is used for the request. 4. The winning protocol is cached for the host and used directly on future requests. 5. If the cached protocol fails, the cache is cleared and racing restarts. ### Usage (Go) \`\`\`go client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithProtocolRacing(), ) \`\`\` ### Using Protocol Racing with a Proxy The HTTP/2 leg of the race runs over TCP, the HTTP/3 leg runs over QUIC, which is UDP. A proxy therefore has to be able to carry UDP, and of the supported proxy schemes only SOCKS5 can, through UDP ASSOCIATE. So when you combine protocol racing with a proxy, that proxy has to be a \`socks5://\` or \`socks5h://\` proxy \*\*and the proxy server has to support UDP ASSOCIATE\*\*. Not every SOCKS5 provider enables it. \`\`\`go client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithProtocolRacing(), tls\_client.WithProxyUrl("socks5://user:pass@host:port"), ) \`\`\` Any other proxy scheme is rejected with an error, both when the client is created and when you call \`SetProxy\` later. That is deliberate: an HTTP or SOCKS4 proxy can only carry the HTTP/2 leg, so the HTTP/3 leg would go out directly and expose your real IP address without any visible sign that it happened. If you have to use an HTTP proxy, disable protocol racing or HTTP/3: \`\`\`go client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithDisableHttp3(), tls\_client.WithProxyUrl("http://user:pass@host:port"), ) \`\`\` ### Configuration Constraints Protocol Racing cannot be used in combination with certain other options. The following configurations are invalid and will result in an error: \* \`WithProtocolRacing()\` + \`WithDisableHttp3()\` — Racing requires HTTP/3 to be enabled. \* \`WithProtocolRacing()\` + \`WithForceHttp1()\` — Racing requires HTTP/2 and HTTP/3. \* \`WithProtocolRacing()\` + a non-SOCKS5 proxy — Only SOCKS5 can tunnel the UDP traffic HTTP/3 needs. \* \`WithDisableIPV4()\` + \`WithDisableIPV6()\` — Cannot disable both IP versions. \* \`WithCertificatePinning()\` + \`WithInsecureSkipVerify()\` — Certificate pinning is incompatible with skipping verification. #### Shared Library & Standalone API When using the shared library or standalone API, set \`"withProtocolRacing": true\` in the request payload to enable protocol racing. The same configuration constraints apply, including the SOCKS5 requirement when a \`"proxyUrl"\` is set. ### Known Issues Two limitations apply to protocol racing as of version 1.16.0. Both only affect clients that actually use HTTP/3, so a client without protocol racing is unaffected. #### Most profiles have no HTTP/3 fingerprint Only five of the shipped profiles carry HTTP/3 settings: \`chrome\_144\`, \`chrome\_144\_PSK\`, \`firefox\_147\`, \`firefox\_147\_PSK\` and \`firefox\_148\`. Every other profile falls back to a minimal SETTINGS frame, so its HTTP/3 fingerprint does not resemble the browser it imitates: \`\`\` chrome\_144 1:65536;6:262144;7:100;51:1;GREASE|GREASE|984832|m,a,s,p chrome\_150 51:1|m,a,s,p chrome\_152 51:1|m,a,s,p firefox\_147 1:65536;7:20;727725890:0;16765559:1;51:1;8:1|GREASE|m,s,a,p \`\`\` The TLS and HTTP/2 fingerprints of those profiles are unaffected; this is only about the HTTP/3 SETTINGS frame, the GREASE setting and the priority parameter. If the HTTP/3 fingerprint matters for your target, use one of the five profiles above, or turn HTTP/3 off with \`WithDisableHttp3()\` so the request goes over HTTP/2 with a correct fingerprint. #### Data race between the two racing legs Both legs of a race are handed the same \`\*http.Request\`. The HTTP/3 transport writes to its header map while the HTTP/2 transport reads from it, which the Go race detector reports as a data race. It is unlikely to be observed on an occasional request but shows up reliably when many requests race at the same time, and a concurrent map access can crash the process. If you send a high volume of concurrent requests, prefer \`WithDisableHttp3()\` until this is fixed. ### Example A runnable version of everything above, including the rejected proxy schemes, is in \[\`./example/protocol\_racing\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol\_racing). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/downloads.md). # Downloads Here you can find the latest prebuilt shared library. Older versions before 1.3.8 can be found in the Github history of the repository: --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/websocket.md). # WebSocket The TLS-Client supports WebSocket connections with the same TLS fingerprinting as regular HTTP requests. This ensures consistent fingerprinting across both HTTP and WebSocket connections. \*\*Important:\*\* WebSocket connections require HTTP/1.1. You \*\*must\*\* use \`WithForceHttp1()\` when creating the HTTP client. ### Usage (Go) \`\`\`go // Create HTTP client with ForceHttp1 (required for WebSocket!) client, err := tls\_client.NewHttpClient(tls\_client.NewNoopLogger(), tls\_client.WithClientProfile(profiles.Chrome\_150), tls\_client.WithForceHttp1(), ) // Create WebSocket with optional header ordering headers := http.Header{ "User-Agent": {"MyBot/1.0"}, http.HeaderOrderKey: {"host", "upgrade", "connection", "user-agent"}, } ws, err := tls\_client.NewWebsocket(nil, tls\_client.WithUrl("wss://example.com/ws"), tls\_client.WithTlsClient(client), tls\_client.WithHeaders(headers), ) conn, err := ws.Connect(context.Background()) defer conn.Close() \`\`\` ### WebSocket Options \* WithUrl \`\`\` WithUrl sets the WebSocket URL to connect to. Required. \`\`\` \* WithTlsClient \`\`\` WithTlsClient sets the tls-client HttpClient to use for the WebSocket connection. The underlying dialer from this client will be used to establish the connection, preserving TLS fingerprinting and other client configurations. Required. \`\`\` \* WithHeaders \`\`\` WithHeaders sets the HTTP headers to send during the WebSocket handshake. You can use the http.HeaderOrderKey to control header ordering. \`\`\` \* WithReadBufferSize \`\`\` WithReadBufferSize sets the read buffer size for the WebSocket connection. \`\`\` \* WithWriteBufferSize \`\`\` WithWriteBufferSize sets the write buffer size for the WebSocket connection. \`\`\` \* WithHandshakeTimeoutMilliseconds \`\`\` WithHandshakeTimeoutMilliseconds sets the timeout for the WebSocket handshake in milliseconds. \`\`\` \* WithCookiejar \`\`\` WithCookiejar sets the cookie jar to use for the WebSocket connection. \`\`\` ### Example A runnable version is in \[\`./example/websocket\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/websocket). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/readme/proxies.md). # Proxies Proxies can be used by either setting them as client option \`WithProxyUrl\` when creating the TLS client or calling \`SetProxy\` on an exisiting client instance. A proxy should be formatted like this: \`http://username:password@host:port\` or \`socks5://username:password@host:port\` If you are using rotating Proxies (proxies with a static URL) then make sure to always call SetProxy with the same proxy again to let the client reconnect to the Proxy Server and receive a new IP-Address. ### Proxies and HTTP/3 HTTP/3 runs over QUIC, which is UDP. An HTTP or SOCKS4 proxy can only carry TCP, so it cannot tunnel HTTP/3 at all. Only SOCKS5 can, through UDP ASSOCIATE. That is why a client with \`WithProtocolRacing()\` enabled requires a \`socks5://\` or \`socks5h://\` proxy whose server supports UDP ASSOCIATE. Any other scheme is rejected with an error, both when creating the client and when calling \`SetProxy\`. Without that check the HTTP/2 leg would go through the proxy while the HTTP/3 leg went out directly and exposed your real IP address. Clients without protocol racing are unaffected and work with every supported proxy scheme. #### Shared Library & Standalone API When you are using the shared library or the standalone api you can supply a proxy in the \`"proxyUrl"\` field and set \`"isRotatingProxy"\` to \`true\` or \`false\`. ### Example A runnable version, including switching the proxy on an existing client, is in \[\`./example/proxy\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/proxy). For protocol racing over a proxy see \[Protocol Racing\](/open-source-oasis/readme/protocol-racing.md) and \[\`./example/protocol\_racing\`\](https://github.com/bogdanfinn/tls-client/tree/master/example/protocol\_racing). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/javascript/examples.md). # Examples Please take a look at the following NodeJS Code in the repository to see examples implemented: \`cffi\_dist/example\_node/\` We provide examples for the following use cases: \* GET Request \* POST Request \* Image Download \* Image Upload \* Async Request \* Custom Client \* Use Cookies \* Proxy Rotation \* Switching the Redirect Following Behavior \* Certificate Pinning \* Use ffi-rs instead of ffi-napi --- # Antibots & Captchas | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas.md) . The TLS-Client is just a tool to mimic specific client profiles. It does not solve / pass antibot solutions which have other "challenges" like a javascript challenge or require solving a captcha. Luckily for this there are various services on the market to help you. #### HyperSolutions[](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas#hypersolutions) Hyper Solutions offers proven solutions for handling Akamai, Incapsula, DataDome, Kasada, and Cloudflare antibot systems. Our request-based APIs generate tokens and sensor data instantly. No browsers, no complexity, just fast and reliable bypass solutions trusted by leading companies across industries. [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fhypersolutions.co%2Ffavicon.ico%3F0a7c94befe43e4fd&width=20&dpr=3&quality=100&sign=51fe1e2414c4e473a55a635f1e325b0b&sv=3)Bot Protection Bypass API | Hyper SolutionsHyper Solutions](https://hypersolutions.co/?utm_source=gitbook&utm_medium=sponsorship&utm_campaign=open_source_oasis) #### **ParallaxSystems**[](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas#parallaxsystems) ParallaxSystems offers the most reliable solutions for handling various AntiBot Systems, trusted by leading companies across industries. With years of expertise, we ensure seamless integration and fast results, including direct cookie returns for ultimate efficiency. [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fdiscord.com%2Fassets%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=631295bc07dcc57ce781edd8f7617f7b&sv=3)Join the ParallaxAPIs | Antibot's & solution's Discord Server!Discord](https://discord.gg/parallaxapis) #### Capsolver.com[](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas#capsolver.com) Capsolver‘s automatic captcha solver offers the most affordable and quick captcha-solving solution. You may rapidly combine it with your program using its simple integration option to achieve the best results in a matter of seconds. [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fwww.capsolver.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=0c084e9a3343c6b5220879ace1769221&sv=3)Capsolver: Fastest AI Captcha Solver, Auto Captcha Solving Servicewww.capsolver.com](https://www.capsolver.com/) #### Nstbrowser.io[](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas#nstbrowser.io) Nstbrowser is a powerful anti-detect browser designed for multi-accounting professionals to manage multiple accounts securely and efficiently. [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fwww.nstbrowser.io%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=bac973d9e5bfb053c669ed9c9bd23f31&sv=3)Nstbrowser - Advanced Anti-Detect Browser for Web Scraping and Multiple Accounts Managingwww.nstbrowser.io](https://www.nstbrowser.io/) #### Other services[](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas#other-services) [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fgeekflare.com%2Fwp-content%2Fuploads%2F2024%2F05%2Fcropped-geekflare-brand-favicon-192x192.png&width=20&dpr=3&quality=100&sign=2c269febefc374e0ab1ebab51b7df92e&sv=3)12 Best Captcha Solver APIs for Web Scraping and AutomationGeekflare](https://geekflare.com/captcha-solving-services-api/) [PreviousFurther Information](https://bogdanfinn.gitbook.io/open-source-oasis/further-information) [NextProxies](https://bogdanfinn.gitbook.io/open-source-oasis/proxies) Last updated 7 months ago --- # Download | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/download.md) . Here you can find the latest prebuilt binaries. Older versions before 1.3.8 can be found in the Github history of the repository: [https://github.com/bogdanfinn/tls-client-api/releases](https://github.com/bogdanfinn/tls-client-api/releases) There is a binary for linux, macos and windows. Just modify the `config.dist.yml` file next to the binary to your needs and start the application. [PreviousStandalone API Application](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application) [NextBuild from source](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/build-from-source) Last updated 3 years ago --- # Build from source | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/build-from-source.md) . When you want to build the application from source, make sure to also checkout this repository `https://github.com/Solem8s/gosoline` on the branch `tls-client-api` next to this project. Afterwards you can just run the following script: `cmd/tls-client-api/build.sh SOME_BUILD_IDENTIFIER` and it should build the binaries for you. [PreviousDownload](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/download) [NextConfiguration & Start](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/configuration-and-start) Last updated 3 years ago --- # Configuration & Start | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/configuration-and-start.md) . * Configure things like api port and authentication keys in the `cmd/tls-client-api/config.dist.yml` file. * The default endpoint is `http://127.0.0.1:8080/api/forward` * You need to set a `x-api-key` header with an auth key from the config file. This is for protecting the API when you host it on some server. Requests without the correct keys in the header will be rejected. [PreviousBuild from source](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/build-from-source) [NextEndpoints](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints) Last updated 3 years ago --- # Response | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response.md) . The Response of a call against the shared library looks like this Copy { "id": "some response identifier", "sessionId": "some reusable sessionId if provided on the request", "status": 200, "target": "the target url", "body": "The Response as string here or the error message", "headers": {}, "cookies": {}, "usedProtocol": "h2" } In case of an unexpected error the `"status"` will be 0 The `"id"` is necessary when you want to free the memory used to generate this response. Take a look at [Memory Issues](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues) . The `"sessionId"` can be reused to keep the cookies from the previous requests in this session. The `"status"` indicates the status code of the remote response. The `"body"` is the response body from the remote response. The `"headers"` are the headers returned from the remote response. The `"cookies"` are the cookies returned from the remote response. The `"usedProtocol"` indicates which protocol was used for the request (e.g. `"h2"`, `"HTTP/2.0"`, `"HTTP/1.1"`). [PreviousPayload](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) [NextMemory Issues](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues) Last updated 7 months ago --- # Payload | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload.md) . This page shows once the full possible request payload against the shared library, with all default values. #### Basic Request Input[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#basic-request-input) Copy { "catchPanics": false, "certificatePinningHosts": null, "customTlsClient": null, "transportOptions": null, "followRedirects": false, "forceHttp1": false, "disableHttp3": false, "disableSessionTickets": false, "withProtocolRacing": false, "headerOrder": null, "headers": null, "insecureSkipVerify": false, "isByteRequest": false, "isByteResponse": false, "isRotatingProxy": false, "proxyUrl": null, "requestBody": null, "requestCookies": null, "requestHostOverride": null, "defaultHeaders": null, "connectHeaders": null, "requestMethod": "", "requestUrl": "", "disableIPV6": false, "disableIPV4": false, "localAddress": null, "sessionId": null, "serverNameOverwrite": "", "streamOutputBlockSize": null, "streamOutputEOFSymbol": null, "streamOutputPath": null, "timeoutMilliseconds": 0, "timeoutSeconds": 0, "tlsClientIdentifier": "", "withDebug": false, "withCustomCookieJar": false, "withoutCookieJar": false, "withRandomTLSExtensionOrder": false } Field Type Description headers Map Headers to attach on the current request. defaultHeaders will be used when empty. defaultHeaders Map> Default Headers to be used when no request headers are specified. The default header order can be specified with the Key "Header-Order:" connectHeaders Map> Headers to be used during the CONNECT request. serverNameOverwrite string Lookup [Client Option](https://bogdanfinn.gitbook.io/open-source-oasis/readme/client-options) "WithServerNameOverwrite" * `sessionId` is optional. When not provided the API does not create a Session. On every forwarded request with a given sessionId you will receive the sessionId in the response to be able to reuse sessions (cookies). * Be aware that `insecureSkipVerify` and the `timeoutSeconds` can not be changed during a session. * `followRedirects` and `proxyUrl` can be changed within a session. * If you do not want to set `requestBody` or `proxyUrl` use `null` instead of empty string * When you set `isByteResponse` to `true` the response body will be a base64 encoded string. Useful when you want to download images for example. * When you set `isByteRequest` to `true` the request body needs to be a base64 encoded string. Useful when you want to upload images for example. * When you set `withProtocolRacing` to `true` the client will race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel, similar to Chrome's "Happy Eyeballs" approach. Cannot be used together with `forceHttp1` or `disableHttp3`. If you also set a `proxyUrl` it has to be a `socks5://` or `socks5h://` proxy that supports UDP ASSOCIATE, since only SOCKS5 can tunnel the UDP traffic HTTP/3 needs. Any other proxy scheme is rejected with an error. * When you set `disableSessionTickets` to `true` the client does not cache TLS session tickets and never resumes a TLS session, so every connection performs a full handshake. Only profiles that support session resumption (those sending a PSK extension) are affected. * When you set `withCustomCookieJar` to `true` a custom TLS-Client cookie jar will be used which is more suited for certain use cases. Otherwise the default Go cookie jar is used. The `supportedSignatureAlgorithms` list of a custom TLS client additionally accepts `MLDSA44`, `MLDSA65`, `MLDSA87` and `GREASE`, which the Chrome 150 and Chrome 152 profiles use. `GREASE` is replaced with a value drawn from the connection's seed, so it changes per connection just like the built in profiles. **trustAnchorsPayload** Chrome 144 and later send the trust\_anchors extension (`51764`). A ja3 string lists extension IDs but carries no extension data, so if your `ja3String` contains `51764` you have to supply its payload separately in `trustAnchorsPayload`, as a hex string. Leaving it empty while the ja3 string asks for the extension fails the request with an error naming this field. To get the value, open your fingerprint source in the browser you want to imitate, find the entry named `Unknown extension 51764` in the `tls.extensions` array and copy its `data` field whole. It already starts at the 16-bit list length. Copy { "ja3String": "771,...-51764,...", "trustAnchorsPayload": "00b80582df13020108839a648c9b2d010c08839a648c9b2d0107..." } Pass `"0000"` for an empty anchor list, which is what the Chrome 144 and Chrome 146 profiles send. The anchor IDs are put in a fresh order once per client, because Chromium writes them in hash set iteration order, which stays the same for the life of a browser process and differs between processes. So the bytes on the wire are a reordering of what you supply, not a copy of it. #### Custom TLS-Client[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#custom-tls-client) Copy { "certCompressionAlgos": [], "connectionFlow": 0, "h2Settings": null, "h2SettingsOrder": null, "h3Settings": null, "h3SettingsOrder": null, "h3PseudoHeaderOrder": null, "h3PriorityParam": 0, "h3SendGreaseFrames": false, "headerPriority": null, "ja3String": "", "trustAnchorsPayload": "", "keyShareCurves": null, "priorityFrames": null, "alpnProtocols": null, "alpsProtocols": null, "ECHCandidatePayloads": null, "ECHCandidateCipherSuites": null, "pseudoHeaderOrder": null, "supportedDelegatedCredentialsAlgorithms": null, "supportedSignatureAlgorithms": null, "supportedVersions": null, "recordSizeLimit": 0, "streamId": 0, "allowHttp": false } Field Type Description certCompressionAlgos Array See possible values at the end of this page connectionFlow integer h2Settings Map See possible values for the Map keys at the end of this page. h2SettingsOrder Array Array of string keys which are used in the h2Settings property but ordered. h3Settings Map HTTP/3 settings. See possible values for the Map keys at the end of this page. h3SettingsOrder Array Array of string keys which are used in the h3Settings property but ordered. h3PseudoHeaderOrder Array Pseudo header order for HTTP/3 requests. h3PriorityParam integer HTTP/3 priority parameter. h3SendGreaseFrames boolean Whether to send GREASE frames in HTTP/3. headerPriority PriorityParam See type definition below in next section ja3String string trustAnchorsPayload string Hex payload for the trust\_anchors extension (51764). Required if your ja3String lists that extension, since a ja3 string carries extension IDs but no extension data. See the note below. keyShareCurves Array See possible values at the end of this page priorityFrames Array See type definition below in next section alpnProtocols Array List of supported protocols for the ALPN Extension alpsProtocols Array List of supported protocols for the ALPS Extension ECHCandidatePayloads Array List of ECH Candidate Payloads ECHCandidateCipherSuites Array See type definition below in next section pseudoHeaderOrder Array See possible values at the end of this page supportedDelegatedCredentialsAlgorithms Array See possible values at the end of this page supportedSignatureAlgorithms Array See possible values at the end of this page supportedVersions Array See possible values at the end of this page recordSizeLimit integer TLS record size limit extension value streamId integer Initial HTTP/2 stream ID allowHttp boolean Allow plaintext HTTP connections #### TransportOptions[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#transportoptions) Copy { "disableKeepAlives": false, "disableCompression": false, "maxIdleConns": 0, "maxIdleConnsPerHost": 0, "maxConnsPerHost": 0, "maxResponseHeaderBytes": 0, "writeBufferSize": 0, "readBufferSize": 0, "idleConnTimeout": 0, } Field Type Description disableKeepAlives boolean disableCompression boolean disables (automatic) decompression behavor as documented [here](https://bogdanfinn.gitbook.io/open-source-oasis/readme/response-body-encoding-decoding) maxIdleConns integer maxIdleConnsPerHost integer maxConnsPerHost integer maxResponseHeaderBytes integer If zero, a default is used writeBufferSize integer If zero, a default (currently 4KB) is used readBufferSize integer If zero, a default (currently 4KB) is used idleConnTimeout integer Duration in Nano Seconds #### CandidateCipherSuite[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#candidateciphersuite) Copy { "kdfId": "", "aeadId": "", } Field Type Description kdfId string See possible values at the end of this page aeadId string See possible values at the end of this page #### PriorityParam[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#priorityparam) Copy { "streamDep": 0, "exclusive": false, "weight": 0 } Field Type Description streamDep integer exclusive boolean weight integer #### PriorityFrames[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#priorityframes) Copy { "streamID": 0, "priorityParam": null } Field Type Description streamId integer priorityParam PriorityParam See type in the section above #### Cookie Input[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#cookie-input) Copy { "domain": "", "expires": 0, "maxAge": 0, "name": "", "path": "", "value": "", "secure": false, "httpOnly": false } Field Type Description domain string expires integer Unix Timestamp maxAge integer Number of seconds the cookie is valid. name string path string value string secure boolean Whether the cookie should only be sent over HTTPS. httpOnly boolean Whether the cookie is inaccessible to client-side scripts. If both `Expires` and `Max-Age` are set, `Max-Age` has precedence. ### Values[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#values) Here you can find the allowed possible string values to supply for fields like `supportedDelegatedCredentialsAlgorithms`, `supportedSignatureAlgorithms`, `supportedVersions` and much more. #### H2Settings[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#h2settings) Copy "HEADER_TABLE_SIZE", "ENABLE_PUSH", "MAX_CONCURRENT_STREAMS", "INITIAL_WINDOW_SIZE", "MAX_FRAME_SIZE", "MAX_HEADER_LIST_SIZE", "UNKNOWN_SETTING_7", "UNKNOWN_SETTING_8", "UNKNOWN_SETTING_9", #### H3Settings[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#h3settings) Copy "QPACK_MAX_TABLE_CAPACITY", "MAX_FIELD_SECTION_SIZE", "QPACK_BLOCKED_STREAMS", "H3_DATAGRAM", #### Supported Versions[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#supported-versions) Copy "GREASE", "1.3", "1.2", "1.1", "1.0", #### Supported Signature Algorithms[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#supported-signature-algorithms) Copy "PKCS1WithSHA256", "PKCS1WithSHA384", "PKCS1WithSHA512", "PSSWithSHA256", "PSSWithSHA384", "PSSWithSHA512", "ECDSAWithP256AndSHA256", "ECDSAWithP384AndSHA384", "ECDSAWithP521AndSHA512", "PKCS1WithSHA1", "ECDSAWithSHA1", "Ed25519", "SHA224_RSA", "SHA224_ECDSA", "MLDSA44", "MLDSA65", "MLDSA87", "GREASE", `MLDSA44`, `MLDSA65` and `MLDSA87` are the post quantum codepoints Chrome 150 and later advertise. `GREASE` is replaced with a value drawn from the connection's seed, so it differs per connection, the way Chrome 152 sends it. Both are only available for `supportedSignatureAlgorithms`, not for `supportedDelegatedCredentialsAlgorithms`. #### certCompressionAlgorithm[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#certcompressionalgorithm) Copy "zlib", "brotli", "zstd", #### Supported delegated credentials[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#supported-delegated-credentials) Copy "PKCS1WithSHA256", "PKCS1WithSHA384", "PKCS1WithSHA512", "PSSWithSHA256", "PSSWithSHA384", "PSSWithSHA512", "ECDSAWithP256AndSHA256", "ECDSAWithP384AndSHA384", "ECDSAWithP521AndSHA512", "PKCS1WithSHA1", "ECDSAWithSHA1", "Ed25519", "SHA224_RSA", "SHA224_ECDSA" #### KeyShareCurves[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#keysharecurves) Copy "GREASE", "P256", "P384", "P521", "X25519", "P256Kyber768", "X25519Kyber512D", "X25519Kyber768", "X25519Kyber768Old", "X25519MLKEM768", #### kdfIds[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#kdfids) Copy "HKDF_SHA256", "HKDF_SHA384", "HKDF_SHA512", #### aeadIds[](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload#aeadids) Copy "AEAD_AES_128_GCM", "AEAD_AES_256_GCM", "AEAD_CHACHA20_POLY1305", [PreviousDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults) [NextResponse](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response) Last updated 2 days ago --- # Endpoints | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints.md) . You need to do a POST Request against the running API with the following JSON Request Body. #### Forward Request `/api/forward`[](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints#forward-request-api-forward) Copy curl --location --request POST '127.0.0.1:8080/api/forward' \ --header 'x-api-key: my-auth-key-1' \ --header 'Content-Type: application/json' \ --data-raw '{ "tlsClientIdentifier": "chrome_150", "requestUrl": "https://tls.peet.ws/api/all", "requestMethod": "GET" }' #### Get Cookies from Session `/api/cookies`[](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints#get-cookies-from-session-api-cookies) Copy curl --location --request POST '127.0.0.1:8080/api/cookies' \ --header 'x-api-key: my-auth-key-1' \ --header 'Content-Type: application/json' \ --data-raw '{ "sessionId":"my-custom-sessionid", "url":"http://some-url.com" }' #### Free Single Session `/api/free-session`[](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints#free-single-session-api-free-session) Copy curl --location --request POST '127.0.0.1:8080/api/free-session' \ --header 'x-api-key: my-auth-key-1' \ --header 'Content-Type: application/json' \ --data-raw '{ "sessionId":"my-custom-sessionid" }' #### Free All Sessions `/api/free-all`[](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints#free-all-sessions-api-free-all) Copy curl --location --request GET '127.0.0.1:8080/api/free-all' \ --header 'x-api-key: my-auth-key-1' [PreviousConfiguration & Start](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/configuration-and-start) [NextDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/defaults) Last updated 8 hours ago --- # Defaults | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/defaults.md) . For the standalone api the same defaults are configured as for the shared library you can find [here](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults) . [PreviousEndpoints](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints) [NextAttention](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/attention) Last updated 3 years ago --- # Attention | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/attention.md) . * Applications powered with [gosoline](https://github.com/justtrackio/gosoline) automatically host a health check endpoint which is by default on port `8090` under the path `/health`. So in our case it would be `http://127.0.0.1:8090/health`. * Applications powered with [gosoline](https://github.com/justtrackio/gosoline) automatically host a metadata server for your application to provide insights into your application. The metadata server is hosted on port `8070` and has three endpoints. `/`, `/config`, `/memory` this should help you debugging your application. * **Do not make this endpoints public available when you host the Application on some server in the internet. You would make your config file public available.** [PreviousDefaults](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/defaults) [NextPayload](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/payload) Last updated 3 years ago --- # How to get support | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support.md) . [Frequently Asked Questions / Errors](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors) [Community Support](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support) [PreviousResponse](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/response) [NextFrequently Asked Questions / Errors](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors) Last updated 2 years ago --- # Payload | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/payload.md) . The payload you can send against the standalone api is exactly the same as for the shared library which you can find [here](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload) [PreviousAttention](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/attention) [NextResponse](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/response) Last updated 3 years ago --- # Response | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/response.md) . The response for the standalone api is the same as for the shared library which you can find [here](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response) [PreviousPayload](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/payload) [NextHow to get support](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support) Last updated 3 years ago --- # Further Information | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/further-information.md) . This library uses the following api: [https://tls.peet.ws/api/all](https://tls.peet.ws/api/all) to verify the hashes and fingerprints for http2 and ja3. Be aware that also peets api does not show every extension/cipher a TLS client is using. Do not rely just on ja3 strings. The API does not include the GREASE Extenson into the ja3 string. It’s omitted on purpose. Always have a look at the extension list and not only on the ja3 string. Show some love for peet here: [https://www.buymeacoffee.com/peeet](https://www.buymeacoffee.com/peeet) If you appreciate my work feel free to [buy me a coffee](https://www.buymeacoffee.com/CaptainBarnius) or donate some money to charity. [PreviousCommunity Support](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support) [NextAntibots & Captchas](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas) Last updated 2 years ago --- # Proxies | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/proxies.md) . #### Thordata[](https://bogdanfinn.gitbook.io/open-source-oasis/proxies#thordata) Thordata is a leading global residential proxy provider with a massive pool of 60 million dynamic IPs. We empower large-scale web data extraction with fast, stable, and highly scalable access. With a guaranteed 99.9% uptime, Thordata offers a versatile range of Mobile, Static ISP, and Datacenter proxies. [![Logo](https://bogdanfinn.gitbook.io/open-source-oasis/~gitbook/image?url=https%3A%2F%2Fwww.thordata.com%2Ffavicon.ico&width=20&dpr=3&quality=100&sign=cb78e6abbd48af87d79bf8814f515c60&sv=3)Thordata - High-Quality Proxy Service for Web Data Scrapingwww.thordata.com](https://www.thordata.com/?ls=github&lk=scrapoxy) [PreviousAntibots & Captchas](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas) [NextCommunity Projects](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects) Last updated 7 months ago --- # Community Projects | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects.md) . Here you can find a list of projects which are using the TLS-Client ### Go[](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects#go) * [https://github.com/mochaaless/bogdanfinn-go-wrapper](https://github.com/mochaaless/bogdanfinn-go-wrapper) ### Python[](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects#python) * [https://github.com/FlorianREGAZ/Python-Tls-Client](https://github.com/FlorianREGAZ/Python-Tls-Client) * [https://github.com/rawandahmad698/noble-tls](https://github.com/rawandahmad698/noble-tls) * [https://github.com/daijro/hrequests](https://github.com/daijro/hrequests) * [https://thewebscraping.github.io/tls-requests/](https://thewebscraping.github.io/tls-requests/) ### JavaScript / Node[](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects#javascript-node) * [https://www.npmjs.com/package/@dryft/tlsclient](https://www.npmjs.com/package/@dryft/tlsclient) * [https://github.com/DemonMartin/tlsClient](https://github.com/DemonMartin/tlsClient) * [https://github.com/senpai0807/tls-server](https://github.com/senpai0807/tls-server) ### Others[](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects#others) * [https://github.com/vihangatheturtle/TLSProxy](https://github.com/vihangatheturtle/TLSProxy) * [https://github.com/brianxor/tls-api](https://github.com/brianxor/tls-api) [PreviousProxies](https://bogdanfinn.gitbook.io/open-source-oasis/proxies) [NextContributing](https://bogdanfinn.gitbook.io/open-source-oasis/contributing) Last updated 11 months ago --- # Contributing | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/contributing.md) . Contributions to this documentation are welcome! If you find something that is outdated, incorrect, or missing, feel free to help improve it. ### How to contribute[](https://bogdanfinn.gitbook.io/open-source-oasis/contributing#how-to-contribute) 1. Fork the documentation repository: [https://github.com/bogdanfinn/tls-client-docs](https://github.com/bogdanfinn/tls-client-docs) 2. Create a new branch for your changes. 3. Make your changes and commit them. 4. Open a Pull Request against the `main` branch with a short description of what you changed and why. ### What you can contribute[](https://bogdanfinn.gitbook.io/open-source-oasis/contributing#what-you-can-contribute) * Fix typos or incorrect information * Add missing documentation for existing features * Improve existing explanations or examples * Add examples for additional languages or use cases * Add or update client profile information [PreviousCommunity Projects](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects) Last updated 7 months ago --- # Frequently Asked Questions / Errors | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors.md) . Here are some frequently asked questions about the cookiejar 1. How can i delete cookies from the session / jar? * Pass a new cookiejar instance to the clients SetCookiejar() method * For the shared library there is no option to delete all cookies of a session * You can delete a single cookie inside a session if you give the cookie a negative maxAge value. (Does only work for the tls\_client cookiejar not the standard cookiejar) 2. I can not do a successful POST Request with the shared library or standalone api * Be aware that when you do a POST Request and want to provide a forwarded request body in the `requestBody` field it has to be a string. That means if you want to send JSON you need to stringify this JSON to a string first and set the correct `content-type` header. 3. How can I use other request body content types besides json? * `requestBody` accepts strings and forwards them as the payload. combined with the `content-type` header the api makes the actual request body out of it. You can use for example `application/x-www-form-urlencoded` content type in the header and then just provide as request body a string similar to `key=value&key=value` 4. x509: certificate signed by unknown authority * As the message indicates you are trying to request a server which most likely has a self signed ssl certificate. There is a client option to skip the cerification. 5. x509: certificate has expired or is not yet valid * As the message indicates you are trying to request a server which most likely has an expired or invalid ssl certificate. There is a client option to skip the cerification. 6. stream error: stream ID 3; PROTOCOL\_ERROR * Sometimes this happens when people set a wrong `content-length` header on the request. Usually you never need to set the `content-length` header because the client will take care of that for you. [PreviousHow to get support](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support) [NextCommunity Support](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support) Last updated 2 years ago --- # Community Support | Open Source Oasis For the complete documentation index, see [llms.txt](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt) . This page is also available as [Markdown](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support.md) . Please join the community support server here: [https://discord.gg/7Ej9eJvHqk](https://discord.gg/7Ej9eJvHqk) and ask for support in the community. I will not give support to you in my Discord DMs. [PreviousFrequently Asked Questions / Errors](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors) [NextFurther Information](https://bogdanfinn.gitbook.io/open-source-oasis/further-information) Last updated 3 years ago --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python.md). # Python - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples.md). # Examples Please take a look at the following Typescript Code in the repository to see examples implemented: \`cffi\_dist/example\_typescript/src/samples/\` We provide examples for the following use cases: \* GET Request (\`sync.ts\`) \* Async Request (\`async.ts\`) \* POST Request (\`post.ts\`) \* Use Cookies (\`cookies.ts\`) \* Custom Client (\`custom\_client.ts\`) \* Proxy Rotation (\`proxy.ts\`) \* Switching the Redirect Following Behavior (\`redirects.ts\`) \* Certificate Pinning (\`pinning.ts\`) \* Image Download (\`download.ts\`) Each sample can be run with its own npm script, e.g. \`npm run start:post\`. See \`package.json\` for the full list. \`src/types.ts\` mirrors the payload and response structs of the shared library, which live in \`cffi\_src/types.go\` in the tls-client repository. Every field of the request payload, the \`customTlsClient\` definition and the transport options is typed there, including the HTTP/2 and HTTP/3 setting names as string unions. When you upgrade the shared library, check that go file for new fields. \`src/client.ts\` wraps the \[exposed methods\](/open-source-oasis/shared-library/exposed-methods.md) and frees the memory of every response for you, so you do not have to call \`freeMemory\` yourself. In general you can also take a look at the \[JavaScript Examples\](/open-source-oasis/shared-library/javascript/examples.md). The Typescript examples are more about how to define the types correctly and use them. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript.md). # TypeScript - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/typescript/examples.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/python/examples.md). # Examples Please take a look at the following Python Code in the repository to see examples implemented: \`cffi\_dist/example\_python/\` We provide examples for the following use cases: \* GET Request \* POST Request \* Image Download \* Image Upload \* Async Request \* Custom Client \* Use Cookies \* Proxy Rotation \* Switching the Redirect Following Behavior \* Certificate Pinning --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c.md). # C\\# - \[Examples\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/c/examples.md). # Examples Please take a look at the following C# code in the repository to see examples implemented: \`cffi\_dist/example\_csharp/\` \`Requester.cs\` shows loading and defining the shared library, plus a small session wrapper class. \`Example.csproj\` is a runnable console project (\`dotnet run -- \`) with a short, focused example per topic: \* \`basic\` - GET Request \* \`post\` - POST Request \* \`cookies\` - Use Cookies \* \`custom\_client\` - Custom Client \* \`proxy\` - Proxy Rotation \* \`redirects\` - Switching the Redirect Following Behavior \* \`pinning\` - Certificate Pinning \* \`download\` - Image Download Adjust \`LibraryPath\` in \`TlsClientLibrary.cs\` to point at the shared library you downloaded for your OS/arch/version before running. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/defaults.md). # Defaults The client from the shared library uses the same default settings as the regular TLS client which are defined \[here\](/open-source-oasis/readme/defaults.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/memory-issues.md). # Memory Issues #### Go TLS Client & Standalone API For the pure go implementation there is no real possibility to run into memory leak issues, except of the fact that you implemented your request handling badly and the references to your objects are never really freed that the go garbage collection can not clean up the used memory. If you are running into memory leak issues with the Go client or the standalone api please double check your request handling in order so see if you are doing things not as recommended (for example not closing or deferred closing the response body inside an infinite loop) #### Shared Library If you are using the shared library there is potential to run into memory leak issues. Luckily you can avoid that by following a couple simple steps. By design there is memory allocated for every response coming from the go implementation (shared library) to the invoking application (python, node, etc.). The caller has to free the memory when he is done with handling the response. otherwise the memory will never be freed and you run into memory issues. On every response from the shared library you will see an \`"id"\` property. You can pass the value from the \`"id"\` field as parameter to the \`freeMemory()\` call of the shared library. \`\`\`javascript const response = tlsClientLibrary.request(JSON.stringify(requestPayload)); const responseObject = JSON.parse(response) tlsClientLibrary.freeMemory(responseObject.id) // free memory \`\`\` \`\`\`python response = request(dumps(request\_payload).encode('utf-8')) response\_bytes = ctypes.string\_at(response) response\_string = response\_bytes.decode('utf-8') response\_object = loads(response\_string) freeMemory(response\_object\['id'\].encode('utf-8')) \`\`\` --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application.md). # Standalone API Application The standalone API Application can be found here: This is an application which is using \[gosoline\](https://github.com/justtrackio/gosoline) and \[TLS-Client\](https://github.com/bogdanfinn/tls-client) to run a simple request forwarding service with the option to use specific TLS fingerprints which are implemented in \[TLS-client\](https://github.com/bogdanfinn/tls-client). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/endpoints.md). # Endpoints You need to do a POST Request against the running API with the following JSON Request Body. #### Forward Request \`/api/forward\` \`\`\` curl --location --request POST '127.0.0.1:8080/api/forward' \\ --header 'x-api-key: my-auth-key-1' \\ --header 'Content-Type: application/json' \\ --data-raw '{ "tlsClientIdentifier": "chrome\_150", "requestUrl": "https://tls.peet.ws/api/all", "requestMethod": "GET" }' \`\`\` #### Get Cookies from Session \`/api/cookies\` \`\`\` curl --location --request POST '127.0.0.1:8080/api/cookies' \\ --header 'x-api-key: my-auth-key-1' \\ --header 'Content-Type: application/json' \\ --data-raw '{ "sessionId":"my-custom-sessionid", "url":"http://some-url.com" }' \`\`\` #### Free Single Session \`/api/free-session\` \`\`\` curl --location --request POST '127.0.0.1:8080/api/free-session' \\ --header 'x-api-key: my-auth-key-1' \\ --header 'Content-Type: application/json' \\ --data-raw '{ "sessionId":"my-custom-sessionid" }' \`\`\` #### Free All Sessions \`/api/free-all\` \`\`\` curl --location --request GET '127.0.0.1:8080/api/free-all' \\ --header 'x-api-key: my-auth-key-1' \`\`\` --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/antibots-and-captchas.md). # Antibots & Captchas The TLS-Client is just a tool to mimic specific client profiles. It does not solve / pass antibot solutions which have other "challenges" like a javascript challenge or require solving a captcha. Luckily for this there are various services on the market to help you. #### HyperSolutions Hyper Solutions offers proven solutions for handling Akamai, Incapsula, DataDome, Kasada, and Cloudflare antibot systems. Our request-based APIs generate tokens and sensor data instantly. No browsers, no complexity, just fast and reliable bypass solutions trusted by leading companies across industries. {% embed url="" %} #### \*\*ParallaxSystems\*\* ParallaxSystems offers the most reliable solutions for handling various AntiBot Systems, trusted by leading companies across industries. With years of expertise, we ensure seamless integration and fast results, including direct cookie returns for ultimate efficiency. {% embed url="" %} #### Capsolver.com Capsolver‘s automatic captcha solver offers the most affordable and quick captcha-solving solution. You may rapidly combine it with your program using its simple integration option to achieve the best results in a matter of seconds. {% embed url="" %} #### Nstbrowser.io Nstbrowser is a powerful anti-detect browser designed for multi-accounting professionals to manage multiple accounts securely and efficiently. {% embed url="" %} #### Other services {% embed url="" %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/build-from-source.md). # Build from source When you want to build the application from source, make sure to also checkout this repository \`https://github.com/Solem8s/gosoline\` on the branch \`tls-client-api\` next to this project. \\ Afterwards you can just run the following script: \`cmd/tls-client-api/build.sh SOME\_BUILD\_IDENTIFIER\` and it should build the binaries for you. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/proxies.md). # Proxies #### Thordata Thordata is a leading global residential proxy provider with a massive pool of 60 million dynamic IPs. We empower large-scale web data extraction with fast, stable, and highly scalable access. With a guaranteed 99.9% uptime, Thordata offers a versatile range of Mobile, Static ISP, and Datacenter proxies. {% embed url="" %} --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/configuration-and-start.md). # Configuration & Start \* Configure things like api port and authentication keys in the \`cmd/tls-client-api/config.dist.yml\` file. \* The default endpoint is \`http://127.0.0.1:8080/api/forward\` \* You need to set a \`x-api-key\` header with an auth key from the config file. This is for protecting the API when you host it on some server. Requests without the correct keys in the header will be rejected. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/response.md). # Response The Response of a call against the shared library looks like this \`\`\` { "id": "some response identifier", "sessionId": "some reusable sessionId if provided on the request", "status": 200, "target": "the target url", "body": "The Response as string here or the error message", "headers": {}, "cookies": {}, "usedProtocol": "h2" } \`\`\` In case of an unexpected error the \`"status"\` will be 0 The \`"id"\` is necessary when you want to free the memory used to generate this response. Take a look at \[Memory Issues\](/open-source-oasis/shared-library/memory-issues.md). The \`"sessionId"\` can be reused to keep the cookies from the previous requests in this session. The \`"status"\` indicates the status code of the remote response. The \`"body"\` is the response body from the remote response. The \`"headers"\` are the headers returned from the remote response. The \`"cookies"\` are the cookies returned from the remote response. The \`"usedProtocol"\` indicates which protocol was used for the request (e.g. \`"h2"\`, \`"HTTP/2.0"\`, \`"HTTP/1.1"\`). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/attention.md). # Attention \* Applications powered with \[gosoline\](https://github.com/justtrackio/gosoline) automatically host a health check endpoint which is by default on port \`8090\` under the path \`/health\`. So in our case it would be \`http://127.0.0.1:8090/health\`. \* Applications powered with \[gosoline\](https://github.com/justtrackio/gosoline) automatically host a metadata server for your application to provide insights into your application. The metadata server is hosted on port \`8070\` and has three endpoints. \`/\`, \`/config\`, \`/memory\` this should help you debugging your application. \* \*\*Do not make this endpoints public available when you host the Application on some server in the internet. You would make your config file public available.\*\* --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/download.md). # Download Here you can find the latest prebuilt binaries. Older versions before 1.3.8 can be found in the Github history of the repository: There is a binary for linux, macos and windows. Just modify the \`config.dist.yml\` file next to the binary to your needs and start the application. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/shared-library/payload.md). # Payload This page shows once the full possible request payload against the shared library, with all default values. #### Basic Request Input \`\`\` { "catchPanics": false, "certificatePinningHosts": null, "customTlsClient": null, "transportOptions": null, "followRedirects": false, "forceHttp1": false, "disableHttp3": false, "disableSessionTickets": false, "withProtocolRacing": false, "headerOrder": null, "headers": null, "insecureSkipVerify": false, "isByteRequest": false, "isByteResponse": false, "isRotatingProxy": false, "proxyUrl": null, "requestBody": null, "requestCookies": null, "requestHostOverride": null, "defaultHeaders": null, "connectHeaders": null, "requestMethod": "", "requestUrl": "", "disableIPV6": false, "disableIPV4": false, "localAddress": null, "sessionId": null, "serverNameOverwrite": "", "streamOutputBlockSize": null, "streamOutputEOFSymbol": null, "streamOutputPath": null, "timeoutMilliseconds": 0, "timeoutSeconds": 0, "tlsClientIdentifier": "", "withDebug": false, "withCustomCookieJar": false, "withoutCookieJar": false, "withRandomTLSExtensionOrder": false } \`\`\` | Field | Type | Description | | ------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | headers | Map\\ | Headers to attach on the current request. defaultHeaders will be used when empty. | | defaultHeaders | Map\\> | Default Headers to be used when no request headers are specified. The default header order can be specified with the Key "Header-Order:" | | connectHeaders | Map\\> | Headers to be used during the CONNECT request. | | serverNameOverwrite | string | Lookup \[Client Option \](/open-source-oasis/readme/client-options.md)"WithServerNameOverwrite" | \* \`sessionId\` is optional. When not provided the API does not create a Session. On every forwarded request with a given sessionId you will receive the sessionId in the response to be able to reuse sessions (cookies). \* Be aware that \`insecureSkipVerify\` and the \`timeoutSeconds\` can not be changed during a session. \* \`followRedirects\` and \`proxyUrl\` can be changed within a session. \* If you do not want to set \`requestBody\` or \`proxyUrl\` use \`null\` instead of empty string \* When you set \`isByteResponse\` to \`true\` the response body will be a base64 encoded string. Useful when you want to download images for example. \* When you set \`isByteRequest\` to \`true\` the request body needs to be a base64 encoded string. Useful when you want to upload images for example. \* When you set \`withProtocolRacing\` to \`true\` the client will race HTTP/3 (QUIC) and HTTP/2 (TCP) connections in parallel, similar to Chrome's "Happy Eyeballs" approach. Cannot be used together with \`forceHttp1\` or \`disableHttp3\`. If you also set a \`proxyUrl\` it has to be a \`socks5://\` or \`socks5h://\` proxy that supports UDP ASSOCIATE, since only SOCKS5 can tunnel the UDP traffic HTTP/3 needs. Any other proxy scheme is rejected with an error. \* When you set \`disableSessionTickets\` to \`true\` the client does not cache TLS session tickets and never resumes a TLS session, so every connection performs a full handshake. Only profiles that support session resumption (those sending a PSK extension) are affected. \* When you set \`withCustomCookieJar\` to \`true\` a custom TLS-Client cookie jar will be used which is more suited for certain use cases. Otherwise the default Go cookie jar is used. The \`supportedSignatureAlgorithms\` list of a custom TLS client additionally accepts \`MLDSA44\`, \`MLDSA65\`, \`MLDSA87\` and \`GREASE\`, which the Chrome 150 and Chrome 152 profiles use. \`GREASE\` is replaced with a value drawn from the connection's seed, so it changes per connection just like the built in profiles. \*\*trustAnchorsPayload\*\* Chrome 144 and later send the trust\\\_anchors extension (\`51764\`). A ja3 string lists extension IDs but carries no extension data, so if your \`ja3String\` contains \`51764\` you have to supply its payload separately in \`trustAnchorsPayload\`, as a hex string. Leaving it empty while the ja3 string asks for the extension fails the request with an error naming this field. To get the value, open your fingerprint source in the browser you want to imitate, find the entry named \`Unknown extension 51764\` in the \`tls.extensions\` array and copy its \`data\` field whole. It already starts at the 16-bit list length. \`\`\` { "ja3String": "771,...-51764,...", "trustAnchorsPayload": "00b80582df13020108839a648c9b2d010c08839a648c9b2d0107..." } \`\`\` Pass \`"0000"\` for an empty anchor list, which is what the Chrome 144 and Chrome 146 profiles send. The anchor IDs are put in a fresh order once per client, because Chromium writes them in hash set iteration order, which stays the same for the life of a browser process and differs between processes. So the bytes on the wire are a reordering of what you supply, not a copy of it. #### Custom TLS-Client \`\`\` { "certCompressionAlgos": \[\], "connectionFlow": 0, "h2Settings": null, "h2SettingsOrder": null, "h3Settings": null, "h3SettingsOrder": null, "h3PseudoHeaderOrder": null, "h3PriorityParam": 0, "h3SendGreaseFrames": false, "headerPriority": null, "ja3String": "", "trustAnchorsPayload": "", "keyShareCurves": null, "priorityFrames": null, "alpnProtocols": null, "alpsProtocols": null, "ECHCandidatePayloads": null, "ECHCandidateCipherSuites": null, "pseudoHeaderOrder": null, "supportedDelegatedCredentialsAlgorithms": null, "supportedSignatureAlgorithms": null, "supportedVersions": null, "recordSizeLimit": 0, "streamId": 0, "allowHttp": false } \`\`\`
FieldTypeDescription
certCompressionAlgosArray<string>See possible values at the end of this page
connectionFlowinteger
h2SettingsMap<string, int>See possible values for the Map keys at the end of this page.
h2SettingsOrderArray<string>Array of string keys which are used in the h2Settings property but ordered.
h3SettingsMap<string, int>HTTP/3 settings. See possible values for the Map keys at the end of this page.
h3SettingsOrderArray<string>Array of string keys which are used in the h3Settings property but ordered.
h3PseudoHeaderOrderArray<string>Pseudo header order for HTTP/3 requests.
h3PriorityParamintegerHTTP/3 priority parameter.
h3SendGreaseFramesbooleanWhether to send GREASE frames in HTTP/3.
headerPriorityPriorityParamSee type definition below in next section
ja3Stringstring
trustAnchorsPayloadstringHex payload for the trust\_anchors extension (51764). Required if your ja3String lists that extension, since a ja3 string carries extension IDs but no extension data. See the note below.
keyShareCurvesArray<string>See possible values at the end of this page
priorityFramesArray<PriorityFrames>See type definition below in next section
alpnProtocolsArray<string>List of supported protocols for the ALPN Extension
alpsProtocolsArray<string>List of supported protocols for the ALPS Extension
ECHCandidatePayloadsArray<uint16>List of ECH Candidate Payloads
ECHCandidateCipherSuitesArray<CandidateCipherSuite>See type definition below in next section
pseudoHeaderOrderArray<string>See possible values at the end of this page
supportedDelegatedCredentialsAlgorithmsArray<string>See possible values at the end of this page
supportedSignatureAlgorithmsArray<string>See possible values at the end of this page
supportedVersionsArray<string>See possible values at the end of this page
recordSizeLimitintegerTLS record size limit extension value
streamIdintegerInitial HTTP/2 stream ID
allowHttpbooleanAllow plaintext HTTP connections
#### TransportOptions \`\`\` { "disableKeepAlives": false, "disableCompression": false, "maxIdleConns": 0, "maxIdleConnsPerHost": 0, "maxConnsPerHost": 0, "maxResponseHeaderBytes": 0, "writeBufferSize": 0, "readBufferSize": 0, "idleConnTimeout": 0, } \`\`\` | Field | Type | Description | | ---------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- | | disableKeepAlives | boolean | | | disableCompression | boolean | disables (automatic) decompression behavor as documented \[here\](/open-source-oasis/readme/response-body-encoding-decoding.md) | | maxIdleConns | integer | | | maxIdleConnsPerHost | integer | | | maxConnsPerHost | integer | | | maxResponseHeaderBytes | integer | If zero, a default is used | | writeBufferSize | integer | If zero, a default (currently 4KB) is used | | readBufferSize | integer | If zero, a default (currently 4KB) is used | | idleConnTimeout | integer | Duration in Nano Seconds | #### CandidateCipherSuite
{
    "kdfId": "",
    "aeadId": "",
}
| Field | Type | Description | | ------ | ------ | ------------------------------------------- | | kdfId | string | See possible values at the end of this page | | aeadId | string | See possible values at the end of this page | #### PriorityParam
{
    "streamDep": 0,
    "exclusive": false,
    "weight": 0
}
| Field | Type | Description | | --------- | ------- | ----------- | | streamDep | integer | | | exclusive | boolean | | | weight | integer | | #### PriorityFrames \`\`\` { "streamID": 0, "priorityParam": null } \`\`\` | Field | Type | Description | | ------------- | ------------- | ----------------------------- | | streamId | integer | | | priorityParam | PriorityParam | See type in the section above | | | | | #### Cookie Input \`\`\` { "domain": "", "expires": 0, "maxAge": 0, "name": "", "path": "", "value": "", "secure": false, "httpOnly": false } \`\`\`
FieldTypeDescription
domainstring
expiresintegerUnix Timestamp
maxAgeintegerNumber of seconds the cookie is valid.
namestring
pathstring
valuestring
securebooleanWhether the cookie should only be sent over HTTPS.
httpOnlybooleanWhether the cookie is inaccessible to client-side scripts.
If both \`Expires\` and \`Max-Age\` are set, \`Max-Age\` has precedence. ### Values Here you can find the allowed possible string values to supply for fields like \`supportedDelegatedCredentialsAlgorithms\`, \`supportedSignatureAlgorithms\`, \`supportedVersions\` and much more. #### H2Settings \`\`\` "HEADER\_TABLE\_SIZE", "ENABLE\_PUSH", "MAX\_CONCURRENT\_STREAMS", "INITIAL\_WINDOW\_SIZE", "MAX\_FRAME\_SIZE", "MAX\_HEADER\_LIST\_SIZE", "UNKNOWN\_SETTING\_7", "UNKNOWN\_SETTING\_8", "UNKNOWN\_SETTING\_9", \`\`\` #### H3Settings \`\`\` "QPACK\_MAX\_TABLE\_CAPACITY", "MAX\_FIELD\_SECTION\_SIZE", "QPACK\_BLOCKED\_STREAMS", "H3\_DATAGRAM", \`\`\` #### Supported Versions \`\`\` "GREASE", "1.3", "1.2", "1.1", "1.0", \`\`\` #### Supported Signature Algorithms \`\`\` "PKCS1WithSHA256", "PKCS1WithSHA384", "PKCS1WithSHA512", "PSSWithSHA256", "PSSWithSHA384", "PSSWithSHA512", "ECDSAWithP256AndSHA256", "ECDSAWithP384AndSHA384", "ECDSAWithP521AndSHA512", "PKCS1WithSHA1", "ECDSAWithSHA1", "Ed25519", "SHA224\_RSA", "SHA224\_ECDSA", "MLDSA44", "MLDSA65", "MLDSA87", "GREASE", \`\`\` \`MLDSA44\`, \`MLDSA65\` and \`MLDSA87\` are the post quantum codepoints Chrome 150 and later advertise. \`GREASE\` is replaced with a value drawn from the connection's seed, so it differs per connection, the way Chrome 152 sends it. Both are only available for \`supportedSignatureAlgorithms\`, not for \`supportedDelegatedCredentialsAlgorithms\`. #### certCompressionAlgorithm \`\`\` "zlib", "brotli", "zstd", \`\`\` #### Supported delegated credentials \`\`\` "PKCS1WithSHA256", "PKCS1WithSHA384", "PKCS1WithSHA512", "PSSWithSHA256", "PSSWithSHA384", "PSSWithSHA512", "ECDSAWithP256AndSHA256", "ECDSAWithP384AndSHA384", "ECDSAWithP521AndSHA512", "PKCS1WithSHA1", "ECDSAWithSHA1", "Ed25519", "SHA224\_RSA", "SHA224\_ECDSA" \`\`\` #### KeyShareCurves \`\`\` "GREASE", "P256", "P384", "P521", "X25519", "P256Kyber768", "X25519Kyber512D", "X25519Kyber768", "X25519Kyber768Old", "X25519MLKEM768", \`\`\` #### kdfIds \`\`\` "HKDF\_SHA256", "HKDF\_SHA384", "HKDF\_SHA512", \`\`\` #### aeadIds \`\`\` "AEAD\_AES\_128\_GCM", "AEAD\_AES\_256\_GCM", "AEAD\_CHACHA20\_POLY1305", \`\`\` --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/defaults.md). # Defaults For the standalone api the same defaults are configured as for the shared library you can find \[here\](/open-source-oasis/shared-library/defaults.md). --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support.md). # How to get support - \[Frequently Asked Questions / Errors\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors.md) - \[Community Support\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/payload.md). # Payload The payload you can send against the standalone api is exactly the same as for the shared library which you can find \[here\](/open-source-oasis/shared-library/payload.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/community-support.md). # Community Support Please join the community support server here: and ask for support in the community. I will not give support to you in my Discord DMs. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/further-information.md). # Further Information This library uses the following api: to verify the hashes and fingerprints for http2 and ja3. Be aware that also peets api does not show every extension/cipher a TLS client is using. Do not rely just on ja3 strings. The API does not include the GREASE Extenson into the ja3 string. It’s omitted on purpose. Always have a look at the extension list and not only on the ja3 string. Show some love for peet here: If you appreciate my work feel free to \[buy me a coffee\](https://www.buymeacoffee.com/CaptainBarnius) or donate some money to charity. --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/community-projects.md). # Community Projects Here you can find a list of projects which are using the TLS-Client ### Go \* ### Python \* \* \* \* ### JavaScript / Node \* \* \* ### Others \* \* --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/standalone-api-application/response.md). # Response The response for the standalone api is the same as for the shared library which you can find \[here\](/open-source-oasis/shared-library/response.md) --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/contributing.md). # Contributing Contributions to this documentation are welcome! If you find something that is outdated, incorrect, or missing, feel free to help improve it. ### How to contribute 1. Fork the documentation repository: 2. Create a new branch for your changes. 3. Make your changes and commit them. 4. Open a Pull Request against the \`main\` branch with a short description of what you changed and why. ### What you can contribute \* Fix typos or incorrect information \* Add missing documentation for existing features \* Improve existing explanations or examples \* Add examples for additional languages or use cases \* Add or update client profile information --- # Unknown \> For the complete documentation index, see \[llms.txt\](https://bogdanfinn.gitbook.io/open-source-oasis/llms.txt). Markdown versions of documentation pages are available by appending \`.md\` to page URLs; this page is available as \[Markdown\](https://bogdanfinn.gitbook.io/open-source-oasis/how-to-get-support/frequently-asked-questions-errors.md). # Frequently Asked Questions / Errors Here are some frequently asked questions about the cookiejar 1. How can i delete cookies from the session / jar? \* Pass a new cookiejar instance to the clients SetCookiejar() method \* For the shared library there is no option to delete all cookies of a session \* You can delete a single cookie inside a session if you give the cookie a negative maxAge value. (Does only work for the tls\\\_client cookiejar not the standard cookiejar) 2. I can not do a successful POST Request with the shared library or standalone api \* Be aware that when you do a POST Request and want to provide a forwarded request body in the \`requestBody\` field it has to be a string. That means if you want to send JSON you need to stringify this JSON to a string first and set the correct \`content-type\` header. 3. How can I use other request body content types besides json? \* \`requestBody\` accepts strings and forwards them as the payload. combined with the \`content-type\` header the api makes the actual request body out of it. You can use for example \`application/x-www-form-urlencoded\` content type in the header and then just provide as request body a string similar to \`key=value&key=value\` 4. x509: certificate signed by unknown authority \* As the message indicates you are trying to request a server which most likely has a self signed ssl certificate. There is a client option to skip the cerification. 5. x509: certificate has expired or is not yet valid \* As the message indicates you are trying to request a server which most likely has an expired or invalid ssl certificate. There is a client option to skip the cerification. 6. stream error: stream ID 3; PROTOCOL\\\_ERROR \* Sometimes this happens when people set a wrong \`content-length\` header on the request. Usually you never need to set the \`content-length\` header because the client will take care of that for you. ---