Skip to content

Commit 80a0f4e

Browse files
authored
Added -500 option: for return 500 error if shell exit code != 0 (#94)
1 parent 16130c9 commit 80a0f4e

5 files changed

Lines changed: 24 additions & 17 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ Usage
3636
-one-thread : run each shell command in one thread
3737
-show-errors : show the standard output even if the command exits with a non-zero exit code
3838
-include-stderr : include stderr to output (default is stdout only)
39+
-500 : return 500 error if shell exit code != 0
3940
-cert=cert.pem : SSL certificate path (if specified -cert/-key options - run https server)
4041
-key=key.pem : SSL private key path
4142
-basic-auth="" : setup HTTP Basic Authentication ("user_name:password"), can be used several times

config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ type Config struct {
6767
oneThread bool // run each shell commands in one thread
6868
showErrors bool // returns the standard output even if the command exits with a non-zero exit code
6969
includeStderr bool // also returns output written to stderr (default is stdout only)
70+
intServerErr bool // return 500 error if shell status code != 0
7071
formCheckRe *regexp.Regexp // regexp for check form fields
7172
}
7273

@@ -102,6 +103,7 @@ func getConfig() (*Config, error) {
102103
flag.BoolVar(&cfg.oneThread, "one-thread", false, "run each shell command in one thread")
103104
flag.BoolVar(&cfg.showErrors, "show-errors", false, "show the standard output even if the command exits with a non-zero exit code")
104105
flag.BoolVar(&cfg.includeStderr, "include-stderr", false, "include stderr to output (default is stdout only)")
106+
flag.BoolVar(&cfg.intServerErr, "500", false, "return 500 error if shell exit code != 0")
105107
flag.StringVar(&cfg.cert, "cert", "", "SSL certificate `path` (if specified -cert/-key options - run https server)")
106108
flag.StringVar(&cfg.key, "key", "", "SSL private key `/path/...`")
107109
flag.Var(&cfg.auth, "basic-auth", "setup HTTP Basic Authentication (\"user_name:password\"), can be used several times")

shell2http.1

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.\" generated with Ronn/v0.7.3
22
.\" http://github.com/rtomayko/ronn/tree/0.7.3
33
.
4-
.TH "SHELL2HTTP" "" "February 2023" "" ""
4+
.TH "SHELL2HTTP" "" "March 2023" "" ""
55
HTTP\-server to execute shell commands\. Designed for development, prototyping or remote control\. Settings through two command line arguments, path and shell command\.
66
.
77
.SH "Usage"
@@ -29,6 +29,7 @@ options:
2929
\-one\-thread : run each shell command in one thread
3030
\-show\-errors : show the standard output even if the command exits with a non\-zero exit code
3131
\-include\-stderr : include stderr to output (default is stdout only)
32+
\-500 : return 500 error if shell exit code != 0
3233
\-cert=cert\.pem : SSL certificate path (if specified \-cert/\-key options \- run https server)
3334
\-key=key\.pem : SSL private key path
3435
\-basic\-auth="" : setup HTTP Basic Authentication ("user_name:password"), can be used several times

shell2http.go

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -142,16 +142,15 @@ func getShellHandler(appConfig Config, shell string, params []string, cacheTTL r
142142
log.Printf("out: %s, exec error: %s", string(shellOut), err)
143143
}
144144

145-
rw.Header().Set("X-Shell2http-Exit-Code", strconv.Itoa(exitCode))
145+
customStatusCode := 0
146+
outText := string(shellOut)
146147

147148
if err != nil && !appConfig.showErrors {
148-
responseWrite(rw, fmt.Sprintf("%s\nexec error: %s", string(shellOut), err))
149+
outText = fmt.Sprintf("%s\nexec error: %s", string(shellOut), err)
149150
} else {
150-
outText := string(shellOut)
151151
if appConfig.setCGI {
152152
var headers map[string]string
153153
outText, headers = parseCGIHeaders(outText)
154-
customStatusCode := 0
155154

156155
for headerKey, headerValue := range headers {
157156
switch headerKey {
@@ -170,14 +169,18 @@ func getShellHandler(appConfig Config, shell string, params []string, cacheTTL r
170169

171170
rw.Header().Set(headerKey, headerValue)
172171
}
173-
174-
if customStatusCode > 0 {
175-
rw.WriteHeader(customStatusCode)
176-
}
177172
}
173+
}
178174

179-
responseWrite(rw, outText)
175+
rw.Header().Set("X-Shell2http-Exit-Code", strconv.Itoa(exitCode))
176+
177+
if customStatusCode > 0 {
178+
rw.WriteHeader(customStatusCode)
179+
} else if exitCode > 0 && appConfig.intServerErr {
180+
rw.WriteHeader(http.StatusInternalServerError)
180181
}
182+
183+
responseWrite(rw, outText)
181184
}
182185
}
183186

@@ -408,15 +411,15 @@ func parseCGIHeaders(shellOut string) (string, map[string]string) {
408411
headersMap[headerParts[1]] = headerParts[2]
409412
} else {
410413
// headers is not valid, return all text
411-
return shellOut, map[string]string{}
414+
return shellOut, nil
412415
}
413416
}
414417

415418
return parts[1], headersMap
416419
}
417420

418421
// headers don't found, return all text
419-
return shellOut, map[string]string{}
422+
return shellOut, nil
420423
}
421424

422425
// getForm - parse form into environment vars, also handle uploaded files

shell2http_test.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func Test_parseCGIHeaders(t *testing.T) {
2222
{
2323
in: "Some text",
2424
out: "Some text",
25-
headers: map[string]string{},
25+
headers: nil,
2626
},
2727
{
2828
in: "Location: url\n\nSome text",
@@ -42,12 +42,12 @@ func Test_parseCGIHeaders(t *testing.T) {
4242
{
4343
in: "Some text\nText\n\ntext",
4444
out: "Some text\nText\n\ntext",
45-
headers: map[string]string{},
45+
headers: nil,
4646
},
4747
{
4848
in: "Some text\nText: value in text\n\ntext",
4949
out: "Some text\nText: value in text\n\ntext",
50-
headers: map[string]string{},
50+
headers: nil,
5151
},
5252
{
5353
in: "Text::::\n\ntext",
@@ -62,12 +62,12 @@ func Test_parseCGIHeaders(t *testing.T) {
6262
{
6363
in: "Text: \n\ntext",
6464
out: "Text: \n\ntext",
65-
headers: map[string]string{},
65+
headers: nil,
6666
},
6767
{
6868
in: "Header: value\nText: \n\ntext",
6969
out: "Header: value\nText: \n\ntext",
70-
headers: map[string]string{},
70+
headers: nil,
7171
},
7272
{
7373
in: "Location: url\r\nX-Name: x-value\r\n\r\nOn Windows",

0 commit comments

Comments
 (0)