Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
Juby210 committed May 23, 2023
0 parents commit b53aaba
Show file tree
Hide file tree
Showing 10 changed files with 973 additions and 0 deletions.
62 changes: 62 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
name: Release
on:
push:
tags:
- v*

permissions:
contents: write

jobs:
build-windows:
runs-on: windows-latest

steps:
- name: Install Go
uses: actions/setup-go@v3
with:
go-version: "1.20.4"

- name: Checkout code
uses: actions/checkout@v3

- uses: actions/cache@v3
with:
path: |
~\AppData\Local\go-build
~\go\pkg\mod
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
location: D:\

- name: Install WebView2
shell: msys2 {0}
run: |
cd /d
mkdir webview2
cd webview2
curl -sSL "https://www.nuget.org/api/v2/package/Microsoft.Web.WebView2" | bsdtar -xvf-
- name: Build
shell: cmd
run: |
set Path=%Path%;D:\msys64\mingw64\bin
set CGO_CXXFLAGS=-ID:\webview2\build\native\include
go build -v -ldflags "-s -w -H=windowsgui" -o httptoolkit-desktop-go.exe .
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: build
path: httptoolkit-desktop-go.exe

- name: Release
uses: softprops/action-gh-release@1e07f4398721186383de40550babbdf2b84acfc5 # v1
with:
name: ${{ github.ref_name }}
files: httptoolkit-desktop-go.exe
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
httptoolkit-server
httptoolkit-desktop-go*
661 changes: 661 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# HTTP Toolkit Desktop Go
Unofficial desktop app for HTTP Toolkit in Go.

Supports only Windows, because of webkit/webview lib bug on Linux https://github.com/webview/webview/issues/241
13 changes: 13 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module httptoolkit-desktop-go

go 1.20

require (
github.com/harry1453/go-common-file-dialog v1.2.0
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc
)

require (
github.com/go-ole/go-ole v1.2.4 // indirect
github.com/google/uuid v1.1.1 // indirect
)
8 changes: 8 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI=
github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM=
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/harry1453/go-common-file-dialog v1.2.0 h1:nGr9ZIpXrKb7IUY9Or6jqt4nuPEd/I+5sH1JPMsKhaM=
github.com/harry1453/go-common-file-dialog v1.2.0/go.mod h1:3zwmbo7fy+uYGyaec74mu+Z9DPg0aEt10fSjjPwfyiY=
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc h1:3LWOLV/SbVjPYCARWGcRpOKP30U/I6EP1v8PSIoh1aU=
github.com/webview/webview v0.0.0-20230415172654-8387ff8945fc/go.mod h1:rpXAuuHgyEJb6kXcXldlkOjU6y4x+YcASKKXJNUhh0Y=
94 changes: 94 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package main

import (
"fmt"
"net/http"
"os"
"os/exec"
"strings"
"time"

"github.com/harry1453/go-common-file-dialog/cfd"
"github.com/harry1453/go-common-file-dialog/cfdutil"
"github.com/webview/webview"
)

var (
cmd *exec.Cmd
serverKilled = false
)

func main() {
w := webview.New(true)
defer w.Destroy()
w.SetTitle("HTTP Toolkit")
w.SetSize(1366, 768, webview.HintNone)
w.SetHtml("Setting up server..<script>window.onload=()=>_onload()</script>")

w.Bind("_onload", func() {
go func() {
if err := setupServer(); err != nil {
w.Dispatch(func() {
w.SetHtml("error while setting up server: <pre>" + err.Error() + "</pre>")
})
} else {
w.Dispatch(func() {
w.Navigate("https://juby-httptoolkit.github.io")
})

out, err := startServer()
serverKilled = true
w.Dispatch(func() {
if err != nil {
w.SetHtml("server error: <pre>" + err.Error() + "\n\n" + string(out) + "</pre>")
} else {
w.SetHtml("server stopped <pre>" + string(out) + "</pre>")
}
})
}
}()
})

//goland:noinspection ALL
if platform == "win32" {
w.Bind("prompt", func(_ string) string {
result, err := cfdutil.ShowOpenFileDialog(cfd.DialogConfig{})
if err != cfd.ErrorCancelled {
fmt.Println(err)
}
return result
})
}

w.Run()

if !serverKilled && cmd != nil {
req, err := http.NewRequest(
"POST",
"http://127.0.0.1:45457",
strings.NewReader(`{"operationName":"Shutdown","query":"mutation Shutdown { shutdown }","variables":{}}`),
)
if err == nil {
req.Header.Set("content-type", "application/json")
req.Header.Set("origin", "https://app.httptoolkit.tech")
c := &http.Client{Timeout: 3 * time.Second}
_, err = c.Do(req)
if err == nil {
fmt.Println("soft shutdown")
}
}
}
}

func startServer() ([]byte, error) {
cmd = exec.Command("bin/node", "bin/run", "start")
cmd.Dir = "httptoolkit-server"
cmd.Env = append(
os.Environ(),
"HTTPTOOLKIT_SERVER_BINPATH="+binPath,
"NODE_SKIP_PLATFORM_CHECK=1",
`NODE_OPTIONS="--max-http-header-size=102400 --insecure-http-parser"`,
)
hideWindow()
return cmd.CombinedOutput()
}
102 changes: 102 additions & 0 deletions setup_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package main

import (
"archive/tar"
"compress/gzip"
"fmt"
"io"
"net/http"
"os"
)

const requiredVersion = "1.12.6"

func setupServer() error {
if _, err := os.Stat("httptoolkit-server/package.json"); err != nil {
if err = downloadServer(); err != nil {
return err
}
}
return nil
}

func downloadServer() error {
fmt.Println("Downloading httptoolkit-server " + requiredVersion + " for " + platform)
fileName := "httptoolkit-server.tar.gz"
err := dl(
fmt.Sprintf(
"https://github.com/juby-httptoolkit/httptoolkit-server/releases/download/v%s/httptoolkit-server-v%s-%s-x64.tar.gz",
requiredVersion, requiredVersion, platform,
),
fileName,
)
if err != nil {
return err
}
file, err := os.Open(fileName)
if err != nil {
return err
}
err = extract(file)
file.Close()
if err != nil {
return err
}
os.Remove(fileName)
fmt.Println("Server download completed")
return nil
}

func dl(url, path string) error {
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()

file, err := os.Create(path)
if err != nil {
return err
}
_, err = io.Copy(file, resp.Body)
if err != nil {
return err
}
return file.Close()
}

// https://codereview.stackexchange.com/questions/272457/decompress-tar-gz-file-in-go
func extract(gzipStream io.Reader) error {
uncompressedStream, err := gzip.NewReader(gzipStream)
if err != nil {
return err
}

tarReader := tar.NewReader(uncompressedStream)
var header *tar.Header
for header, err = tarReader.Next(); err == nil; header, err = tarReader.Next() {
switch header.Typeflag {
case tar.TypeDir:
if err := os.Mkdir(header.Name, 0755); err != nil {
return fmt.Errorf("extract: Mkdir() failed: %w", err)
}
case tar.TypeReg:
outFile, err := os.Create(header.Name)
if err != nil {
return fmt.Errorf("extract: Create() failed: %w", err)
}

if _, err = io.Copy(outFile, tarReader); err != nil {
outFile.Close()
return fmt.Errorf("extract: Copy() failed: %w", err)
}
if err = outFile.Close(); err != nil {
return fmt.Errorf("extract: Close() failed: %w", err)
}
}
}
if err != io.EOF {
return fmt.Errorf("extract: Next() failed: %w", err)
}
return nil
}
12 changes: 12 additions & 0 deletions utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//go:build !windows

package main

import "runtime"

const (
binPath = "bin/httptoolkit-server"
platform = runtime.GOOS
)

func hideWindow() {}
14 changes: 14 additions & 0 deletions utils_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//go:build windows

package main

import "syscall"

const (
binPath = "bin/httptoolkit-server.cmd"
platform = "win32"
)

func hideWindow() {
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
}

0 comments on commit b53aaba

Please sign in to comment.