@@ -49,6 +49,8 @@ idate-to-date: function [date [string!]] [
49
49
]
50
50
;@@==================================================
51
51
52
+ ;@@ just simple trace function
53
+ ;@@net-log: :print
52
54
53
55
sync-op : func [ port body /local state] [
54
56
unless port/state [open port port/state/close?: yes]
@@ -60,14 +62,26 @@ sync-op: func [port body /local state] [
60
62
;The timeout should be triggered only when the response from other side exceeds the timeout value.
61
63
;--Richard
62
64
while [not find [ready close] state/state ][
65
+ ;@@net-log ["########### sync-op.." state/state]
63
66
unless port? wait [state/connection port/spec/timeout ] [http-error "Timeout" ]
64
- if state/state = 'reading-data [read state/connection ]
67
+ ;@@net-log ["########### sync-op wakeup" state/state]
68
+ switch state/state [
69
+ reading-data [
70
+ read state/connection
71
+ ]
72
+ redirect [
73
+ do-redirect port port/state/info/headers/location
74
+ state: port/state
75
+ state/awake: :read-sync-awake
76
+ ]
77
+ ]
65
78
]
66
79
body: copy port
67
80
if state/close? [close port]
68
81
body
69
82
]
70
83
read-sync-awake : func [ event [event! ] /local error] [
84
+ ;@@net-log ["[HTTP read-sync-awake]" event/type]
71
85
switch /default event/type [
72
86
connect ready [
73
87
do-request event/port
@@ -79,6 +93,13 @@ read-sync-awake: func [event [event!] /local error] [
79
93
close [
80
94
true
81
95
]
96
+ custom [
97
+ if event/offset/x = 300 [
98
+ event/port/state/state: 'redirect
99
+ return true
100
+ ]
101
+ false
102
+ ]
82
103
error [
83
104
error: event/port/state/error
84
105
event/port/state/error: none
@@ -94,6 +115,11 @@ http-awake: func [event /local port http-port state awake res] [
94
115
state: http-port/state
95
116
if any-function? : http-port/awake [state/awake: : http-port/awake ]
96
117
awake: : state/awake
118
+
119
+ ;@@net-log ["[HTTP http-awake]" event/type]
120
+
121
+ ;?? awake
122
+
97
123
switch /default event/type [
98
124
read [
99
125
awake make event! [type: 'read port: http-port]
@@ -200,9 +226,10 @@ do-request: func [
200
226
port/state/state: 'doing-request
201
227
info/headers: info/response-line: info/response-parsed: port/data:
202
228
info/size: info/date: info/name: none
203
- write port/state/connection
204
- make-http-request spec/method to file! any [spec/path %/ ]
205
- spec/headers spec/content
229
+
230
+ ;@@net-log ["[HTTP do-request]" spec/method spec/host spec/path]
231
+
232
+ write port/state/connection make-http-request spec/method to file! any [spec/path %/ ] spec/headers spec/content
206
233
]
207
234
parse-write-dialect : func [ port block /local spec] [
208
235
spec: port/spec
@@ -218,6 +245,9 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
218
245
line: info/response-line
219
246
awake: : state/awake
220
247
spec: port/spec
248
+
249
+ ;@@net-log ["[HTTP check-response]" info/response-parsed]
250
+
221
251
if all [
222
252
not headers
223
253
d1: find conn/data crlfbin
@@ -267,6 +297,9 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
267
297
| (info/response-parsed: 'version-not-supported)
268
298
]
269
299
]
300
+ ;?? info/response-parsed
301
+ ;?? spec/method
302
+
270
303
switch /all info/response-parsed [
271
304
ok [
272
305
either spec/method = 'head [
@@ -290,9 +323,13 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
290
323
unless open? port [
291
324
;NOTE some servers(e.g. yahoo.com) don't supply content-data in the redirect header so the state/state can be left in 'reading-data after check-data call
292
325
;I think it is better to check if port has been closed here and set the state so redirect sequence can happen. --Richard
293
- state/state: 'ready
326
+ state/state: 'redirect ; ready
294
327
]
295
328
]
329
+ ;?? res
330
+ ;?? headers
331
+ ;?? state/state
332
+
296
333
if all [not res state/state = 'ready] [
297
334
either all [
298
335
any [
@@ -304,7 +341,7 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
304
341
]
305
342
in headers 'Location
306
343
] [
307
- res: do-redirect port headers /location
344
+ return awake make event! [ type: 'custom port: port code: 300 ]
308
345
] [
309
346
state/error: make-http-error "Redirect requires manual intervention"
310
347
res: awake make event! [type: 'error port: port]
@@ -379,30 +416,34 @@ do-redirect: func [port [port!] new-uri [url! string! file!] /local spec state]
379
416
]
380
417
]
381
418
new-uri: construct /with new-uri port/scheme/spec
419
+ new-uri/ref: to url! ajoin [new-uri/scheme "://" new-uri/host new-uri/path ]
420
+ new-uri/method: spec/method
421
+
422
+ ;@@net-log ["[HTTP do-redirect] new-uri:" mold new-uri]
423
+ ;?? port
424
+
382
425
unless find [http https] new-uri/scheme [
383
426
state/error: make-http-error {Redirect to a protocol different from HTTP or HTTPS not supported}
384
427
return state/awake make event! [type: 'error port: port]
385
428
]
386
- either all [
387
- new-uri/host = spec/host
388
- new-uri/port-id = spec/port-id
389
- ] [
390
- spec/path: new-uri/path
391
- ;we need to reset tcp connection here before doing a redirect
392
- close port/state/connection
393
- open port/state/connection
394
- do-request port
395
- false
396
- ] [
397
- state/error: make-http-error "Redirect to other host - requires custom handling"
398
- state/awake make event! [type: 'error port: port]
399
- ]
429
+
430
+ ;we need to reset tcp connection here before doing a redirect
431
+ clear spec/headers
432
+ port/data: none
433
+ close port/state/connection
434
+
435
+ port/spec: spec: new-uri
436
+ port/state: none
437
+ open port
400
438
]
401
439
check-data : func [ port /local headers res data out chunk-size mk1 mk2 trailer state conn] [
402
440
state: port/state
403
441
headers: state/info/headers
404
442
conn: state/connection
405
443
res: false
444
+
445
+ ;@@net-log ["[HTTP check-data] bytes:" length? conn/data]
446
+
406
447
case [
407
448
headers/transfer-encoding = "chunked" [
408
449
data: conn/data
@@ -449,7 +490,7 @@ check-data: func [port /local headers res data out chunk-size mk1 mk2 trailer st
449
490
port/data: conn/data
450
491
either headers/content-length <= length? port/data [
451
492
state/state: 'ready
452
- conn/data: make binary! 32000
493
+ conn/data: make binary! 32000 ;@@ Oldes: why not just none?
453
494
res: state/awake make event! [type: 'custom port: port code: 0 ]
454
495
] [
455
496
;Awake from the WAIT loop to prevent timeout when reading big data. --Richard
@@ -489,6 +530,7 @@ sys/make-scheme [
489
530
read : func [
490
531
port [port! ]
491
532
] [
533
+ ;@@net-log "[HTTP read]"
492
534
either any-function? : port/awake [
493
535
unless open? port [cause-error 'Access 'not-open port/spec/ref ]
494
536
if port/state/state <> 'ready [http-error "Port not ready" ]
@@ -503,8 +545,11 @@ sys/make-scheme [
503
545
port [port! ]
504
546
value
505
547
] [
548
+ ;@@net-log "[HTTP write]"
549
+ ;?? port
506
550
unless any [block? :value binary? :value any-string? :value ] [value: form :value ]
507
551
unless block? value [value: reduce [[Content-Type: "application/x-www-form-urlencoded; charset=utf-8" ] value]]
552
+
508
553
either any-function? : port/awake [
509
554
unless open? port [cause-error 'Access 'not-open port/spec/ref ]
510
555
if port/state/state <> 'ready [http-error "Port not ready" ]
@@ -520,6 +565,7 @@ sys/make-scheme [
520
565
port [port! ]
521
566
/local conn
522
567
] [
568
+ ;@@net-log ["[HTTP open]" port/state]
523
569
if port/state [return port]
524
570
if none? port/spec/host [http-error "Missing host address" ]
525
571
port/state: context [
@@ -534,10 +580,13 @@ sys/make-scheme [
534
580
scheme: (to lit-word! either port/spec/scheme = 'http ['tcp]['tls])
535
581
host: port/spec/host
536
582
port-id: port/spec/port-id
537
- ref: rejoin [tcp :// host ":" port-id]
583
+ ref: rejoin [to url! scheme " ://" host # ":" port-id]
538
584
]
585
+ ;?? conn
539
586
conn/awake: :http-awake
540
587
conn/locals: port
588
+ ;@@net-log ["[HTTP opne]" conn/spec/scheme conn/spec/host]
589
+ ;?? conn
541
590
open conn
542
591
port
543
592
]
@@ -549,6 +598,7 @@ sys/make-scheme [
549
598
close : func [
550
599
port [port! ]
551
600
] [
601
+ ;@@net-log "[HTTP close]"
552
602
if port/state [
553
603
close port/state/connection
554
604
port/state/connection/awake: none
@@ -577,8 +627,9 @@ sys/make-scheme [
577
627
state: port/state
578
628
close port
579
629
]
630
+ ;?? state
580
631
if none? state [return none]
581
- either state/info/response-parsed = 'ok [
632
+ either find [ok redirect] state/info/response-parsed [
582
633
state/info
583
634
][ none ]
584
635
]
0 commit comments