-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
b1e2e2e
commit 6af5993
Showing
197 changed files
with
159,803 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
vendor/** -diff |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Gopkg.toml example | ||
# | ||
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html | ||
# for detailed Gopkg.toml documentation. | ||
# | ||
# required = ["github.com/user/thing/cmd/thing"] | ||
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] | ||
# | ||
# [[constraint]] | ||
# name = "github.com/user/project" | ||
# version = "1.0.0" | ||
# | ||
# [[constraint]] | ||
# name = "github.com/user/project2" | ||
# branch = "dev" | ||
# source = "github.com/myfork/project2" | ||
# | ||
# [[override]] | ||
# name = "github.com/x/y" | ||
# version = "2.4.0" | ||
# | ||
# [prune] | ||
# non-go = false | ||
# go-tests = true | ||
# unused-packages = true | ||
|
||
[[constraint]] | ||
name = "github.com/spf13/cobra" | ||
version = "0.0.3" | ||
|
||
[[constraint]] | ||
name = "golang.org/x/net" | ||
branch = "master" | ||
|
||
[prune] | ||
go-tests = true | ||
unused-packages = true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,33 @@ | ||
# h2-stream | ||
|
||
HTTP2 client and server implementation in GO that holds a persistent data stream | ||
- Client takes data from standard input and forwards it to the server | ||
- Client forwards server responses to standard output | ||
- Server responds echoing the received data | ||
|
||
TLS and non TLS options are both available | ||
|
||
## Usage | ||
|
||
### without TLS | ||
|
||
launch server: | ||
``` | ||
go run cmd/h2-stream/main.go serve --addr=localhost:8080 --tls=false | ||
``` | ||
|
||
launch client: | ||
``` | ||
go run cmd/h2-stream/main.go cli --addr=http://localhost:8080 --method=POST | ||
``` | ||
|
||
### with TLS | ||
launch server: | ||
``` | ||
go run cmd/h2-stream/main.go serve --addr=localhost:8080 --tls=true --cert=certs/cert.pem --key=certs/key.pem | ||
``` | ||
|
||
launch client: | ||
``` | ||
go run cmd/h2-stream/main.go cli --addr=https://localhost:8080 --method=POST --insecure | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIDADCCAeigAwIBAgIRAMlZFfrjDjpriu1r+XIr1kwwDQYJKoZIhvcNAQELBQAw | ||
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xODA4MDIxMTI0MTlaFw0xOTA4MDIxMTI0 | ||
MTlaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw | ||
ggEKAoIBAQDHYGCQkL4xc4djNNtjWcuPAGLmiRLI+uompmccJ7f9vUZgu/gO9oVS | ||
nQlVRNX4LS0TnZjyQMso+9ZNt9sdyDohkMVmS0O27kD9gz2Pz+otYg0w4TVX0pJp | ||
c3jwvSoXdqNxrj+Fk9aptIFsfipN2cE7uFA40+rZSlyND+lSB/VvNKILSrp6Ugmo | ||
CpRRFJ0O8VjYV+qU7RZh9HFIvtW6w9uLeN2jD+k7VGVt6hADpdoSzQiAerZ5+8ee | ||
IcmAj/G5COGbGAnbuy73/Bmo9b728UXo6b+7GdyXYij/pev/0OcIoT7WKFQJJyVz | ||
owc+yyEHhKpuKqCy9KNzPQqm7je//BptAgMBAAGjUTBPMA4GA1UdDwEB/wQEAwIF | ||
oDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMBoGA1UdEQQTMBGC | ||
CWxvY2FsaG9zdIcEfwAAATANBgkqhkiG9w0BAQsFAAOCAQEAlDF2c4ktrz1BJcQL | ||
PhyynqOmLCJiPw/A9vSCOuaH2RduHufiO80RKW9KRiLsAAvSToAsFrTNlTL3Jdjp | ||
UnWjal+gMh3fU+Fw3lGlq/UeYxMjZsTATazy2D2dJWwv0PUWo7dE0w/Thh1SdhEU | ||
cNpoIDTsrnfa4P300XK+ej5A6gVYa++adAh3QdjLAzOfDxIInMwinMIQy9kACPvd | ||
XNZ4AfD+wsH0dHTFPr5k12ZJbPMljCFe/rmbDoEpxOwimBcnRohEgOIbKjwEUXRi | ||
B+q7AnJ0Q1rK/J7ikSDFBBGlg8wHWz+FCINmyyv62qClErI4aA/WN6+ilINJV/gG | ||
qgNGqQ== | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIIEpAIBAAKCAQEAx2BgkJC+MXOHYzTbY1nLjwBi5okSyPrqJqZnHCe3/b1GYLv4 | ||
DvaFUp0JVUTV+C0tE52Y8kDLKPvWTbfbHcg6IZDFZktDtu5A/YM9j8/qLWINMOE1 | ||
V9KSaXN48L0qF3ajca4/hZPWqbSBbH4qTdnBO7hQONPq2UpcjQ/pUgf1bzSiC0q6 | ||
elIJqAqUURSdDvFY2FfqlO0WYfRxSL7VusPbi3jdow/pO1RlbeoQA6XaEs0IgHq2 | ||
efvHniHJgI/xuQjhmxgJ27su9/wZqPW+9vFF6Om/uxncl2Io/6Xr/9DnCKE+1ihU | ||
CSclc6MHPsshB4SqbiqgsvSjcz0Kpu43v/wabQIDAQABAoIBADbktjGXaIY9BL2v | ||
w+eqxXzt4k0O2Hk1fFp/3kvGM8ZM4p+noTidbz+7tOIhPbhC1/Japc2tQUJbdDmZ | ||
sV6VzkuHjJIJju9C0en6xGxgFl3AbVlT6FfxxhX6kQXXT0t+gqm+DAc/GQ9If4nb | ||
gtJEbgt/R7cdwb9p1emQw/Ct+ElRe+xTZ36Vw1wgyLUmJJB3IAj5JTqeBwqFQOvt | ||
fV3zuS/zzzfXuhShwJMpsdHVJJzULeZPU1nhxAeTKGSF8XwBOL0hSL4ikS0s/U0P | ||
RoTL4flKsC3YwFOVq3Cn8bZW0xI5h/UmISJhkyj8th6PV72NNCBJ5ogLAr24TqH4 | ||
Emvj14ECgYEA1uLZXRue7vScYbpEUud+crM6ejBNOhib968J/Au1yf6aS9dgALVP | ||
MaZXg2GKRJWLHr3om4vJOUP14970NkJKlCkqJD8uUjKtGchcaNELPQjwM7HjmBAW | ||
VHANjHFJTEIGG/v9wwVE/ZUf9ljqE7jFA+DkJ5GrSfomwU1eKEthmQkCgYEA7YXc | ||
9zD/dmHg4LpbBP7R8syC4Ijl+ux/huuBh6GIbyLKCagtL3TFSNInDPO6rT1YdgLZ | ||
7WZSXaQ98aq2Q0vNRiXMccrsx6nPj20arRaZROZgz7s5W62Eexbz/b5rUrAuXzJF | ||
CVF6raZUxUKlF1b2ybc93ScqqjfWfoyZebE8w0UCgYEApxz+O+maHW2AHIR2VB8R | ||
+HOoG5Rqyq6OxP2Mf0ZAFxn4ttiFIaffMdaSImt90z6VVdANEMKSOAXBOXiPZY8C | ||
XtzwmAXGqUgd1Ho8W4uO+OV1oE5MmFqScxI9hyYnAbYq+CJtw/faIneRxsx5JeNA | ||
3HZOGPOxSTPQZe4cNqwA97kCgYBfVvYk+rPwDsW3LtZOIQKg1NpLymeV2swtmeZ6 | ||
TKp5AZvbWHgarmJqIoCuQD7UPuV9KRPUqNey4rRChuV2Cb0xxQZVPsDgPBcmWQL2 | ||
KzYGY/rEJ0CUvgeJaOMzHPXzUOisKX9wiBYYEcXBEEk4Hx4cRcM9O/VyMcuVLFaG | ||
dFARiQKBgQCHKrb0SzYVnaEWFR+GP+sJMfxrhq/N8m+WcCpoQ/UIvguMWmFKtVtC | ||
WVTd3XNizIpuNpDgGI4qvIwmEs7UhAzemxasYoP3y3FO2dT0QGC+T1SX/BsW6AiO | ||
fi06KUiLh/4rJtf2wph2wN8SPAY4yQkopFlDYTJNmhhYsKTGIhrpww== | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/igarciaolaizola/h2-stream/internal/cli" | ||
) | ||
|
||
func main() { | ||
cmd := cli.NewCommand() | ||
|
||
if err := cmd.Execute(); err != nil { | ||
log.Fatal(err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package cli | ||
|
||
import ( | ||
"github.com/igarciaolaizola/h2-stream/internal/client" | ||
"github.com/igarciaolaizola/h2-stream/internal/server" | ||
"github.com/spf13/cobra" | ||
) | ||
|
||
// NewCommand create and returns the root cli command | ||
func NewCommand() *cobra.Command { | ||
tunnelCmd := &cobra.Command{ | ||
Use: "tunnel", | ||
Short: "CLI tool aimed to handle http2 streams", | ||
Long: `CLI tool aimed to handle http2 streams: client or server side.`, | ||
} | ||
|
||
tunnelCmd.AddCommand(newServerCommand()) | ||
tunnelCmd.AddCommand(newClientCommand()) | ||
return tunnelCmd | ||
} | ||
|
||
func newServerCommand() *cobra.Command { | ||
var addr, cert, key string | ||
var tls bool | ||
|
||
cmd := &cobra.Command{ | ||
Use: "serve", | ||
Short: "Launches the http2 stream echo server", | ||
Long: `Launches the http2 stream server that echoes any incoming data.`, | ||
RunE: func(c *cobra.Command, args []string) error { | ||
return server.Run(addr, tls, cert, key) | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&addr, "addr", "localhost:8080", "http listening address") | ||
cmd.Flags().BoolVar(&tls, "tls", true, "enable tls (https)") | ||
cmd.Flags().StringVar(&cert, "cert", "certs/cert.pem", "tls certificate file") | ||
cmd.Flags().StringVar(&key, "key", "certs/key.pem", "tls key file") | ||
return cmd | ||
} | ||
|
||
func newClientCommand() *cobra.Command { | ||
var cfg client.Config | ||
|
||
cmd := &cobra.Command{ | ||
Use: "cli", | ||
Short: "Launches the http2 stream client", | ||
Long: `Launches the http2 stream client that sends any writen to stdin.`, | ||
RunE: func(c *cobra.Command, args []string) error { | ||
client, err := client.New(cfg) | ||
if err != nil { | ||
return err | ||
} | ||
return client.Run() | ||
}, | ||
} | ||
|
||
cmd.Flags().StringVar(&cfg.Addr, "addr", "https://localhost:8080", "http server address") | ||
cmd.Flags().StringVar(&cfg.Method, "method", "POST", "http method (GET, POST, PUT, DELETE...)") | ||
cmd.Flags().BoolVar(&cfg.Insecure, "insecure", false, "skip tls validation") | ||
cmd.Flags().StringArrayVar(&cfg.Headers, "header", nil, "custom headers, ex.: \"Content-Type: application/json\"") | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
package client | ||
|
||
import ( | ||
"crypto/tls" | ||
"errors" | ||
"fmt" | ||
"io" | ||
"log" | ||
"net" | ||
"net/http" | ||
"net/url" | ||
"os" | ||
"strings" | ||
|
||
"golang.org/x/net/http2" | ||
) | ||
|
||
// Config of the http2 client | ||
type Config struct { | ||
Addr string | ||
Method string | ||
Insecure bool | ||
Headers []string | ||
} | ||
|
||
// Client is a http2 client | ||
type Client struct { | ||
Config | ||
client http.Client | ||
} | ||
|
||
// New returns a new client | ||
func New(cfg Config) (*Client, error) { | ||
// Parse url | ||
url, err := url.Parse(cfg.Addr) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
var tlsConfig *tls.Config | ||
tlsEnabled := url.Scheme == "https" | ||
if tlsEnabled { | ||
tlsConfig = &tls.Config{InsecureSkipVerify: cfg.Insecure} | ||
} | ||
|
||
// Create http2 client | ||
client := http.Client{ | ||
Transport: &http2.Transport{ | ||
AllowHTTP: !tlsEnabled, | ||
DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) { | ||
if tlsEnabled { | ||
return tls.Dial(network, addr, cfg) | ||
} | ||
return net.Dial(network, addr) | ||
}, | ||
TLSClientConfig: tlsConfig, | ||
}, | ||
} | ||
|
||
return &Client{ | ||
client: client, | ||
Config: cfg, | ||
}, nil | ||
} | ||
|
||
// Run launches a client | ||
func (c *Client) Run() error { | ||
// Establish http connection | ||
req, err := http.NewRequest(c.Method, c.Addr, os.Stdin) | ||
if c.Headers != nil { | ||
for _, h := range c.Headers { | ||
kv := strings.Split(h, ":") | ||
if len(kv) != 2 { | ||
return errors.New("client: error parsing header") | ||
} | ||
k := strings.Trim(kv[0], " ") | ||
v := strings.Trim(kv[1], " ") | ||
fmt.Println(k, " ", v) | ||
req.Header.Add(k, v) | ||
} | ||
} | ||
if err != nil { | ||
return err | ||
} | ||
resp, err := c.client.Do(req) | ||
if err != nil { | ||
return err | ||
} | ||
defer func() { | ||
if err := resp.Body.Close(); err != nil { | ||
log.Println(err) | ||
} | ||
}() | ||
|
||
log.Println(fmt.Sprintf("Connected to %s", c.Addr)) | ||
io.Copy(os.Stdout, resp.Body) | ||
return nil | ||
} |
Oops, something went wrong.