Skip to content

Commit b53aaba

Browse files
committed
init
0 parents  commit b53aaba

File tree

10 files changed

+973
-0
lines changed

10 files changed

+973
-0
lines changed

.github/workflows/release.yml

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
name: Release
2+
on:
3+
push:
4+
tags:
5+
- v*
6+
7+
permissions:
8+
contents: write
9+
10+
jobs:
11+
build-windows:
12+
runs-on: windows-latest
13+
14+
steps:
15+
- name: Install Go
16+
uses: actions/setup-go@v3
17+
with:
18+
go-version: "1.20.4"
19+
20+
- name: Checkout code
21+
uses: actions/checkout@v3
22+
23+
- uses: actions/cache@v3
24+
with:
25+
path: |
26+
~\AppData\Local\go-build
27+
~\go\pkg\mod
28+
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
29+
restore-keys: |
30+
${{ runner.os }}-go-
31+
32+
- name: Setup MSYS2
33+
uses: msys2/setup-msys2@v2
34+
with:
35+
location: D:\
36+
37+
- name: Install WebView2
38+
shell: msys2 {0}
39+
run: |
40+
cd /d
41+
mkdir webview2
42+
cd webview2
43+
curl -sSL "https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2" | bsdtar -xvf-
44+
45+
- name: Build
46+
shell: cmd
47+
run: |
48+
set Path=%Path%;D:\msys64\mingw64\bin
49+
set CGO_CXXFLAGS=-ID:\webview2\build\native\include
50+
go build -v -ldflags "-s -w -H=windowsgui" -o httptoolkit-desktop-go.exe .
51+
52+
- name: Upload artifact
53+
uses: actions/upload-artifact@v3
54+
with:
55+
name: build
56+
path: httptoolkit-desktop-go.exe
57+
58+
- name: Release
59+
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5 # v1
60+
with:
61+
name: ${{ github.ref_name }}
62+
files: httptoolkit-desktop-go.exe

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea
2+
httptoolkit-server
3+
httptoolkit-desktop-go*

LICENSE

+661
Large diffs are not rendered by default.

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# HTTP Toolkit Desktop Go
2+
Unofficial desktop app for HTTP Toolkit in Go.
3+
4+
Supports only Windows, because of webkit/webview lib bug on Linux https://github.com/webview/webview/issues/241

go.mod

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module httptoolkit-desktop-go
2+
3+
go 1.20
4+
5+
require (
6+
github.com/harry1453/go-common-file-dialog v1.2.0
7+
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc
8+
)
9+
10+
require (
11+
github.com/go-ole/go-ole v1.2.4 // indirect
12+
github.com/google/uuid v1.1.1 // indirect
13+
)

go.sum

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
2+
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
3+
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
4+
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
5+
github.com/harry1453/go-common-file-dialog v1.2.0 h1:nGr9ZIpXrKb7IUY9Or6jqt4nuPEd/I+5sH1JPMsKhaM=
6+
github.com/harry1453/go-common-file-dialog v1.2.0/go.mod h1:3zwmbo7fy+uYGyaec74mu+Z9DPg0aEt10fSjjPwfyiY=
7+
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc h1:3LWOLV/SbVjPYCARWGcRpOKP30U/I6EP1v8PSIoh1aU=
8+
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc/go.mod h1:rpXAuuHgyEJb6kXcXldlkOjU6y4x+YcASKKXJNUhh0Y=

main.go

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"net/http"
6+
"os"
7+
"os/exec"
8+
"strings"
9+
"time"
10+
11+
"github.com/harry1453/go-common-file-dialog/cfd"
12+
"github.com/harry1453/go-common-file-dialog/cfdutil"
13+
"github.com/webview/webview"
14+
)
15+
16+
var (
17+
cmd *exec.Cmd
18+
serverKilled = false
19+
)
20+
21+
func main() {
22+
w := webview.New(true)
23+
defer w.Destroy()
24+
w.SetTitle("HTTP Toolkit")
25+
w.SetSize(1366, 768, webview.HintNone)
26+
w.SetHtml("Setting up server..<script>window.onload=()=>_onload()</script>")
27+
28+
w.Bind("_onload", func() {
29+
go func() {
30+
if err := setupServer(); err != nil {
31+
w.Dispatch(func() {
32+
w.SetHtml("error while setting up server: <pre>" + err.Error() + "</pre>")
33+
})
34+
} else {
35+
w.Dispatch(func() {
36+
w.Navigate("https://juby-httptoolkit.github.io")
37+
})
38+
39+
out, err := startServer()
40+
serverKilled = true
41+
w.Dispatch(func() {
42+
if err != nil {
43+
w.SetHtml("server error: <pre>" + err.Error() + "\n\n" + string(out) + "</pre>")
44+
} else {
45+
w.SetHtml("server stopped <pre>" + string(out) + "</pre>")
46+
}
47+
})
48+
}
49+
}()
50+
})
51+
52+
//goland:noinspection ALL
53+
if platform == "win32" {
54+
w.Bind("prompt", func(_ string) string {
55+
result, err := cfdutil.ShowOpenFileDialog(cfd.DialogConfig{})
56+
if err != cfd.ErrorCancelled {
57+
fmt.Println(err)
58+
}
59+
return result
60+
})
61+
}
62+
63+
w.Run()
64+
65+
if !serverKilled && cmd != nil {
66+
req, err := http.NewRequest(
67+
"POST",
68+
"http://127.0.0.1:45457",
69+
strings.NewReader(`{"operationName":"Shutdown","query":"mutation Shutdown { shutdown }","variables":{}}`),
70+
)
71+
if err == nil {
72+
req.Header.Set("content-type", "application/json")
73+
req.Header.Set("origin", "https://app.httptoolkit.tech")
74+
c := &http.Client{Timeout: 3 * time.Second}
75+
_, err = c.Do(req)
76+
if err == nil {
77+
fmt.Println("soft shutdown")
78+
}
79+
}
80+
}
81+
}
82+
83+
func startServer() ([]byte, error) {
84+
cmd = exec.Command("bin/node", "bin/run", "start")
85+
cmd.Dir = "httptoolkit-server"
86+
cmd.Env = append(
87+
os.Environ(),
88+
"HTTPTOOLKIT_SERVER_BINPATH="+binPath,
89+
"NODE_SKIP_PLATFORM_CHECK=1",
90+
`NODE_OPTIONS="--max-http-header-size=102400 --insecure-http-parser"`,
91+
)
92+
hideWindow()
93+
return cmd.CombinedOutput()
94+
}

setup_server.go

+102
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
package main
2+
3+
import (
4+
"archive/tar"
5+
"compress/gzip"
6+
"fmt"
7+
"io"
8+
"net/http"
9+
"os"
10+
)
11+
12+
const requiredVersion = "1.12.6"
13+
14+
func setupServer() error {
15+
if _, err := os.Stat("httptoolkit-server/package.json"); err != nil {
16+
if err = downloadServer(); err != nil {
17+
return err
18+
}
19+
}
20+
return nil
21+
}
22+
23+
func downloadServer() error {
24+
fmt.Println("Downloading httptoolkit-server " + requiredVersion + " for " + platform)
25+
fileName := "httptoolkit-server.tar.gz"
26+
err := dl(
27+
fmt.Sprintf(
28+
"https://github.com/juby-httptoolkit/httptoolkit-server/releases/download/v%s/httptoolkit-server-v%s-%s-x64.tar.gz",
29+
requiredVersion, requiredVersion, platform,
30+
),
31+
fileName,
32+
)
33+
if err != nil {
34+
return err
35+
}
36+
file, err := os.Open(fileName)
37+
if err != nil {
38+
return err
39+
}
40+
err = extract(file)
41+
file.Close()
42+
if err != nil {
43+
return err
44+
}
45+
os.Remove(fileName)
46+
fmt.Println("Server download completed")
47+
return nil
48+
}
49+
50+
func dl(url, path string) error {
51+
resp, err := http.Get(url)
52+
if err != nil {
53+
return err
54+
}
55+
defer resp.Body.Close()
56+
57+
file, err := os.Create(path)
58+
if err != nil {
59+
return err
60+
}
61+
_, err = io.Copy(file, resp.Body)
62+
if err != nil {
63+
return err
64+
}
65+
return file.Close()
66+
}
67+
68+
// https://codereview.stackexchange.com/questions/272457/decompress-tar-gz-file-in-go
69+
func extract(gzipStream io.Reader) error {
70+
uncompressedStream, err := gzip.NewReader(gzipStream)
71+
if err != nil {
72+
return err
73+
}
74+
75+
tarReader := tar.NewReader(uncompressedStream)
76+
var header *tar.Header
77+
for header, err = tarReader.Next(); err == nil; header, err = tarReader.Next() {
78+
switch header.Typeflag {
79+
case tar.TypeDir:
80+
if err := os.Mkdir(header.Name, 0755); err != nil {
81+
return fmt.Errorf("extract: Mkdir() failed: %w", err)
82+
}
83+
case tar.TypeReg:
84+
outFile, err := os.Create(header.Name)
85+
if err != nil {
86+
return fmt.Errorf("extract: Create() failed: %w", err)
87+
}
88+
89+
if _, err = io.Copy(outFile, tarReader); err != nil {
90+
outFile.Close()
91+
return fmt.Errorf("extract: Copy() failed: %w", err)
92+
}
93+
if err = outFile.Close(); err != nil {
94+
return fmt.Errorf("extract: Close() failed: %w", err)
95+
}
96+
}
97+
}
98+
if err != io.EOF {
99+
return fmt.Errorf("extract: Next() failed: %w", err)
100+
}
101+
return nil
102+
}

utils.go

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//go:build !windows
2+
3+
package main
4+
5+
import "runtime"
6+
7+
const (
8+
binPath = "bin/httptoolkit-server"
9+
platform = runtime.GOOS
10+
)
11+
12+
func hideWindow() {}

utils_windows.go

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//go:build windows
2+
3+
package main
4+
5+
import "syscall"
6+
7+
const (
8+
binPath = "bin/httptoolkit-server.cmd"
9+
platform = "win32"
10+
)
11+
12+
func hideWindow() {
13+
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
14+
}

0 commit comments

Comments
 (0)