Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/buildandtest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,6 @@ jobs:
- name: Build
run: direnv exec . go build -v ./...
- name: Build Examples
run: direnv exec . go build -v ./examples/...
run: direnv exec . go build -C ./examples -v ./...
- name: Test
run: direnv exec . go test -v ./...
25 changes: 24 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,27 @@
## 2.0.0

This is a breaking-change release that updates ngrok-go to a new, simplified
API.

Enhancements:
- Dramatically simplified the API to remove many overlapping options, options
that are now deprecated, unnecessary convenience functions, and more.
- Simplified the API by removing all protocol-specific behaviors (which have
all been moved to Traffic Policy).
- Removed the config package. All of its options are now folded into the
top-level package or removed because they were migrated into Traffic Policy.
- Updates the API to use new ngrok terminology of Agents, Endpoints Upstreams,
and Traffic Policy.
- Removes functionality that is now deprecated (like labeled tunnels).
- Added support for agent-based TLS termination and Mutual TLS termination.
- Added support for full TLS control over forwarding to the upstream.
- Added support for full control over dialing the upstream.
- Removed a bespoke logging interface in favor of `log/slog`.
- Removed the prototype policy package that was not well supported.
- Separated out a concept of an Agent from its Session which were previously
co-mingled.
- Added integration tests.

## 1.12.1

Fixes:
Expand All @@ -9,7 +33,6 @@ Fixes:
Breaking changes:

- Renames pre-release option `WithAllowsPooling` to `WithPoolingEnabled`
-

## 1.11.0

Expand Down
10 changes: 3 additions & 7 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,10 @@ For any larger changes or features, please [open a new issue](https://github.com

The library can be compiled with `go build`.

To run tests, `go test`.
To run tests, use `go test ./...`.

Tests are split into a number of categories that can be enabled as desired via environment variables. By default, only offline tests run which validate tunnel protocol RPC messages generated from the `config` APIs. The other tests are gated behind the following environment variables:

* `NGROK_TEST_ONLINE`: All online tests require this variable to be set
* `NGROK_TEST_AUTHED`: Enables tests that require an ngrok account and that the authtoken is set in `NGROK_AUTHTOKEN`.
* `NGROK_TEST_PAID`: Enables online, authenticated tests that require access to paid features. If your subscription doesn't support a feature being tested, you should see error messages to that effect.
* `NGROK_TEST_LONG`: Enables online tests that may take longer than most. May also require the `AUTHED` and/or `PAID` groups enabled.
* `NGROK_TEST_FLAKEY`: Enable online tests that may be unreliable. Their success or failure may depend on network conditions, timing, solar flares, ghosts in the machine, etc.
* `NGROK_TEST_ONLINE`: All online tests require this variable to be set and an authtoken in `NGROK_AUTHTOKEN`. Tests that require paid features will fail with appropriate error messages if your subscription doesn't support them.

This list may be incomplete and drift slightly as we add more tests and granularity. See the tests in `online_test.go` for the most accurate list.
This list may be incomplete and drift slightly as we add more tests and granularity. See the tests in `internal/legacy/online_test.go` and `internal/integration_tests/` for the most accurate implementations.
103 changes: 79 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,51 @@
# ngrok-go

[![Go Reference](https://pkg.go.dev/badge/golang.ngrok.com/ngrok.svg)](https://pkg.go.dev/golang.ngrok.com/ngrok)
[![Go Reference](https://pkg.go.dev/badge/golang.ngrok.com/ngrok/v2.svg)](https://pkg.go.dev/golang.ngrok.com/ngrok/v2)
[![Go](https://github.com/ngrok/ngrok-go/actions/workflows/buildandtest.yml/badge.svg)](https://github.com/ngrok/ngrok-go/actions/workflows/buildandtest.yml)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ngrok/ngrok-rust/blob/main/LICENSE-MIT)
[![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/ngrok/ngrok-go/blob/main/LICENSE.txt)


[ngrok](https://ngrok.com) is a simplified API-first ingress-as-a-service that adds connectivity, security, and observability to your apps.
[ngrok](https://ngrok.com) is an API gateway cloud service that forwards to
applications running anywhere.

ngrok-go is an open source and idiomatic library for embedding ngrok networking directly into Go applications. If you’ve used ngrok before, you can think of ngrok-go as the ngrok agent packaged as a Go library.
ngrok-go is an open source and idiomatic Go package for embedding ngrok
networking directly into your Go applications. If you've used ngrok before, you
can think of ngrok-go as the ngrok agent packaged as a Go library.

ngrok-go lets developers serve Go apps on the internet in a single line of code without setting up low-level network primitives like IPs, certificates, load balancers and even ports! Applications using ngrok-go listen on ngrok’s global ingress network but they receive the same interface any Go app would expect (net.Listener) as if it listened on a local port by calling net.Listen(). This makes it effortless to integrate ngrok-go into any application that uses Go's net or net/http packages.

See [`examples/http/main.go`](/examples/http/main.go) for example usage, or the tests in [`online_test.go`](/online_test.go).
ngrok-go enables you to serve Go apps on the internet in a single line of code
without setting up low-level network primitives like IPs, certificates, load
balancers and even ports! Applications using ngrok-go listen on ngrok's global
cloud service but, they receive connections using the same interface
(net.Listener) that any Go app would expect if it listened on a local port.

For working with the [ngrok API](https://ngrok.com/docs/api/), check out the [ngrok Go API Client Library](https://github.com/ngrok/ngrok-api-go).

## Installation

The best way to install the ngrok agent SDK is through `go get`.
Install ngrok-go with `go get`.

```sh
go get golang.ngrok.com/ngrok
go get golang.ngrok.com/ngrok/v2
```

## Documentation

A full API reference is included in the [ngrok go sdk documentation on pkg.go.dev](https://pkg.go.dev/golang.ngrok.com/ngrok). Check out the [ngrok Documentation](https://ngrok.com/docs) for more information about what you can do with ngrok.

For additional information, be sure to also check out the [ngrok-go launch announcement](https://ngrok.com/blog-post/ngrok-go)!
- [ngrok-go API Reference](https://pkg.go.dev/golang.ngrok.com/ngrok/v2) on pkg.go.dev.
- [ngrok Documentation](https://ngrok.com/docs) for what you can do with ngrok.
- [Examples](./examples) are another great way to get started.
- [ngrok-go launch announcement](https://ngrok.com/blog-post/ngrok-go) for more context on why we built it. The examples in the blog post may be out of date for the new API.

## Quickstart

For more examples of using ngrok-go, check out the [/examples](/examples) folder.

The following example uses ngrok to start an http endpoint with a random url that will route traffic to the handler. The ngrok URL provided when running this example is accessible by anyone with an internet connection.
The following example starts a Go web server that receives traffic from an
endpoint on ngrok's cloud service with a randomly-assigned URL. The ngrok URL
provided when running this example is accessible by anyone with an internet
connection.

The ngrok authtoken is pulled from the `NGROK_AUTHTOKEN` environment variable. You can find your authtoken by logging into the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken).
You need an ngrok authtoken to run the following example, which you can get from
the [ngrok dashboard](https://dashboard.ngrok.com/get-started/your-authtoken).

You can run this example with the following command:
Run this example with the following command:

```sh
NGROK_AUTHTOKEN=xxxx_xxxx go run examples/http/main.go
Expand All @@ -52,8 +60,7 @@ import (
"log"
"net/http"

"golang.ngrok.com/ngrok"
"golang.ngrok.com/ngrok/config"
"golang.ngrok.com/ngrok/v2"
)

func main() {
Expand All @@ -63,16 +70,16 @@ func main() {
}

func run(ctx context.Context) error {
ln, err := ngrok.Listen(ctx,
config.HTTPEndpoint(),
ngrok.WithAuthtokenFromEnv(),
)
// ngrok.Listen uses ngrok.DefaultAgent which uses the NGROK_AUTHTOKEN
// environment variable for auth
ln, err := ngrok.Listen(ctx)
if err != nil {
return err
}

log.Println("Ingress established at:", ln.URL())
log.Println("Endpoint online", ln.URL())

// Serve HTTP traffic on the ngrok endpoint
return http.Serve(ln, http.HandlerFunc(handler))
}

Expand All @@ -81,6 +88,54 @@ func handler(w http.ResponseWriter, r *http.Request) {
}
```

## Traffic Policy

You can use ngrok's [Traffic Policy](https://ngrok.com/docs/traffic-policy/)
engine to apply API Gateway behaviors at ngrok's cloud service to auth, route,
block and rate-limit the traffic. For example:

```go
tp := `
on_http_request:
- name: "rate limit by ip address"
actions:
- type: rate-limit
config:
name: client-ip-rate-limit
algorithm: sliding_window
capacity: 30
rate: 60s
bucket_key:
- conn.client_ip
- name: "federate to google for auth"
actions:
- type: oauth
config:
provider: google
- name: "block users without an 'example.com' domain"
expressions:
- "!actions.ngrok.oauth.identity.email.endsWith('@example.com')"
actions:
- type: custom-response
config:
status_code: 403
content: "${actions.ngrok.oauth.identity.name} is not allowed"
`

ln, err := ngrok.Listen(ctx, ngrok.WithTrafficPolicy(tp))
if err != nil {
return err
}
```

## Examples

There are many more great examples you can reference to get started:

- [Creating a TCP endpoint](./examples/tcp/) and handling TCP connections directly.
- [Forwarding to another URL](./examples/forward/) instead of handling connections yourself.
- [Adding Traffic Policy](./examples/traffic-policy/) in front of your app for authentication, rate limiting, etc.

## Support

The best place to get support using ngrok-go is through the [ngrok Slack Community](https://ngrok.com/slack). If you find bugs or would like to contribute code, please follow the instructions in the [contributing guide](/CONTRIBUTING.md).
Expand Down
10 changes: 10 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
TODO

- Fix #176
- Add agent configuration file parsing with an AgentConfig struct
- Wrap `Conn` objects returned by the listener with a type that can be used to determine if they are TLS-terminated or not
- Remove the legacy package by folding all of its logic into the current package
- Add an RPC test
- Implement support for AgentSession.ID()
- Endpoint.ID() should return the endpoint's API resource identifier but right now it just returns a random unique identifier unrelated to the API resource
- Endpoint.Wait() which can be used to wait until an endpoint stops
1 change: 0 additions & 1 deletion VERSION

This file was deleted.

Loading