forked from projectdiscovery/simplehttpserver
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhttpserver.go
More file actions
131 lines (113 loc) · 3.09 KB
/
httpserver.go
File metadata and controls
131 lines (113 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package httpserver
import (
"crypto/tls"
"errors"
"net/http"
"os"
"path/filepath"
"github.com/projectdiscovery/sslcert"
)
// Options of the http server
type Options struct {
Folder string
EnableUpload bool
ListenAddress string
TLS bool
Certificate string
CertificateKey string
CertificateDomain string
BasicAuthUsername string
BasicAuthPassword string
BasicAuthReal string
Verbose bool
Sandbox bool
HTTP1Only bool
MaxFileSize int // 50Mb
MaxDumpBodySize int64
Python bool
CORS bool
HTTPHeaders []HTTPHeader
}
// HTTPServer instance
type HTTPServer struct {
options *Options
layers http.Handler
}
// LayerHandler is the interface of all layer funcs
type Middleware func(http.Handler) http.Handler
// New http server instance with options
func New(options *Options) (*HTTPServer, error) {
var h HTTPServer
EnableUpload = options.EnableUpload
EnableVerbose = options.Verbose
folder, err := filepath.Abs(options.Folder)
if err != nil {
return nil, err
}
if _, err := os.Stat(folder); os.IsNotExist(err) {
return nil, errors.New("path does not exist")
}
options.Folder = folder
var dir http.FileSystem
dir = http.Dir(options.Folder)
if options.Sandbox {
dir = SandboxFileSystem{fs: http.Dir(options.Folder), RootFolder: options.Folder}
}
var httpHandler http.Handler
if options.Python {
httpHandler = PythonStyle(dir.(http.Dir))
} else {
httpHandler = http.FileServer(dir)
}
addHandler := func(newHandler Middleware) {
httpHandler = newHandler(httpHandler)
}
// middleware
if options.EnableUpload {
addHandler(h.uploadlayer)
}
if options.BasicAuthUsername != "" || options.BasicAuthPassword != "" {
addHandler(h.basicauthlayer)
}
if options.CORS {
addHandler(h.corslayer)
}
httpHandler = h.loglayer(httpHandler)
httpHandler = h.headerlayer(httpHandler, options.HTTPHeaders)
// add handler
h.layers = httpHandler
h.options = options
return &h, nil
}
func (t *HTTPServer) makeHTTPServer(tlsConfig *tls.Config) *http.Server {
httpServer := &http.Server{Addr: t.options.ListenAddress}
if t.options.HTTP1Only {
httpServer.TLSNextProto = make(map[string]func(*http.Server, *tls.Conn, http.Handler))
}
httpServer.TLSConfig = tlsConfig
httpServer.Handler = t.layers
return httpServer
}
// ListenAndServe requests over http
func (t *HTTPServer) ListenAndServe() error {
httpServer := t.makeHTTPServer(nil)
return httpServer.ListenAndServe()
}
// ListenAndServeTLS requests over https
func (t *HTTPServer) ListenAndServeTLS() error {
if t.options.Certificate == "" || t.options.CertificateKey == "" {
tlsOptions := sslcert.DefaultOptions
tlsOptions.Host = t.options.CertificateDomain
tlsConfig, err := sslcert.NewTLSConfig(tlsOptions)
if err != nil {
return err
}
httpServer := t.makeHTTPServer(tlsConfig)
return httpServer.ListenAndServeTLS("", "")
}
return http.ListenAndServeTLS(t.options.ListenAddress, t.options.Certificate, t.options.CertificateKey, t.layers)
}
// Close the service
func (t *HTTPServer) Close() error {
return nil
}