@@ -241,59 +241,73 @@ throw-http-error: func [
241
241
]
242
242
243
243
make-http-request : func [
244
- "Create an HTTP request (returns string!)"
245
- method [word! string! ] "E.g. GET, HEAD, POST etc."
246
- target [file! string! ] {In case of string!, no escaping is performed (eg. useful to override escaping etc.). Careful!}
247
- headers [block! map! ] "Request headers (set-word! string! pairs)"
248
- content [any-string! binary! map! none! ] {Request contents (Content-Length is created automatically). Empty string not exactly like none.}
249
- /local result
244
+ "Create an HTTP request (returns binary!)"
245
+ spec [block! ] "Request specification from an opened port"
246
+ /local method path target query headers content request
250
247
] [
251
- result: rejoin [
252
- uppercase form method #" "
253
- either file? target [next mold target][target]
254
- " HTTP/1.1" CRLF
248
+ method: any [select spec 'method 'GET]
249
+ path: any [select spec 'path %/ ]
250
+ target: select spec 'target
251
+ query: select spec 'query
252
+ headers: any [select spec 'headers []]
253
+ content: select spec 'content
254
+
255
+ request: ajoin [
256
+ uppercase form :method SP
257
+ mold as url! :path ;; `mold as url!` is used because it produces correct escaping
255
258
]
256
- foreach [word string] headers [
257
- repend result [mold word #" " string CRLF]
259
+ if :target [append request mold as url! :target ]
260
+ if :query [append append request #"?" :query ]
261
+
262
+ append request " HTTP/1.1^M^/ "
263
+
264
+ foreach [word string] :headers [
265
+ append request ajoin [form :word #":" SP :string CRLF]
258
266
]
259
- if content [
260
- if map? content [content: to-json content]
261
- content: to binary! content
262
- repend result ["Content-Length: " length? content CRLF]
267
+
268
+ if :content [
269
+ if map? :content [
270
+ content: to-json content
271
+ unless find headers 'Content-Type [
272
+ append request "Content-Type: application/json^M^/ "
273
+ ]
274
+ ]
275
+ content: to binary! :content
276
+ append request ajoin [
277
+ "Content-Length: " length? content CRLF
278
+ ]
263
279
]
264
- sys/log/info 'HTTP ["Request:^[ [22m" mold result ]
280
+ sys/log/info 'HTTP ["Request:^[ [22m" mold request ]
265
281
266
- append result CRLF
267
- result : to binary! result
268
- if content [append result content]
269
- result
282
+ append request CRLF
283
+ request : to binary! request
284
+ if content [append request content]
285
+ request
270
286
]
287
+
271
288
do-request : func [
272
289
"Perform an HTTP request"
273
290
port [port! ]
274
291
/local spec info
275
292
] [
276
293
spec: port/spec
277
294
info: port/state/info
278
- spec/headers: body-of make make object! [
279
- Accept: "*/*"
280
- Accept-charset: "utf-8"
281
- Accept-Encoding: "gzip,deflate"
282
- Host: either not find [80 443 ] spec/port [
283
- ajoin [spec/host #":" spec/port ]
284
- ][
295
+
296
+ spec/headers: make system/schemes/http/headers to block! spec/headers
297
+
298
+ unless spec/headers/host [
299
+ spec/headers/host: either find [80 443 ] spec/port [
300
+ ; default http/https scheme port ids
285
301
form spec/host
302
+ ][ ; custom port id
303
+ ajoin [spec/host #":" spec/port ]
286
304
]
287
- User-Agent: any [system/schemes/http/User-Agent "REBOL" ]
288
- ] to block! spec/headers
305
+ ]
289
306
port/state/state: 'doing-request
290
307
info/headers: info/response-line: info/response-parsed: port/data:
291
308
info/size: info/date: info/name: none
292
309
293
- ;sys/log/info 'HTTP ["Request:^[[22m" spec/method spec/host mold spec/path]
294
-
295
- ;write port/state/connection make-http-request spec/method enhex as file! any [spec/path %/] spec/headers spec/content
296
- write port/state/connection make-http-request spec/method any [spec/path %/ ] spec/headers spec/content
310
+ write port/state/connection make-http-request :spec
297
311
]
298
312
parse-write-dialect : func [ port block /local spec] [
299
313
spec: port/spec
@@ -875,9 +889,16 @@ sys/make-scheme [
875
889
either port/data [length? port/data ][0 ]
876
890
]
877
891
]
878
- User-Agent: none
879
- ;@@ One can set above value for example to: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
880
- ;@@ And so pretend that request is coming from Chrome on Windows10
892
+ ; default request header values...
893
+ headers : context [
894
+ Host: none
895
+ Accept: "*/*"
896
+ Accept-charset: "utf-8"
897
+ Accept-Encoding: "gzip,deflate"
898
+ User-Agent: ajoin ["rebol/" system/version " (" system/platform "; " system/build/arch #")" ]
899
+ ;@@ One can set above value for example to: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
900
+ ;@@ And so pretend that request is coming from Chrome on Windows10
901
+ ]
881
902
]
882
903
883
904
sys/make-scheme/with [
0 commit comments