This guide walks you through the process of setting up your Go environment and using the Outline SDK in your Go code.
We will build an example application called splitfetch
that showcases a
feature of the SDK. This application fetches a web page, but instead of sending
the request in a single network packet, it uses the Outline SDK to split the
initial TCP stream into two separate packets. This may help bypass some forms
of network intervention.
You will be able to run the application on Linux, Mac, and Windows. For integrating with mobile apps, check out Add Outline SDK to your mobile app.
Step 1: Set up Go
First up, you'll need the Go programming language. If you've already got Go (version 1.21 or newer) installed, you can skip to the next step.
For installation, you can follow the official guide; or, if you use a package manager:
Linux
Follow the steps in Go Wiki: Ubuntu.
Mac
brew install go
Windows
winget install --id=GoLang.Go -e
After Go is installed, you can verify that it is installed correctly by running the following command in a terminal:
go version
Step 2: Create the splitfetch
Application
Let get the splitfetch
project set up. First, create the project directory and
initialize a Go module:
mkdir splitfetch
cd splitfetch
go mod init example/splitfetch
Next, pull in the Outline SDK and create your main.go
file:
go get github.com/Jigsaw-Code/outline-sdk@latest
touch main.go
Step 3: Use Outline SDK in the Application
Open the main.go
file in your favorite code editor and paste the following
code into it. This code contains all the logic for our splitfetch
application.
package main
import (
"context"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"github.com/Jigsaw-Code/outline-sdk/transport"
"github.com/Jigsaw-Code/outline-sdk/transport/split"
)
// The number of bytes to send in the first packet.
const splitPacketSize = 3
func main() {
// 1. Get the URL from the command-line arguments.
if len(os.Args) < 2 {
log.Fatalf("Usage: %s <URL>", os.Args[0])
}
url := os.Args[1]
// 2. Create a split dialer from the Outline SDK.
// This dialer wraps a standard TCP dialer to add the splitting behavior.
dialer, err := split.NewStreamDialer(&transport.TCPDialer{}, split.NewFixedSplitIterator(splitPacketSize))
if err != nil {
log.Fatalf("Failed to create split dialer: %v", err)
}
// 3. Configure an HTTP client to use our custom split dialer for TCP connections.
httpClient := &http.Client{
Transport: &http.Transport{
DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) {
return dialer.DialStream(ctx, addr)
},
},
}
// 4. Use the custom client to make the HTTP GET request.
resp, err := httpClient.Get(url)
if err != nil {
log.Fatalf("HTTP request failed: %v", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
log.Fatalf("Failed to read response body: %v", err)
}
fmt.Println(string(body))
}
After saving the code, run the following command in your terminal to make sure
the go.mod
file is updated correctly.
go mod tidy
Step 4: Run the Application
With the code in place, you can now run the splitfetch
application.
From within the splitfetch
directory, run the following command in your
terminal, passing a URL as an argument:
go run . https://getoutline.org
This compiles and runs the application, displaying the webpage's HTML content.
If you want to create and distribute a standalone program that you can run
without go
, use the go build
command:
Linux & Mac
go build -o splitfetch .
Windows
go build -o splitfetch.exe .
Once the build is finished, you can distribute and run your application. For example:
./splitfetch https://getoutline.org