Skip to content

Commit 07379a6

Browse files
committed
FEAT: enable read/binary and write/binary in HTTP protocol
By default, `read` automatically tries to convert text data according give specified charset in the received header info. This may be avoided using `/binary` refinement.
1 parent 55d3aee commit 07379a6

File tree

2 files changed

+45
-24
lines changed

2 files changed

+45
-24
lines changed

src/boot/actions.r

+3-1
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ read: action [
402402
/seek {Read from a specific position (source relative)}
403403
index [number!]
404404
/string {Convert UTF and line terminators to standard text string}
405+
/binary {Preserves contents exactly}
405406
/lines {Convert to block of strings (implies /string)}
406407
; /as {Convert to string using a specified encoding}
407408
; encoding [none! number!] {UTF number (0 8 16 -16)}
@@ -419,6 +420,7 @@ write: action [
419420
/allow {Specifies protection attributes}
420421
access [block!]
421422
/lines {Write each value in a block as a separate line}
423+
/binary {Preserves contents exactly}
422424
; /as {Convert string to a specified encoding}
423425
; encoding [none! number!] {UTF number (0 8 16 -16)}
424426
]
@@ -430,7 +432,7 @@ open?: action [
430432

431433
query: action [
432434
{Returns information about target if possible.}
433-
target [port! file! url! block! vector!]
435+
target [port! file! url! block! vector! date!]
434436
/mode "Get mode information"
435437
field [word! block! none!] "NONE will return valid modes for target type"
436438
]

src/mezz/prot-http.r

+42-23
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ REBOL [
1111
}
1212
Name: 'http
1313
Type: 'module
14-
Version: 0.3.2
14+
Version: 0.3.3
15+
Date: 25-Feb-2020
1516
File: %prot-http.r
1617
Purpose: {
1718
This program defines the HTTP protocol scheme for REBOL 3.
1819
}
1920
Author: ["Gabriele Santilli" "Richard Smolak" "Oldes"]
20-
Date: 02-Apr-2019
2121
History: [
2222
0.1.1 22-Jun-2007 "Gabriele Santilli" "Version used in R3-Alpha"
2323
0.1.4 26-Nov-2012 "Richard Smolak" "Version from Atronix's fork"
@@ -31,10 +31,11 @@ REBOL [
3131
0.3.0 06-Jul-2019 "Oldes" "FIX: Error handling revisited and improved dealing with chunked data"
3232
0.3.1 13-Feb-2020 "Oldes" "FEAT: Possible auto conversion to text if found charset specification in content-type"
3333
0.3.2 25-Feb-2020 "Oldes" "FIX: Properly handling chunked data"
34+
0.3.3 25-Feb-2020 "Oldes" "FEAT: support for read/binary and write/binary to force raw data result"
3435
]
3536
]
3637

37-
sync-op: func [port body /local state encoding content-type code-page tmp][
38+
sync-op: func [port body /local header state encoding content-type code-page tmp][
3839
unless port/state [open port port/state/close?: yes]
3940
state: port/state
4041
state/awake: :read-sync-awake
@@ -49,7 +50,7 @@ sync-op: func [port body /local state encoding content-type code-page tmp][
4950
throw-http-error port make error! [
5051
type: 'Access
5152
id: 'no-connect
52-
arg1: port/spec/ref
53+
arg1: port/spec/ref
5354
arg2: 'timeout
5455
]
5556
exit
@@ -99,26 +100,16 @@ sync-op: func [port body /local state encoding content-type code-page tmp][
99100
]
100101
]
101102

102-
if all [
103-
content-type: select port/state/info/headers 'Content-Type
104-
any [
105-
; consider content to be a text if charset specification is included
106-
parse content-type [to #";" thru "charset=" copy code-page to end]
107-
; or when it is without charset, but of type text/*
108-
parse content-type ["text/" to end]
109-
]
110-
][
111-
unless code-page [code-page: "utf-8"]
112-
sys/log/info 'HTTP ["Trying to decode from code-page:^[[m" code-page]
113-
if string? tmp: try [iconv body code-page][ body: tmp ]
114-
]
103+
header: copy port/state/info/headers
115104

116105
if state/close? [
117106
sys/log/more 'HTTP ["Closing port for:^[[m" port/spec/ref]
118107
close port
119108
]
120-
body
109+
110+
reduce [header body]
121111
]
112+
122113
read-sync-awake: func [event [event!] /local error][
123114
sys/log/debug 'HTTP ["Read-sync-awake:" event/type]
124115
switch/default event/type [
@@ -551,7 +542,7 @@ check-data: func [port /local headers res data available out chunk-size pos trai
551542
conn: state/connection
552543
res: false
553544

554-
sys/log/more 'HTTP ["Check-data; bytes:^[[m" length? conn/data "^[[36mfrom:^[[m" state/read-pos]
545+
sys/log/more 'HTTP ["Check-data; bytes:^[[m" length? conn/data]
555546

556547
case [
557548
headers/transfer-encoding = "chunked" [
@@ -649,6 +640,27 @@ check-data: func [port /local headers res data available out chunk-size pos trai
649640
]
650641
res
651642
]
643+
644+
decode-result: func[
645+
result [block!] {[header body]}
646+
/local body content-type code-page
647+
][
648+
if all [
649+
content-type: select result/1 'Content-Type
650+
any [
651+
; consider content to be a text if charset specification is included
652+
parse content-type [to #";" thru "charset=" copy code-page to end]
653+
; or when it is without charset, but of type text/*
654+
parse content-type [["text/" | "application/json"] to end]
655+
]
656+
][
657+
unless code-page [code-page: "utf-8"]
658+
sys/log/info 'HTTP ["Trying to decode from code-page:^[[m" code-page]
659+
try [result/2: iconv result/2 code-page]
660+
]
661+
result
662+
]
663+
652664
hex-digits: charset "1234567890abcdefABCDEF"
653665
sys/make-scheme [
654666
name: 'http
@@ -668,7 +680,8 @@ sys/make-scheme [
668680
actor: [
669681
read: func [
670682
port [port!]
671-
/binary
683+
/binary
684+
/local result
672685
][
673686
sys/log/debug 'HTTP "READ"
674687
either any-function? :port/awake [
@@ -677,12 +690,16 @@ sys/make-scheme [
677690
port/state/awake: :port/awake
678691
do-request port
679692
][
680-
sync-op port []
693+
result: sync-op port []
694+
unless binary [decode-result result]
695+
result/2
681696
]
682697
]
683698
write: func [
684699
port [port!]
685700
value
701+
/binary
702+
/local result
686703
][
687704
sys/log/debug 'HTTP "WRITE"
688705
;?? port
@@ -696,7 +713,9 @@ sys/make-scheme [
696713
parse-write-dialect port value
697714
do-request port
698715
][
699-
sync-op port [parse-write-dialect port value]
716+
result: sync-op port [parse-write-dialect port value]
717+
unless binary [decode-result result]
718+
result/2
700719
]
701720
]
702721
open: func [
@@ -711,12 +730,12 @@ sys/make-scheme [
711730
connection:
712731
error: none
713732
close?: no
733+
binary?: no
714734
info: make port/scheme/info [type: 'url]
715735
awake: :port/awake
716736
redirects: 0
717737
chunk: none
718738
chunk-size: none
719-
read-pos: 0
720739
]
721740
;? port/state/info
722741
port/state/connection: conn: make port! compose [

0 commit comments

Comments
 (0)