Skip to content

Commit 1f80006

Browse files
Add support for custom HTTP response headers (projectdiscovery#86)
* add support for custom HTTP response headers * update flag list in readme * fix readme typo and adjust cases of words Co-authored-by: Sandeep Singh <sandeep@projectdiscovery.io>
1 parent 7d15504 commit 1f80006

File tree

5 files changed

+66
-20
lines changed

5 files changed

+66
-20
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ This will display help for the tool. Here are all the switches it supports.
6969
| `-realm` | Basic auth message | `simplehttpserver -realm "insert the credentials"` |
7070
| `-version` | Show version | `simplehttpserver -version` |
7171
| `-silent` | Show only results | `simplehttpserver -silent` |
72+
| `-header` | HTTP response header (can be used multiple times) | `simplehttpserver -header 'X-Powered-By: Go'` |
7273

7374
### Running simplehttpserver in the current folder
7475

internal/runner/options.go

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,40 @@ package runner
22

33
import (
44
"flag"
5+
"fmt"
56
"os"
67
"path/filepath"
78
"strings"
89

910
"github.com/projectdiscovery/gologger"
1011
"github.com/projectdiscovery/gologger/levels"
12+
"github.com/projectdiscovery/simplehttpserver/pkg/httpserver"
1113
)
1214

1315
// Options of the tool
1416
type Options struct {
15-
ListenAddress string
16-
Folder string
17-
BasicAuth string
18-
username string
19-
password string
20-
Realm string
21-
TLSCertificate string
22-
TLSKey string
23-
TLSDomain string
24-
HTTPS bool
25-
Verbose bool
26-
EnableUpload bool
27-
EnableTCP bool
28-
RulesFile string
29-
TCPWithTLS bool
30-
Version bool
31-
Silent bool
32-
Sandbox bool
33-
MaxFileSize int
34-
HTTP1Only bool
17+
ListenAddress string
18+
Folder string
19+
BasicAuth string
20+
username string
21+
password string
22+
Realm string
23+
TLSCertificate string
24+
TLSKey string
25+
TLSDomain string
26+
HTTPS bool
27+
Verbose bool
28+
EnableUpload bool
29+
EnableTCP bool
30+
RulesFile string
31+
TCPWithTLS bool
32+
Version bool
33+
Silent bool
34+
Sandbox bool
35+
MaxFileSize int
36+
HTTP1Only bool
3537
MaxDumpBodySize int
38+
HTTPHeaders HTTPHeaders
3639
}
3740

3841
// ParseOptions parses the command line options for application
@@ -61,6 +64,7 @@ func ParseOptions() *Options {
6164
flag.BoolVar(&options.HTTP1Only, "http1", false, "Enable only HTTP1")
6265
flag.IntVar(&options.MaxFileSize, "max-file-size", 50, "Max Upload File Size")
6366
flag.IntVar(&options.MaxDumpBodySize, "max-dump-body-size", -1, "Max Dump Body Size")
67+
flag.Var(&options.HTTPHeaders, "header", "Add HTTP Response Header (name: value), can be used multiple times")
6468
flag.Parse()
6569

6670
// Read the inputs and configure the logging
@@ -113,3 +117,21 @@ func (options *Options) FolderAbsPath() string {
113117
}
114118
return abspath
115119
}
120+
121+
// HTTPHeaders is a slice of HTTPHeader structs
122+
type HTTPHeaders []httpserver.HTTPHeader
123+
124+
func (h *HTTPHeaders) String() string {
125+
return fmt.Sprint(*h)
126+
}
127+
128+
// Set sets a new header, which must be a string of the form 'name: value'
129+
func (h *HTTPHeaders) Set(value string) error {
130+
tokens := strings.SplitN(value, ":", 2)
131+
if len(tokens) != 2 {
132+
return fmt.Errorf("header '%s' not in format 'name: value'", value)
133+
}
134+
135+
*h = append(*h, httpserver.HTTPHeader{Name: tokens[0], Value: tokens[1]})
136+
return nil
137+
}

internal/runner/runner.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func New(options *Options) (*Runner, error) {
6868
MaxFileSize: r.options.MaxFileSize,
6969
HTTP1Only: r.options.HTTP1Only,
7070
MaxDumpBodySize: unit.ToMb(r.options.MaxDumpBodySize),
71+
HTTPHeaders: r.options.HTTPHeaders,
7172
})
7273
if err != nil {
7374
return nil, err

pkg/httpserver/headerlayer.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package httpserver
2+
3+
import (
4+
"net/http"
5+
)
6+
7+
// HTTPHeader represents an HTTP header
8+
type HTTPHeader struct {
9+
Name string
10+
Value string
11+
}
12+
13+
func (t *HTTPServer) headerlayer(handler http.Handler, headers []HTTPHeader) http.Handler {
14+
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
15+
for _, header := range headers {
16+
w.Header().Set(header.Name, header.Value)
17+
}
18+
handler.ServeHTTP(w, r)
19+
})
20+
}

pkg/httpserver/httpserver.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ type Options struct {
2727
HTTP1Only bool
2828
MaxFileSize int // 50Mb
2929
MaxDumpBodySize int64
30+
HTTPHeaders []HTTPHeader
3031
}
3132

3233
// HTTPServer instance
@@ -72,6 +73,7 @@ func New(options *Options) (*HTTPServer, error) {
7273
}
7374

7475
httpHandler = h.loglayer(httpHandler)
76+
httpHandler = h.headerlayer(httpHandler, options.HTTPHeaders)
7577

7678
// add handler
7779
h.layers = httpHandler

0 commit comments

Comments
 (0)