this repo has no description smallweb.run
smallweb
4
fork

Configure Feed

Select the types of activity you want to include in your feed.

add std decoding

pomdtr 4e5aedc6 0e3c9d30

+96 -109
+16 -11
api/api.go
··· 2 2 3 3 import ( 4 4 "embed" 5 + "encoding/base64" 5 6 "encoding/json" 6 7 "errors" 7 8 "fmt" ··· 34 35 35 36 type Server struct { 36 37 domain string 37 - dir string 38 38 httpWriter *utils.MultiWriter 39 39 consoleWriter *utils.MultiWriter 40 40 } 41 41 42 - func NewHandler(dir string, domain string, httpWriter *utils.MultiWriter, consoleWriter *utils.MultiWriter) http.Handler { 43 - server := &Server{domain: domain, dir: dir, httpWriter: httpWriter, consoleWriter: consoleWriter} 42 + func NewHandler(domain string, httpWriter *utils.MultiWriter, consoleWriter *utils.MultiWriter) http.Handler { 43 + server := &Server{domain: domain, httpWriter: httpWriter, consoleWriter: consoleWriter} 44 44 handler := Handler(server) 45 45 webdavHandler := webdav.Handler{ 46 - FileSystem: webdav.Dir(dir), 46 + FileSystem: webdav.Dir(utils.RootDir()), 47 47 LockSystem: webdav.NewMemLS(), 48 48 Prefix: "/webdav", 49 49 } ··· 62 62 } 63 63 64 64 appname := strings.TrimSuffix(d, "."+domain) 65 - appDir := filepath.Join(dir, appname) 65 + appDir := filepath.Join(utils.RootDir(), appname) 66 66 if _, err := app.LoadApp(appDir, domain); err != nil { 67 67 http.Error(w, err.Error(), http.StatusInternalServerError) 68 68 return ··· 128 128 129 129 // GetV0AppsAppEnv implements ServerInterface. 130 130 func (me *Server) GetApp(w http.ResponseWriter, r *http.Request, appname string) { 131 - a, err := app.LoadApp(filepath.Join(me.dir, appname), me.domain) 131 + a, err := app.LoadApp(filepath.Join(utils.RootDir(), appname), me.domain) 132 132 if err != nil { 133 133 http.Error(w, err.Error(), http.StatusInternalServerError) 134 134 return ··· 175 175 } 176 176 177 177 func (me *Server) GetApps(w http.ResponseWriter, r *http.Request) { 178 - names, err := app.ListApps(me.dir) 178 + names, err := app.ListApps(utils.RootDir()) 179 179 if err != nil { 180 180 http.Error(w, err.Error(), http.StatusInternalServerError) 181 181 return ··· 183 183 184 184 var apps []App 185 185 for _, name := range names { 186 - a, err := app.LoadApp(filepath.Join(me.dir, name), me.domain) 186 + a, err := app.LoadApp(filepath.Join(utils.RootDir(), name), me.domain) 187 187 if err != nil { 188 188 http.Error(w, err.Error(), http.StatusInternalServerError) 189 189 return ··· 268 268 } 269 269 270 270 res.Success = res.Code == 0 271 - res.Stdout = stdout.String() 272 - res.Stderr = stderr.String() 271 + res.Stdout = base64.StdEncoding.EncodeToString([]byte(stdout.String())) 272 + res.Stderr = base64.StdEncoding.EncodeToString([]byte(stderr.String())) 273 273 274 274 w.Header().Set("Content-Type", "application/json") 275 275 if err := json.NewEncoder(w).Encode(res); err != nil { ··· 279 279 } 280 280 281 281 func (me *Server) GetHttpLogs(w http.ResponseWriter, r *http.Request, params GetHttpLogsParams) { 282 + if me.httpWriter == nil { 283 + http.Error(w, "Logging unsupported", http.StatusInternalServerError) 284 + return 285 + } 286 + 282 287 flusher, ok := w.(http.Flusher) 283 288 if !ok { 284 289 http.Error(w, "Streaming unsupported", http.StatusInternalServerError) ··· 337 342 338 343 func (me *Server) GetConsoleLogs(w http.ResponseWriter, r *http.Request, params GetConsoleLogsParams) { 339 344 if me.consoleWriter == nil { 340 - http.Error(w, "Streaming unsupported", http.StatusInternalServerError) 345 + http.Error(w, "Logging unsupported", http.StatusInternalServerError) 341 346 return 342 347 } 343 348
+76
cmd/api.go
··· 1 + package cmd 2 + 3 + import ( 4 + "encoding/json" 5 + "fmt" 6 + "io" 7 + "net/http/httptest" 8 + "os" 9 + "strings" 10 + 11 + "github.com/pomdtr/smallweb/api" 12 + "github.com/spf13/cobra" 13 + ) 14 + 15 + func NewCmdAPI() *cobra.Command { 16 + var flags struct { 17 + method string 18 + headers []string 19 + data string 20 + } 21 + 22 + cmd := &cobra.Command{ 23 + Use: "api", 24 + Short: "Interact with the smallweb API", 25 + Args: cobra.ExactArgs(1), 26 + RunE: func(cmd *cobra.Command, args []string) error { 27 + var body io.Reader 28 + if flags.data != "" { 29 + body = strings.NewReader(flags.data) 30 + } else if flags.data == "@-" { 31 + body = os.Stdin 32 + } 33 + 34 + req := httptest.NewRequest(flags.method, "http://smallweb"+args[0], body) 35 + 36 + for _, header := range flags.headers { 37 + parts := strings.SplitN(header, ":", 2) 38 + if len(parts) != 2 { 39 + return fmt.Errorf("invalid header: %s", header) 40 + } 41 + 42 + req.Header.Add(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])) 43 + } 44 + 45 + handler := api.NewHandler(k.String("domain"), nil, nil) 46 + w := httptest.NewRecorder() 47 + handler.ServeHTTP(w, req) 48 + 49 + if w.Header().Get("Content-Type") == "application/json" { 50 + var v any 51 + decoder := json.NewDecoder(w.Body) 52 + if err := decoder.Decode(&v); err != nil { 53 + return fmt.Errorf("failed to decode JSON: %w", err) 54 + } 55 + 56 + encoder := json.NewEncoder(os.Stdout) 57 + encoder.SetEscapeHTML(false) 58 + encoder.SetIndent("", " ") 59 + if err := encoder.Encode(v); err != nil { 60 + return fmt.Errorf("failed to encode JSON: %w", err) 61 + } 62 + 63 + return nil 64 + } 65 + 66 + _, _ = io.Copy(os.Stdout, w.Body) 67 + return nil 68 + }, 69 + } 70 + 71 + cmd.Flags().StringVarP(&flags.method, "method", "X", "GET", "HTTP method to use") 72 + cmd.Flags().StringArrayVarP(&flags.headers, "header", "H", nil, "HTTP headers to use") 73 + cmd.Flags().StringVarP(&flags.data, "data", "d", "", "Data to send in the request body") 74 + 75 + return cmd 76 + }
+1
cmd/root.go
··· 76 76 cmd.AddCommand(NewCmdService()) 77 77 cmd.AddCommand(NewCmdConfig()) 78 78 cmd.AddCommand(NewCmdCreate()) 79 + cmd.AddCommand(NewCmdAPI()) 79 80 cmd.AddCommand(NewCmdOpen()) 80 81 cmd.AddCommand(NewCmdList()) 81 82 cmd.AddCommand(NewCmdRename())
+1 -96
cmd/run.go
··· 1 1 package cmd 2 2 3 3 import ( 4 - "context" 5 - "encoding/json" 6 4 "fmt" 7 - "io" 8 - "net" 9 - "net/http" 10 5 "os" 11 6 "path/filepath" 12 7 "strings" 13 8 14 - "github.com/pomdtr/smallweb/api" 15 9 "github.com/pomdtr/smallweb/app" 16 10 "github.com/pomdtr/smallweb/utils" 17 11 "github.com/pomdtr/smallweb/worker" ··· 41 35 return fmt.Errorf("failed to get app: %w", err) 42 36 } 43 37 44 - if app.Entrypoint() == "smallweb:api" { 45 - apiCmd := NewCmdAPI() 46 - apiCmd.SetArgs(args[1:]) 47 - 48 - apiCmd.SetIn(os.Stdin) 49 - apiCmd.SetOut(os.Stdout) 50 - apiCmd.SetErr(os.Stderr) 51 - 52 - return apiCmd.Execute() 53 - } 54 - 55 38 if strings.HasPrefix(app.Config.Entrypoint, "smallweb:") { 56 - return fmt.Errorf("smallweb built-in apps cannot be run") 39 + return fmt.Errorf("smallweb built-in apps do not support running as a CLI") 57 40 } 58 41 59 42 worker := worker.NewWorker(app, nil) ··· 72 55 73 56 return cmd 74 57 } 75 - 76 - func NewCmdAPI() *cobra.Command { 77 - var flags struct { 78 - method string 79 - headers []string 80 - data string 81 - } 82 - 83 - cmd := &cobra.Command{ 84 - Use: "api", 85 - Short: "Interact with the smallweb API", 86 - SilenceUsage: true, 87 - Args: cobra.ExactArgs(1), 88 - RunE: func(cmd *cobra.Command, args []string) error { 89 - var body io.Reader 90 - if flags.data != "" { 91 - body = strings.NewReader(flags.data) 92 - } else if flags.data == "@-" { 93 - body = os.Stdin 94 - } 95 - 96 - // use api unix socket if available 97 - client := &http.Client{ 98 - Transport: &http.Transport{ 99 - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { 100 - return net.Dial("unix", api.SocketPath(k.String("domain"))) 101 - }, 102 - }, 103 - } 104 - 105 - req, err := http.NewRequest(flags.method, "http://smallweb"+args[0], body) 106 - if err != nil { 107 - return fmt.Errorf("failed to create request: %w", err) 108 - } 109 - 110 - for _, header := range flags.headers { 111 - parts := strings.SplitN(header, ":", 2) 112 - if len(parts) != 2 { 113 - return fmt.Errorf("invalid header: %s", header) 114 - } 115 - 116 - req.Header.Add(strings.TrimSpace(parts[0]), strings.TrimSpace(parts[1])) 117 - } 118 - 119 - resp, err := client.Do(req) 120 - if err != nil { 121 - return fmt.Errorf("failed to send request: %w", err) 122 - } 123 - defer resp.Body.Close() 124 - 125 - if resp.Header.Get("Content-Type") == "application/json" { 126 - var v any 127 - decoder := json.NewDecoder(resp.Body) 128 - if err := decoder.Decode(&v); err != nil { 129 - return fmt.Errorf("failed to decode JSON: %w", err) 130 - } 131 - 132 - encoder := json.NewEncoder(os.Stdout) 133 - encoder.SetEscapeHTML(false) 134 - encoder.SetIndent("", " ") 135 - if err := encoder.Encode(v); err != nil { 136 - return fmt.Errorf("failed to encode JSON: %w", err) 137 - } 138 - 139 - return nil 140 - } 141 - 142 - _, _ = io.Copy(os.Stdout, resp.Body) 143 - return nil 144 - }, 145 - } 146 - 147 - cmd.Flags().StringVarP(&flags.method, "method", "X", "GET", "HTTP method to use") 148 - cmd.Flags().StringArrayVarP(&flags.headers, "header", "H", nil, "HTTP headers to use") 149 - cmd.Flags().StringVarP(&flags.data, "data", "d", "", "Data to send in the request body") 150 - 151 - return cmd 152 - }
+1 -1
cmd/tunnel.go
··· 24 24 ValidArgsFunction: completeApp(utils.RootDir()), 25 25 RunE: func(cmd *cobra.Command, args []string) error { 26 26 appHandler := AppHandler{ 27 - apiServer: api.NewHandler(utils.RootDir(), k.String("domain"), nil, nil), 27 + apiServer: api.NewHandler(k.String("domain"), nil, nil), 28 28 logger: slog.New(slog.NewJSONHandler(os.Stderr, nil)), 29 29 } 30 30
+1 -1
cmd/up.go
··· 44 44 45 45 consoleLogger := slog.New(slog.NewJSONHandler(consoleWriter, nil)) 46 46 47 - apiHandler := api.NewHandler(utils.RootDir(), k.String("domain"), httpWriter, consoleWriter) 47 + apiHandler := api.NewHandler(k.String("domain"), httpWriter, consoleWriter) 48 48 appHandler := &AppHandler{apiServer: apiHandler, logger: consoleLogger} 49 49 handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 50 50 rootDir := utils.RootDir()