Merge pull request #292 from bettercap/refactored-http-headers

Refactored http headers
This commit is contained in:
Simone Margaritelli 2018-06-15 11:45:37 +02:00 committed by GitHub
commit 92169f4fab
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 85 additions and 55 deletions

View file

@ -7,13 +7,9 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"strings" "strings"
"regexp"
) )
type JSHeader struct {
Name string
Value string
}
type JSRequest struct { type JSRequest struct {
Client string Client string
Method string Method string
@ -23,7 +19,7 @@ type JSRequest struct {
Query string Query string
Hostname string Hostname string
ContentType string ContentType string
Headers []JSHeader Headers string
Body string Body string
req *http.Request req *http.Request
@ -31,15 +27,17 @@ type JSRequest struct {
bodyRead bool bodyRead bool
} }
var header_regexp = regexp.MustCompile(`(.*?): (.*)`)
func NewJSRequest(req *http.Request) *JSRequest { func NewJSRequest(req *http.Request) *JSRequest {
headers := make([]JSHeader, 0) headers := ""
cType := "" cType := ""
for name, values := range req.Header { for name, values := range req.Header {
for _, value := range values { for _, value := range values {
headers = append(headers, JSHeader{name, value}) headers += name + ": " + value + "\r\n"
if name == "Content-Type" { if strings.ToLower(name) == "content-type" {
cType = value cType = value
} }
} }
@ -65,10 +63,7 @@ func NewJSRequest(req *http.Request) *JSRequest {
} }
func (j *JSRequest) NewHash() string { func (j *JSRequest) NewHash() string {
hash := fmt.Sprintf("%s.%s.%s.%s.%s.%s.%s.%s", j.Client, j.Method, j.Version, j.Scheme, j.Hostname, j.Path, j.Query, j.ContentType) hash := fmt.Sprintf("%s.%s.%s.%s.%s.%s.%s.%s.%s", j.Client, j.Method, j.Version, j.Scheme, j.Hostname, j.Path, j.Query, j.ContentType, j.Headers)
for _, h := range j.Headers {
hash += fmt.Sprintf(".%s-%s", h.Name, h.Value)
}
hash += "." + j.Body hash += "." + j.Body
return hash return hash
} }
@ -87,31 +82,44 @@ func (j *JSRequest) WasModified() bool {
} }
func (j *JSRequest) GetHeader(name, deflt string) string { func (j *JSRequest) GetHeader(name, deflt string) string {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for _, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
return h.Value header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
return header_value
} }
} }
return deflt return deflt
} }
func (j *JSRequest) SetHeader(name, value string) { func (j *JSRequest) SetHeader(name, value string) {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for i, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
j.Headers[i].Value = value header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
old_header := header_name + ": " + header_value + "\r\n"
new_header := header_name + ": " + value + "\r\n"
j.Headers = strings.Replace(j.Headers, old_header, new_header, 1)
return return
} }
} }
j.Headers = append(j.Headers, JSHeader{name, value}) j.Headers += name + ": " + value + "\r\n"
} }
func (j *JSRequest) RemoveHeader(name string) { func (j *JSRequest) RemoveHeader(name string) {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for i, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
j.Headers = append(j.Headers[:i], j.Headers[i+1:]...) header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
removed_header := header_name + ": " + header_value + "\r\n"
j.Headers = strings.Replace(j.Headers, removed_header, "", 1)
return
} }
} }
} }
@ -162,10 +170,17 @@ func (j *JSRequest) ToRequest() (req *http.Request) {
} }
hadType := false hadType := false
for _, h := range j.Headers {
req.Header.Set(h.Name, h.Value) headers := strings.Split(j.Headers, "\r\n")
if h.Name == "Content-Type" { for i := 0; i < len(headers); i++ {
hadType = true if headers[i] != "" {
header_name := header_regexp.ReplaceAllString(headers[i], "$1")
header_value := header_regexp.ReplaceAllString(headers[i], "$2")
req.Header.Set(header_name, header_value)
if strings.ToLower(header_name) == "content-type" {
hadType = true
}
} }
} }

View file

@ -13,7 +13,7 @@ import (
type JSResponse struct { type JSResponse struct {
Status int Status int
ContentType string ContentType string
Headers []JSHeader Headers string
Body string Body string
refHash string refHash string
@ -24,16 +24,16 @@ type JSResponse struct {
func NewJSResponse(res *http.Response) *JSResponse { func NewJSResponse(res *http.Response) *JSResponse {
cType := "" cType := ""
headers := make([]JSHeader, 0) headers := ""
code := 200 code := 200
if res != nil { if res != nil {
code = res.StatusCode code = res.StatusCode
for name, values := range res.Header { for name, values := range res.Header {
for _, value := range values { for _, value := range values {
headers = append(headers, JSHeader{name, value}) headers += name + ": " + value + "\r\n"
if name == "Content-Type" { if strings.ToLower(name) == "content-type" {
cType = value cType = value
} }
} }
@ -54,11 +54,7 @@ func NewJSResponse(res *http.Response) *JSResponse {
} }
func (j *JSResponse) NewHash() string { func (j *JSResponse) NewHash() string {
hash := fmt.Sprintf("%d.%s", j.Status, j.ContentType) return fmt.Sprintf("%d.%s.%s", j.Status, j.ContentType, j.Headers)
for _, h := range j.Headers {
hash += fmt.Sprintf(".%s-%s", h.Name, h.Value)
}
return hash
} }
func (j *JSResponse) UpdateHash() { func (j *JSResponse) UpdateHash() {
@ -81,31 +77,44 @@ func (j *JSResponse) WasModified() bool {
} }
func (j *JSResponse) GetHeader(name, deflt string) string { func (j *JSResponse) GetHeader(name, deflt string) string {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for _, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
return h.Value header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
return header_value
} }
} }
return deflt return deflt
} }
func (j *JSResponse) SetHeader(name, value string) { func (j *JSResponse) SetHeader(name, value string) {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for i, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
j.Headers[i].Value = value header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
old_header := header_name + ": " + header_value + "\r\n"
new_header := header_name + ": " + value + "\r\n"
j.Headers = strings.Replace(j.Headers, old_header, new_header, 1)
return return
} }
} }
j.Headers = append(j.Headers, JSHeader{name, value}) j.Headers += name + ": " + value + "\r\n"
} }
func (j *JSResponse) RemoveHeader(name string) { func (j *JSResponse) RemoveHeader(name string) {
name = strings.ToLower(name) headers := strings.Split(j.Headers, "\r\n")
for i, h := range j.Headers { for i := 0; i < len(headers); i++ {
if name == strings.ToLower(h.Name) { header_name := header_regexp.ReplaceAllString(headers[i], "$1")
j.Headers = append(j.Headers[:i], j.Headers[i+1:]...) header_value := header_regexp.ReplaceAllString(headers[i], "$2")
if strings.ToLower(name) == strings.ToLower(header_name) {
removed_header := header_name + ": " + header_value + "\r\n"
j.Headers = strings.Replace(j.Headers, removed_header, "", 1)
return
} }
} }
} }
@ -117,11 +126,17 @@ func (j *JSResponse) ClearBody() {
func (j *JSResponse) ToResponse(req *http.Request) (resp *http.Response) { func (j *JSResponse) ToResponse(req *http.Request) (resp *http.Response) {
resp = goproxy.NewResponse(req, j.ContentType, j.Status, j.Body) resp = goproxy.NewResponse(req, j.ContentType, j.Status, j.Body)
if len(j.Headers) > 0 {
for _, h := range j.Headers { headers := strings.Split(j.Headers, "\r\n")
resp.Header.Add(h.Name, h.Value) for i := 0; i < len(headers); i++ {
if headers[i] != "" {
header_name := header_regexp.ReplaceAllString(headers[i], "$1")
header_value := header_regexp.ReplaceAllString(headers[i], "$2")
resp.Header.Add(header_name, header_value)
} }
} }
return return
} }