Skip to content
Closed
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
7 changes: 6 additions & 1 deletion cli/jprqc.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"strings"

"github.com/azimjohn/jprq/cli/debugger"
qr_coder "github.com/azimjohn/jprq/cli/utils"
"github.com/azimjohn/jprq/server/events"
"github.com/azimjohn/jprq/server/tunnel"
)
Expand All @@ -23,7 +24,7 @@ type jprqClient struct {
httpDebugger debugger.Debugger
}

func (j *jprqClient) Start(port int, debug bool) {
func (j *jprqClient) Start(port int, debug bool, gen_qe bool) {
eventCon, err := net.Dial("tcp", j.config.Remote.Events)
if err != nil {
log.Fatalf("failed to connect to event server: %s\n", err)
Expand Down Expand Up @@ -62,6 +63,10 @@ func (j *jprqClient) Start(port int, debug bool) {
fmt.Printf("Status: \t Online \n")
fmt.Printf("Protocol: \t %s \n", strings.ToUpper(j.protocol))
fmt.Printf("Forwarded: \t %s -> %s \n", strings.TrimSuffix(j.publicServer, ":80"), j.localServer)
if gen_qe {
fmt.Println("Qr Code:")
qr_coder.GenerateQRStr(j.publicServer)
}

if j.protocol == "http" && debug {
j.httpDebugger = debugger.New()
Expand Down
84 changes: 61 additions & 23 deletions cli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type Flags struct {
debug bool
cname string
subdomain string
qr bool
}

func printVersion() {
Expand All @@ -26,16 +27,18 @@ func printVersion() {
}

func printHelp() {
fmt.Printf("Usage: jprq <command> [arguments]\n\n")
fmt.Printf("Usage: jprq <command> [arguments] [flags]\n\n")
fmt.Println("Commands:")
fmt.Println(" auth <token> Set authentication token from jprq.io/auth")
fmt.Println(" tcp <port> Start a TCP tunnel on the specified port")
fmt.Println(" http <port> Start an HTTP tunnel on the specified port")
fmt.Println(" http <port> -s <subdomain> Start an HTTP tunnel with a custom subdomain")
fmt.Println(" http <port> --debug Debug an HTTP tunnel with Jprq Debugger")
fmt.Println(" serve <dir> Serve files with built-in Http Server")
fmt.Println(" file <file> Serve a file with built-in Http Server")
fmt.Println(" --help Show this help message")
fmt.Println(" --version Show the version number")
fmt.Println(" --qr Generate QR code for public URL")
os.Exit(0)
}

Expand Down Expand Up @@ -65,8 +68,8 @@ func main() {
switch command {
case "auth":
handleAuth(arg)
case "serve":
protocol, port = handleServe(arg)
case "serve", "file":
protocol, port = handleServe(command, arg)
case "tcp", "http":
protocol = command
port, _ = strconv.Atoi(arg)
Expand All @@ -93,7 +96,7 @@ func main() {
cname: flags.cname,
}

go client.Start(port, flags.debug)
go client.Start(port, flags.debug, flags.qr)

signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
Expand All @@ -110,6 +113,8 @@ func parseFlags(args []string) Flags {
flags.subdomain = args[i+1]
case "-c", "-cname", "--cname":
flags.cname = args[i+1]
case "--qr", "--share-qr":
flags.qr = true
}
}
return flags
Expand All @@ -128,27 +133,60 @@ func handleAuth(token string) {
os.Exit(0)
}

func handleServe(dir string) (string, int) {
dir, err := filepath.Abs(dir)
if err != nil {
log.Fatalf("no such dir %s", dir)
}
func handleServe(command, path string) (string, int) {


handler := http.FileServer(http.Dir(dir))
listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf("failed to start server: %s", err)
}

port := listener.Addr().(*net.TCPAddr).Port
go func() {
if err := http.Serve(listener, handler); err != nil {
log.Fatalf("cannot serve files on %s: %s", dir, err)
if command == "serve" {


dir, err := filepath.Abs(path)
if err != nil {
log.Fatalf("no such %s %s", command, dir)
}
}()

time.AfterFunc(600*time.Millisecond, func() {
log.Println("Serving: \t", dir)
})
return "http", port
handler := http.FileServer(http.Dir(dir))
listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf("failed to start server: %s", err)
}

port := listener.Addr().(*net.TCPAddr).Port
go func() {
if err := http.Serve(listener, handler); err != nil {
log.Fatalf("cannot serve files on %s: %s", dir, err)
}
}()

time.AfterFunc(600*time.Millisecond, func() {
log.Println("Serving: \t", dir)
})
return "http", port
} else {
_, err := os.ReadFile(path)
if err != nil {
log.Fatalf("no such %s %s", command, path)
}

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
http.ServeFile(w, r, path)
})

listener, err := net.Listen("tcp", ":0")
if err != nil {
log.Fatalf("failed to start server: %s", err)
}

port := listener.Addr().(*net.TCPAddr).Port
go func() {
if err := http.Serve(listener, handler); err != nil {
log.Fatalf("cannot serve file %s: %s", path, err)
}
}()

time.AfterFunc(600*time.Millisecond, func() {
log.Println("Serving: \t", path)
})
return "http", port
}
}
20 changes: 20 additions & 0 deletions cli/utils/qr_coder.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package qr_coder

import (
"fmt"

qrcode "github.com/skip2/go-qrcode"
)

func GenerateQRStr(content string) error {

q, err := qrcode.New(content, qrcode.Medium)
if err != nil {
fmt.Printf("\033[38;5;208mError: could not generate QRCode: %v\033[0m\n", err) // color is orange
return err
}
fmt.Println(q.ToSmallString(false))
fmt.Println()
return nil

}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ module github.com/azimjohn/jprq

go 1.22

toolchain go1.23.4

require (
github.com/djherbis/buffer v1.2.0
github.com/djherbis/nio/v3 v3.0.1
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ github.com/djherbis/buffer v1.2.0 h1:PH5Dd2ss0C7CRRhQCZ2u7MssF+No9ide8Ye71nPHcrQ
github.com/djherbis/buffer v1.2.0/go.mod h1:fjnebbZjCUpPinBRD+TDwXSOeNQ7fPQWLfGQqiAiUyE=
github.com/djherbis/nio/v3 v3.0.1 h1:6wxhnuppteMa6RHA4L81Dq7ThkZH8SwnDzXDYy95vB4=
github.com/djherbis/nio/v3 v3.0.1/go.mod h1:Ng4h80pbZFMla1yKzm61cF0tqqilXZYrogmWgZxOcmg=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
Binary file added jprq-linux-amd64
Binary file not shown.
Loading