forked from fanux/lhttp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
multipartFilter.go
114 lines (94 loc) · 2.06 KB
/
multipartFilter.go
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
package lhttp
import (
"log"
"strconv"
"strings"
)
type multipartBlock struct {
headers map[string]string
body string
nextBlock *multipartBlock
}
func (m *multipartBlock) GetNext() *multipartBlock {
return m.nextBlock
}
func (m *multipartBlock) GetBody() string {
return m.body
}
func (m *multipartBlock) GetHeaders() map[string]string {
return m.headers
}
type multipartFilter struct {
*HeadFilterBase
}
func splitsString(pos []int, s string) (strs []string) {
log.Print("pos:", pos, " body multipart string:", s)
for i := range pos {
i++
if i >= len(pos) {
strs = append(strs, s[pos[i-1]:])
} else {
strs = append(strs, s[pos[i-1]:pos[i]])
}
}
log.Print("splits murltiple body: ", strs)
return
}
func initBlock(s string, m *multipartBlock) {
log.Print("block is: ", s)
m.headers = make(map[string]string, headerMax)
//parse message
//parse hearders
k := 0
headers := s
var key string
var value string
//traverse once
for j, ch := range headers {
if ch == ':' && key == "" {
key = headers[k:j]
k = j + 1
} else if headers[j:j+2] == CRLF {
value = headers[k:j]
k = j + 2
m.headers[key] = value
log.Print("parse block head key:", key, " block value:", value)
key = ""
}
if headers[k:k+2] == CRLF {
k += 2
break
}
}
//set body
m.body = headers[k:]
log.Print("init multiple block:", m)
}
func (*multipartFilter) BeforeRequestFilterHandle(ws *WsHandler) {
var value string
var posInts []int
posInts = make([]int, 0)
if value = ws.GetHeader(HEADER_KEY_MULTIPART); value == "" {
log.Print("no multipart header found")
return
}
posStrs := strings.Split(value, " ")
for _, p := range posStrs {
pint, err := strconv.Atoi(p)
if err != nil {
log.Print("error multiparts head value")
return
}
posInts = append(posInts, pint)
}
bloks := splitsString(posInts, ws.GetBody())
ws.multiparts = &multipartBlock{}
current := ws.multiparts
initBlock(bloks[0], current)
for _, block := range bloks[1:] {
m := &multipartBlock{}
current.nextBlock = m
current = m
initBlock(block, current)
}
}