this repo has no description smallweb.run
smallweb
4
fork

Configure Feed

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

remove the run endpoint

pomdtr 84f19035 4e5aedc6

+8 -319
-60
api/api.go
··· 2 2 3 3 import ( 4 4 "embed" 5 - "encoding/base64" 6 5 "encoding/json" 7 - "errors" 8 6 "fmt" 9 - "io" 10 7 "io/fs" 11 8 "net/http" 12 9 "os" 13 - "os/exec" 14 10 "path/filepath" 15 11 "strings" 16 12 ··· 219 215 w.Header().Set("Content-Type", "application/json") 220 216 if err := json.NewEncoder(w).Encode(apps); err != nil { 221 217 http.Error(w, err.Error(), http.StatusInternalServerError) 222 - } 223 - } 224 - 225 - func (me *Server) RunApp(w http.ResponseWriter, r *http.Request, app string) { 226 - executable, err := os.Executable() 227 - if err != nil { 228 - http.Error(w, err.Error(), http.StatusInternalServerError) 229 - return 230 - } 231 - 232 - var body RunAppJSONRequestBody 233 - if err := json.NewDecoder(r.Body).Decode(&body); err != nil && !errors.Is(err, io.EOF) { 234 - http.Error(w, err.Error(), http.StatusBadRequest) 235 - return 236 - } 237 - 238 - cmd := exec.Command(executable, "run", app) 239 - cmd.Args = append(cmd.Args, body.Args...) 240 - cmd.Env = os.Environ() 241 - 242 - if strings.Contains(r.Header.Get("Accept"), "text/plain") { 243 - output, err := cmd.CombinedOutput() 244 - if err != nil { 245 - http.Error(w, string(output), http.StatusInternalServerError) 246 - return 247 - } 248 - 249 - w.Header().Set("Content-Type", "text/plain") 250 - w.Write(output) 251 - return 252 - } 253 - 254 - var res CommandOutput 255 - stdout := &strings.Builder{} 256 - stderr := &strings.Builder{} 257 - cmd.Stdout = stdout 258 - cmd.Stderr = stderr 259 - 260 - if err := cmd.Run(); err != nil { 261 - var exitErr *exec.ExitError 262 - if errors.As(err, &exitErr) { 263 - res.Code = exitErr.ExitCode() 264 - } else { 265 - http.Error(w, err.Error(), http.StatusInternalServerError) 266 - return 267 - } 268 - } 269 - 270 - res.Success = res.Code == 0 271 - res.Stdout = base64.StdEncoding.EncodeToString([]byte(stdout.String())) 272 - res.Stderr = base64.StdEncoding.EncodeToString([]byte(stderr.String())) 273 - 274 - w.Header().Set("Content-Type", "application/json") 275 - if err := json.NewEncoder(w).Encode(res); err != nil { 276 - http.Error(w, err.Error(), http.StatusInternalServerError) 277 - return 278 218 } 279 219 } 280 220
+8 -204
api/gen.go
··· 29 29 Url string `json:"url"` 30 30 } 31 31 32 - // CommandOutput defines model for CommandOutput. 33 - type CommandOutput struct { 34 - Code int `json:"code"` 35 - Stderr string `json:"stderr"` 36 - Stdout string `json:"stdout"` 37 - Success bool `json:"success"` 38 - } 39 - 40 32 // GetConsoleLogsParams defines parameters for GetConsoleLogs. 41 33 type GetConsoleLogsParams struct { 42 34 // App Filter logs by app ··· 49 41 Host *string `form:"host,omitempty" json:"host,omitempty"` 50 42 } 51 43 52 - // RunAppJSONBody defines parameters for RunApp. 53 - type RunAppJSONBody struct { 54 - Args []string `json:"args"` 55 - } 56 - 57 - // RunAppJSONRequestBody defines body for RunApp for application/json ContentType. 58 - type RunAppJSONRequestBody RunAppJSONBody 59 - 60 44 // RequestEditorFn is the function signature for the RequestEditor callback function 61 45 type RequestEditorFn func(ctx context.Context, req *http.Request) error 62 46 ··· 141 125 142 126 // GetHttpLogs request 143 127 GetHttpLogs(ctx context.Context, params *GetHttpLogsParams, reqEditors ...RequestEditorFn) (*http.Response, error) 144 - 145 - // RunAppWithBody request with any body 146 - RunAppWithBody(ctx context.Context, app string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) 147 - 148 - RunApp(ctx context.Context, app string, body RunAppJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) 149 128 } 150 129 151 130 func (c *Client) GetApps(ctx context.Context, reqEditors ...RequestEditorFn) (*http.Response, error) { ··· 196 175 return c.Client.Do(req) 197 176 } 198 177 199 - func (c *Client) RunAppWithBody(ctx context.Context, app string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*http.Response, error) { 200 - req, err := NewRunAppRequestWithBody(c.Server, app, contentType, body) 201 - if err != nil { 202 - return nil, err 203 - } 204 - req = req.WithContext(ctx) 205 - if err := c.applyEditors(ctx, req, reqEditors); err != nil { 206 - return nil, err 207 - } 208 - return c.Client.Do(req) 209 - } 210 - 211 - func (c *Client) RunApp(ctx context.Context, app string, body RunAppJSONRequestBody, reqEditors ...RequestEditorFn) (*http.Response, error) { 212 - req, err := NewRunAppRequest(c.Server, app, body) 213 - if err != nil { 214 - return nil, err 215 - } 216 - req = req.WithContext(ctx) 217 - if err := c.applyEditors(ctx, req, reqEditors); err != nil { 218 - return nil, err 219 - } 220 - return c.Client.Do(req) 221 - } 222 - 223 178 // NewGetAppsRequest generates requests for GetApps 224 179 func NewGetAppsRequest(server string) (*http.Request, error) { 225 180 var err error ··· 379 334 return req, nil 380 335 } 381 336 382 - // NewRunAppRequest calls the generic RunApp builder with application/json body 383 - func NewRunAppRequest(server string, app string, body RunAppJSONRequestBody) (*http.Request, error) { 384 - var bodyReader io.Reader 385 - buf, err := json.Marshal(body) 386 - if err != nil { 387 - return nil, err 388 - } 389 - bodyReader = bytes.NewReader(buf) 390 - return NewRunAppRequestWithBody(server, app, "application/json", bodyReader) 391 - } 392 - 393 - // NewRunAppRequestWithBody generates requests for RunApp with any type of body 394 - func NewRunAppRequestWithBody(server string, app string, contentType string, body io.Reader) (*http.Request, error) { 395 - var err error 396 - 397 - var pathParam0 string 398 - 399 - pathParam0, err = runtime.StyleParamWithLocation("simple", false, "app", runtime.ParamLocationPath, app) 400 - if err != nil { 401 - return nil, err 402 - } 403 - 404 - serverURL, err := url.Parse(server) 405 - if err != nil { 406 - return nil, err 407 - } 408 - 409 - operationPath := fmt.Sprintf("/v0/run/%s", pathParam0) 410 - if operationPath[0] == '/' { 411 - operationPath = "." + operationPath 412 - } 413 - 414 - queryURL, err := serverURL.Parse(operationPath) 415 - if err != nil { 416 - return nil, err 417 - } 418 - 419 - req, err := http.NewRequest("POST", queryURL.String(), body) 420 - if err != nil { 421 - return nil, err 422 - } 423 - 424 - req.Header.Add("Content-Type", contentType) 425 - 426 - return req, nil 427 - } 428 - 429 337 func (c *Client) applyEditors(ctx context.Context, req *http.Request, additionalEditors []RequestEditorFn) error { 430 338 for _, r := range c.RequestEditors { 431 339 if err := r(ctx, req); err != nil { ··· 480 388 481 389 // GetHttpLogsWithResponse request 482 390 GetHttpLogsWithResponse(ctx context.Context, params *GetHttpLogsParams, reqEditors ...RequestEditorFn) (*GetHttpLogsResponse, error) 483 - 484 - // RunAppWithBodyWithResponse request with any body 485 - RunAppWithBodyWithResponse(ctx context.Context, app string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RunAppResponse, error) 486 - 487 - RunAppWithResponse(ctx context.Context, app string, body RunAppJSONRequestBody, reqEditors ...RequestEditorFn) (*RunAppResponse, error) 488 391 } 489 392 490 393 type GetAppsResponse struct { ··· 573 476 return 0 574 477 } 575 478 576 - type RunAppResponse struct { 577 - Body []byte 578 - HTTPResponse *http.Response 579 - JSON200 *CommandOutput 580 - } 581 - 582 - // Status returns HTTPResponse.Status 583 - func (r RunAppResponse) Status() string { 584 - if r.HTTPResponse != nil { 585 - return r.HTTPResponse.Status 586 - } 587 - return http.StatusText(0) 588 - } 589 - 590 - // StatusCode returns HTTPResponse.StatusCode 591 - func (r RunAppResponse) StatusCode() int { 592 - if r.HTTPResponse != nil { 593 - return r.HTTPResponse.StatusCode 594 - } 595 - return 0 596 - } 597 - 598 479 // GetAppsWithResponse request returning *GetAppsResponse 599 480 func (c *ClientWithResponses) GetAppsWithResponse(ctx context.Context, reqEditors ...RequestEditorFn) (*GetAppsResponse, error) { 600 481 rsp, err := c.GetApps(ctx, reqEditors...) ··· 631 512 return ParseGetHttpLogsResponse(rsp) 632 513 } 633 514 634 - // RunAppWithBodyWithResponse request with arbitrary body returning *RunAppResponse 635 - func (c *ClientWithResponses) RunAppWithBodyWithResponse(ctx context.Context, app string, contentType string, body io.Reader, reqEditors ...RequestEditorFn) (*RunAppResponse, error) { 636 - rsp, err := c.RunAppWithBody(ctx, app, contentType, body, reqEditors...) 637 - if err != nil { 638 - return nil, err 639 - } 640 - return ParseRunAppResponse(rsp) 641 - } 642 - 643 - func (c *ClientWithResponses) RunAppWithResponse(ctx context.Context, app string, body RunAppJSONRequestBody, reqEditors ...RequestEditorFn) (*RunAppResponse, error) { 644 - rsp, err := c.RunApp(ctx, app, body, reqEditors...) 645 - if err != nil { 646 - return nil, err 647 - } 648 - return ParseRunAppResponse(rsp) 649 - } 650 - 651 515 // ParseGetAppsResponse parses an HTTP response from a GetAppsWithResponse call 652 516 func ParseGetAppsResponse(rsp *http.Response) (*GetAppsResponse, error) { 653 517 bodyBytes, err := io.ReadAll(rsp.Body) ··· 732 596 return response, nil 733 597 } 734 598 735 - // ParseRunAppResponse parses an HTTP response from a RunAppWithResponse call 736 - func ParseRunAppResponse(rsp *http.Response) (*RunAppResponse, error) { 737 - bodyBytes, err := io.ReadAll(rsp.Body) 738 - defer func() { _ = rsp.Body.Close() }() 739 - if err != nil { 740 - return nil, err 741 - } 742 - 743 - response := &RunAppResponse{ 744 - Body: bodyBytes, 745 - HTTPResponse: rsp, 746 - } 747 - 748 - switch { 749 - case strings.Contains(rsp.Header.Get("Content-Type"), "json") && rsp.StatusCode == 200: 750 - var dest CommandOutput 751 - if err := json.Unmarshal(bodyBytes, &dest); err != nil { 752 - return nil, err 753 - } 754 - response.JSON200 = &dest 755 - 756 - case rsp.StatusCode == 200: 757 - // Content-type (text/plain) unsupported 758 - 759 - } 760 - 761 - return response, nil 762 - } 763 - 764 599 // ServerInterface represents all server handlers. 765 600 type ServerInterface interface { 766 601 ··· 775 610 776 611 // (GET /v0/logs/http) 777 612 GetHttpLogs(w http.ResponseWriter, r *http.Request, params GetHttpLogsParams) 778 - 779 - // (POST /v0/run/{app}) 780 - RunApp(w http.ResponseWriter, r *http.Request, app string) 781 613 } 782 614 783 615 // ServerInterfaceWrapper converts contexts to parameters. ··· 882 714 handler.ServeHTTP(w, r) 883 715 } 884 716 885 - // RunApp operation middleware 886 - func (siw *ServerInterfaceWrapper) RunApp(w http.ResponseWriter, r *http.Request) { 887 - 888 - var err error 889 - 890 - // ------------- Path parameter "app" ------------- 891 - var app string 892 - 893 - err = runtime.BindStyledParameterWithOptions("simple", "app", r.PathValue("app"), &app, runtime.BindStyledParameterOptions{ParamLocation: runtime.ParamLocationPath, Explode: false, Required: true}) 894 - if err != nil { 895 - siw.ErrorHandlerFunc(w, r, &InvalidParamFormatError{ParamName: "app", Err: err}) 896 - return 897 - } 898 - 899 - handler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 900 - siw.Handler.RunApp(w, r, app) 901 - })) 902 - 903 - for _, middleware := range siw.HandlerMiddlewares { 904 - handler = middleware(handler) 905 - } 906 - 907 - handler.ServeHTTP(w, r) 908 - } 909 - 910 717 type UnescapedCookieParamError struct { 911 718 ParamName string 912 719 Err error ··· 1031 838 m.HandleFunc("GET "+options.BaseURL+"/v0/apps/{app}", wrapper.GetApp) 1032 839 m.HandleFunc("GET "+options.BaseURL+"/v0/logs/console", wrapper.GetConsoleLogs) 1033 840 m.HandleFunc("GET "+options.BaseURL+"/v0/logs/http", wrapper.GetHttpLogs) 1034 - m.HandleFunc("POST "+options.BaseURL+"/v0/run/{app}", wrapper.RunApp) 1035 841 1036 842 return m 1037 843 } ··· 1039 845 // Base64 encoded, gzipped, json marshaled Swagger object 1040 846 var swaggerSpec = []string{ 1041 847 1042 - "H4sIAAAAAAAC/9SVTW/bPAyA/4rB9z16dbDefOsKrCtQYEN7HHpQbMZRYYuqSHULAv/3gXLTxrGXYB89", 1043 - "7GSBFL8ekfQWKuo8OXTCUG6BqzV2Jh0vvNePD+QxiMUk7IyzK2TRs2w8Qgm0fMBKoM/BmQ73FCzBukYV", 1044 - "MbQz8j6HgI/RBqyh/DpYD3fv86nzS+o64+rPUXyUaWIV1fuxrRNsMKghS40hzObFUlOUeVWsKmTe0y2J", 1045 - "WjRukvfuZj7k8OL1JfK0GnVh3YqSdyut6u4607bfcJldfLmGHJ4wsCUHJSw0HfLojLdQwvnZ4uwccvBG", 1046 - "1im94mlRGO/TucFUjYIxYsld11DCFcqF6jVt9uR4IPZ+sRjAOUGXzIz3ra2SYfHAGnzXEHqygl0y/D/g", 1047 - "Ckr4r3htneK5bwptmv6lXhOC2Qzl1shVsF6Gmm4sS0arLOWtajENK8wkuFfJrqxia7zvTxSXeATToWBQ", 1048 - "P1uwGkYZwa4v1TfsP52EiPlegYftef+HwE5ymnK5QlEmR5C01HBRkWNq8RiUy+HKDTU8hTMO+tG2giFT", 1049 - "z9lykw2YEr/HiGFzCPBvAaNKUN6xBDTdGNyKQmdER846kxI4jDQBd5fcpBpG8JJgDG8t4o+R+yTifwPb", 1050 - "mlh+wu1Z9Q+DC9G9zqEnniF3G92bDuJjRJYPVG9+aQbHPwkTGh6tssnaP1hc402fzOe2ef+Gm2L830tP", 1051 - "hN+l8K2xB15OvvVtdDrdWdXa2Q3T9z8CAAD//4ItGTEPCAAA", 848 + "H4sIAAAAAAAC/9SRQW/bMAyF/4rB7ejVxnrzLRiwrkAPA3occlAc2lFhiSzFdAgC//eBcrMlzpYA2y49", 849 + "ieATH/U+7aGlwBQxaoJmD6ndYHC5XDDbwUKMoh5zM7joO0xqte4YoQFaPWGrMJYQXcAjIan42JuwleE3", 850 + "/bEEweetF1xD822anu4uy7m5Xfaxo2zjdTDtMbhh+I6rYvH1Hkp4QUmeIjRQ205ijI49NHB7U9/cQgns", 851 + "dJNDVC915Zhz3WPOYhmdeor3a2jgDnVhuj0wMcU0hf9Y13a0FBVjHnPMg2/zYPWUbPkBoVVeMeTB94Id", 852 + "NPCu+gW7eiVdGebxZ14n4nZT3DWmVjzrlOnBJy2oK/K7TVbXJ8OWG0vrHGJVe8c8XgmXeYgLqCjmswdv", 853 + "a4wRHH7SvOH4k1S2WB4FnH/o8h+BXeV0zuUO1ZhcQDJQn6qWYqIBL0H5NF15oD6dwzld+tkPilKYc7Ha", 854 + "FROmzO95i7KbA/xfwKhV1A9JBV04BdeRBKfQwMpHlx8w33QG7jHb5Awn8HLjFN5GlS+R+6LKf4FtQ0n/", 855 + "wO1VepPgxvFHAAAA//+qymDlVQUAAA==", 1052 856 } 1053 857 1054 858 // GetSwagger returns the content of the embedded swagger specification file
-55
api/openapi.json
··· 58 58 } 59 59 } 60 60 }, 61 - "/v0/run/{app}": { 62 - "post": { 63 - "operationId": "runApp", 64 - "tags": [ 65 - "apps" 66 - ], 67 - "parameters": [ 68 - { 69 - "name": "app", 70 - "in": "path", 71 - "required": true, 72 - "schema": { 73 - "type": "string" 74 - } 75 - } 76 - ], 77 - "requestBody": { 78 - "content": { 79 - "application/json": { 80 - "schema": { 81 - "type": "object", 82 - "required": [ 83 - "args" 84 - ], 85 - "properties": { 86 - "args": { 87 - "type": "array", 88 - "items": { 89 - "type": "string" 90 - } 91 - } 92 - } 93 - } 94 - } 95 - } 96 - }, 97 - "responses": { 98 - "200": { 99 - "description": "Run app cli", 100 - "content": { 101 - "application/json": { 102 - "schema": { 103 - "$ref": "#/components/schemas/CommandOutput" 104 - } 105 - }, 106 - "text/plain": { 107 - "schema": { 108 - "type": "string" 109 - } 110 - } 111 - } 112 - } 113 - } 114 - } 115 - }, 116 61 "/v0/logs/http": { 117 62 "get": { 118 63 "operationId": "getHttpLogs",