Skip to content

Commit cdd10e7

Browse files
committed
FIX: improved TLS and HTTP protocol to correctly handle chunked data and case when TLS packed was not fully processed
1 parent e602f37 commit cdd10e7

File tree

2 files changed

+34
-24
lines changed

2 files changed

+34
-24
lines changed

src/mezz/prot-http.r

+7-8
Original file line numberDiff line numberDiff line change
@@ -242,8 +242,8 @@ do-request: func [
242242
info: port/state/info
243243
spec/headers: body-of make make object! [
244244
Accept: "*/*"
245-
Accept-Charset: "utf-8"
246-
Accept-encoding: "gzip,deflate"
245+
Accept-charset: "utf-8"
246+
Accept-Encoding: "gzip,deflate"
247247
Host: either not find [80 443] spec/port-id [
248248
rejoin [form spec/host #":" spec/port-id]
249249
] [
@@ -513,19 +513,21 @@ check-data: func [port /local headers res data out chunk-size mk1 mk2 trailer st
513513
res: false
514514

515515
sys/log/more 'HTTP ["check-data; bytes:^[[m" length? conn/data]
516-
;? conn
517516

518517
case [
519518
headers/transfer-encoding = "chunked" [
520519
data: conn/data
520+
sys/log/more 'HTTP ["chunked data: " length? data mold copy/part data 30]
521521
;clear the port data only at the beginning of the request --Richard
522-
unless port/data [port/data: make binary! length? data]
522+
unless port/data [ port/data: make binary! 32000 ]
523523
out: port/data
524524
until [
525525
either parse/all data [
526-
copy chunk-size some hex-digits thru crlfbin mk1: to end
526+
copy chunk-size some hex-digits
527+
crlfbin mk1: to end
527528
] [
528529
chunk-size: to integer! to issue! to string! chunk-size
530+
sys/log/more 'HTTP ["chunk-size:^[[m" chunk-size]
529531
either chunk-size = 0 [
530532
if parse/all mk1 [
531533
crlfbin (trailer: "") to end | copy trailer to crlf2bin to end
@@ -607,7 +609,6 @@ sys/make-scheme [
607609
if port/state/state <> 'ready [http-error "Port not ready"]
608610
port/state/awake: :port/awake
609611
do-request port
610-
port
611612
] [
612613
sync-op port []
613614
]
@@ -627,7 +628,6 @@ sys/make-scheme [
627628
port/state/awake: :port/awake
628629
parse-write-dialect port value
629630
do-request port
630-
port
631631
] [
632632
sync-op port [parse-write-dialect port value]
633633
]
@@ -636,7 +636,6 @@ sys/make-scheme [
636636
port [port!]
637637
/local conn
638638
] [
639-
? port/spec
640639
sys/log/debug 'HTTP ["open, state:" port/state]
641640
if port/state [return port]
642641
if none? port/spec/host [http-error "Missing host address"]

src/mezz/prot-tls.r

+27-16
Original file line numberDiff line numberDiff line change
@@ -1007,7 +1007,7 @@ make-TLS-ctx: does [ context [
10071007
bin: binary 64 ;temporary binary
10081008

10091009
port-data: make binary! 32000 ;this holds received decrypted application data
1010-
1010+
rest: make binary! 8 ;packet may not e fully processed, this value is used to keep temporary leftover
10111011
reading?: false ;if client is reading or writing data
10121012
;server?: false ;always FALSE now as we have just a client
10131013
protocol: none ;current protocol state. One of: [HANDSHAKE APPLICATION ALERT]
@@ -1091,15 +1091,15 @@ TLS-read-data: function [
10911091
] [
10921092
;log-more ["read-data:^[[1m" length? port-data "^[[22mbytes"]
10931093

1094-
;probe copy/part ctx/in/buffer 10
1094+
inp: ctx/in
10951095

1096-
binary/write ctx/in port-data ;- fills input buffer with received data
1096+
binary/write inp ctx/rest ;- possible leftover from previous packet
1097+
binary/write inp port-data ;- fills input buffer with received data
10971098
clear port-data
1099+
clear ctx/rest
10981100

10991101
ctx/reading?: true
11001102

1101-
inp: ctx/in
1102-
11031103
while [ctx/reading? and ((available: length? inp/buffer) >= 5)][
11041104
;?? available
11051105
log-debug ["Data starts: " mold copy/part inp/buffer 10]
@@ -1110,7 +1110,16 @@ TLS-read-data: function [
11101110
version: UI16
11111111
len: UI16
11121112
]
1113-
log-debug ["fragment type: ^[[1m" type "^[[22mver:^[[1m" version "^[[22mbytes:^[[1m" len "^[[22mbytes"]
1113+
log-debug ["fragment type: ^[[1m" type "^[[22mver:^[[1m" version *Protocol-version/name version "^[[22mbytes:^[[1m" len "^[[22mbytes"]
1114+
1115+
if all [
1116+
ctx/server-version
1117+
version <> ctx/server-version
1118+
][
1119+
log-error ["Version mismatch:^[[22m" version "<>" ctx/server-version]
1120+
ctx/critical-error: *Alert/Internal_error
1121+
return false
1122+
]
11141123

11151124
if available < len [
11161125
;probe inp/buffer
@@ -1217,6 +1226,10 @@ TLS-read-data: function [
12171226

12181227
;?? ctx/state
12191228
log-debug "continue reading..."
1229+
unless empty? ctx/in/buffer [
1230+
; keeping rest of unprocessed data for later use
1231+
ctx/rest: copy ctx/in/buffer
1232+
]
12201233
return true
12211234
]
12221235

@@ -1538,25 +1551,23 @@ TLS-awake: function [event [event!]] [
15381551
TLS-error error-id
15391552
]
15401553
log-debug ["Read complete?" complete?]
1541-
if complete? [
1542-
;? TLS-Port/state
1543-
;? TLS-port/state/connection
1544-
TLS-port/data: TLS-port/state/port-data
1545-
binary/init TLS-port/state/in none ; resets input buffer
1554+
unless complete? [
1555+
read port
1556+
return false
15461557
]
1558+
TLS-port/data: TLS-port/state/port-data
1559+
binary/init TLS-port/state/in none ; resets input buffer
15471560
either 'APPLICATION = TLS-port/state/protocol [
15481561
send-event 'read TLS-port
1549-
] [
1550-
read port
1551-
]
1552-
return complete?
1562+
][ read port ]
1563+
return true
15531564
]
15541565
close [
15551566
log-info "CLOSE"
15561567
send-event 'close TLS-port
15571568
return true
15581569
]
1559-
] [
1570+
][
15601571
;try [close port/state/connection]
15611572
close port
15621573
do make error! rejoin ["Unexpected TLS event: " event/type]

0 commit comments

Comments
 (0)