You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
279 lines
5.7 KiB
Go
279 lines
5.7 KiB
Go
4 years ago
|
package web
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
4 years ago
|
"encoding/binary"
|
||
4 years ago
|
"encoding/json"
|
||
4 years ago
|
"errors"
|
||
4 years ago
|
|
||
2 years ago
|
"github.com/lqqyt2423/go-mitmproxy/proxy"
|
||
4 years ago
|
uuid "github.com/satori/go.uuid"
|
||
|
)
|
||
|
|
||
4 years ago
|
// message:
|
||
|
|
||
|
// type: 1/2/3/4
|
||
|
// messageFlow
|
||
|
// version 1 byte + type 1 byte + id 36 byte + waitIntercept 1 byte + content left bytes
|
||
|
|
||
4 years ago
|
// type: 11/12/13/14
|
||
4 years ago
|
// messageEdit
|
||
|
// version 1 byte + type 1 byte + id 36 byte + header len 4 byte + header content bytes + body len 4 byte + [body content bytes]
|
||
|
|
||
|
// type: 21
|
||
|
// messageMeta
|
||
|
// version 1 byte + type 1 byte + content left bytes
|
||
|
|
||
4 years ago
|
const messageVersion = 1
|
||
|
|
||
4 years ago
|
type messageType byte
|
||
4 years ago
|
|
||
4 years ago
|
const (
|
||
4 years ago
|
messageTypeRequest messageType = 1
|
||
4 years ago
|
messageTypeRequestBody messageType = 2
|
||
|
messageTypeResponse messageType = 3
|
||
|
messageTypeResponseBody messageType = 4
|
||
|
|
||
4 years ago
|
messageTypeChangeRequest messageType = 11
|
||
|
messageTypeChangeResponse messageType = 12
|
||
4 years ago
|
messageTypeDropRequest messageType = 13
|
||
|
messageTypeDropResponse messageType = 14
|
||
4 years ago
|
|
||
4 years ago
|
messageTypeChangeBreakPointRules messageType = 21
|
||
4 years ago
|
)
|
||
|
|
||
4 years ago
|
var allMessageTypes = []messageType{
|
||
|
messageTypeRequest,
|
||
|
messageTypeRequestBody,
|
||
|
messageTypeResponse,
|
||
|
messageTypeResponseBody,
|
||
|
messageTypeChangeRequest,
|
||
4 years ago
|
messageTypeChangeResponse,
|
||
4 years ago
|
messageTypeDropRequest,
|
||
|
messageTypeDropResponse,
|
||
4 years ago
|
messageTypeChangeBreakPointRules,
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
func validMessageType(t byte) bool {
|
||
4 years ago
|
for _, v := range allMessageTypes {
|
||
|
if t == byte(v) {
|
||
|
return true
|
||
|
}
|
||
4 years ago
|
}
|
||
|
return false
|
||
|
}
|
||
|
|
||
4 years ago
|
type message interface {
|
||
|
bytes() []byte
|
||
|
}
|
||
|
|
||
|
type messageFlow struct {
|
||
4 years ago
|
mType messageType
|
||
|
id uuid.UUID
|
||
|
waitIntercept byte
|
||
|
content []byte
|
||
4 years ago
|
}
|
||
|
|
||
2 years ago
|
func newMessageFlow(mType messageType, f *proxy.Flow) *messageFlow {
|
||
4 years ago
|
var content []byte
|
||
|
var err error = nil
|
||
|
|
||
|
if mType == messageTypeRequest {
|
||
|
content, err = json.Marshal(f.Request)
|
||
|
} else if mType == messageTypeRequestBody {
|
||
|
content = f.Request.Body
|
||
|
} else if mType == messageTypeResponse {
|
||
|
content, err = json.Marshal(f.Response)
|
||
|
} else if mType == messageTypeResponseBody {
|
||
|
content, err = f.Response.DecodedBody()
|
||
|
} else {
|
||
|
panic(errors.New("invalid message type"))
|
||
|
}
|
||
|
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
return &messageFlow{
|
||
4 years ago
|
mType: mType,
|
||
4 years ago
|
id: f.Id,
|
||
4 years ago
|
content: content,
|
||
|
}
|
||
|
}
|
||
|
|
||
4 years ago
|
func (m *messageFlow) bytes() []byte {
|
||
|
buf := bytes.NewBuffer(make([]byte, 0))
|
||
|
buf.WriteByte(byte(messageVersion))
|
||
|
buf.WriteByte(byte(m.mType))
|
||
|
buf.WriteString(m.id.String()) // len: 36
|
||
|
buf.WriteByte(m.waitIntercept)
|
||
|
buf.Write(m.content)
|
||
|
return buf.Bytes()
|
||
|
}
|
||
|
|
||
|
type messageEdit struct {
|
||
|
mType messageType
|
||
|
id uuid.UUID
|
||
2 years ago
|
request *proxy.Request
|
||
|
response *proxy.Response
|
||
4 years ago
|
}
|
||
|
|
||
|
func parseMessageEdit(data []byte) *messageEdit {
|
||
4 years ago
|
// 2 + 36
|
||
|
if len(data) < 38 {
|
||
4 years ago
|
return nil
|
||
|
}
|
||
4 years ago
|
|
||
|
mType := (messageType)(data[1])
|
||
|
|
||
|
id, err := uuid.FromString(string(data[2:38]))
|
||
|
if err != nil {
|
||
4 years ago
|
return nil
|
||
4 years ago
|
}
|
||
4 years ago
|
|
||
4 years ago
|
msg := &messageEdit{
|
||
|
mType: mType,
|
||
|
id: id,
|
||
|
}
|
||
|
|
||
|
if mType == messageTypeDropRequest || mType == messageTypeDropResponse {
|
||
|
return msg
|
||
|
}
|
||
|
|
||
|
// 2 + 36 + 4 + 4
|
||
|
if len(data) < 46 {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
4 years ago
|
hl := (int)(binary.BigEndian.Uint32(data[38:42]))
|
||
|
if 42+hl+4 > len(data) {
|
||
4 years ago
|
return nil
|
||
|
}
|
||
4 years ago
|
headerContent := data[42 : 42+hl]
|
||
4 years ago
|
|
||
4 years ago
|
bl := (int)(binary.BigEndian.Uint32(data[42+hl : 42+hl+4]))
|
||
|
if 42+hl+4+bl != len(data) {
|
||
|
return nil
|
||
|
}
|
||
|
bodyContent := data[42+hl+4:]
|
||
|
|
||
|
if mType == messageTypeChangeRequest {
|
||
2 years ago
|
req := new(proxy.Request)
|
||
4 years ago
|
err := json.Unmarshal(headerContent, req)
|
||
|
if err != nil {
|
||
|
return nil
|
||
|
}
|
||
|
req.Body = bodyContent
|
||
|
msg.request = req
|
||
|
} else if mType == messageTypeChangeResponse {
|
||
2 years ago
|
res := new(proxy.Response)
|
||
4 years ago
|
err := json.Unmarshal(headerContent, res)
|
||
|
if err != nil {
|
||
|
return nil
|
||
|
}
|
||
|
res.Body = bodyContent
|
||
|
msg.response = res
|
||
|
} else {
|
||
4 years ago
|
return nil
|
||
|
}
|
||
|
|
||
4 years ago
|
return msg
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
func (m *messageEdit) bytes() []byte {
|
||
|
buf := bytes.NewBuffer(make([]byte, 0))
|
||
|
buf.WriteByte(byte(messageVersion))
|
||
|
buf.WriteByte(byte(m.mType))
|
||
|
buf.WriteString(m.id.String()) // len: 36
|
||
|
|
||
|
if m.mType == messageTypeChangeRequest {
|
||
|
headerContent, err := json.Marshal(m.request)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
hl := make([]byte, 4)
|
||
|
binary.BigEndian.PutUint32(hl, (uint32)(len(headerContent)))
|
||
|
buf.Write(hl)
|
||
|
|
||
|
bodyContent := m.request.Body
|
||
|
bl := make([]byte, 4)
|
||
|
binary.BigEndian.PutUint32(bl, (uint32)(len(bodyContent)))
|
||
|
buf.Write(bl)
|
||
|
buf.Write(bodyContent)
|
||
|
} else if m.mType == messageTypeChangeResponse {
|
||
|
headerContent, err := json.Marshal(m.response)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
hl := make([]byte, 4)
|
||
|
binary.BigEndian.PutUint32(hl, (uint32)(len(headerContent)))
|
||
|
buf.Write(hl)
|
||
|
|
||
|
bodyContent := m.response.Body
|
||
|
bl := make([]byte, 4)
|
||
|
binary.BigEndian.PutUint32(bl, (uint32)(len(bodyContent)))
|
||
|
buf.Write(bl)
|
||
|
buf.Write(bodyContent)
|
||
4 years ago
|
}
|
||
4 years ago
|
|
||
|
return buf.Bytes()
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
type messageMeta struct {
|
||
|
mType messageType
|
||
|
breakPointRules []*breakPointRule
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
func parseMessageMeta(data []byte) *messageMeta {
|
||
|
content := data[2:]
|
||
|
rules := make([]*breakPointRule, 0)
|
||
|
err := json.Unmarshal(content, &rules)
|
||
4 years ago
|
if err != nil {
|
||
4 years ago
|
return nil
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
return &messageMeta{
|
||
|
mType: messageType(data[1]),
|
||
|
breakPointRules: rules,
|
||
|
}
|
||
4 years ago
|
}
|
||
|
|
||
4 years ago
|
func (m *messageMeta) bytes() []byte {
|
||
4 years ago
|
buf := bytes.NewBuffer(make([]byte, 0))
|
||
|
buf.WriteByte(byte(messageVersion))
|
||
4 years ago
|
buf.WriteByte(byte(m.mType))
|
||
4 years ago
|
|
||
|
content, err := json.Marshal(m.breakPointRules)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
buf.Write(content)
|
||
|
|
||
4 years ago
|
return buf.Bytes()
|
||
|
}
|
||
4 years ago
|
|
||
|
func parseMessage(data []byte) message {
|
||
|
if len(data) < 2 {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if data[0] != messageVersion {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
if !validMessageType(data[1]) {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
mType := (messageType)(data[1])
|
||
|
|
||
4 years ago
|
if mType == messageTypeChangeRequest || mType == messageTypeChangeResponse || mType == messageTypeDropRequest || mType == messageTypeDropResponse {
|
||
4 years ago
|
return parseMessageEdit(data)
|
||
|
} else if mType == messageTypeChangeBreakPointRules {
|
||
|
return parseMessageMeta(data)
|
||
|
} else {
|
||
|
log.Warnf("invalid message type %v", mType)
|
||
|
return nil
|
||
|
}
|
||
|
}
|