How to pass cookie url using Rebol 3 and get response cookies?
See this question on stackoverflow - How to pass cookie url using Rebol 3? - almost answers my question, but I'm not sure how to write cookies from the answer.
What I would like to do is access the url passed in the cookies (and headers) and be able to view the response and the cookies (and headers).
I think what I need to do to open
port and then I can query
answer. Something like that:
site: open http://rebol.com
write site [ GET [ Cookie: {test=1}] ]
query site
close site
Is this the best approach?
source to share
I am doing this using the http protocol which has been changed to
- use an extra header in the post dialect that returns a port object so you can check the body and header
- returns an error object with a port object on error, eg. manual redirection required.
The file is available at:
https://raw.githubusercontent.com/gchiu/Rebol3/master/protocols/prot-http.r3
>> do https://raw.githubusercontent.com/gchiu/Rebol3/master/protocols/prot-http.r3
>> a: write http://stackoverflow.com [ headers "" ]
>> probe a/spec/debug/headers/set-cookie
[{__cfduid=d349046701c0e9fd9f8858fa4b406ff141438752651; expires=Thu, 04-Aug-16 0
5:30:51 GMT; path=/; domain=.stackoverflow.com; HttpOnly} {prov=f1a9c7a9-cd49-44
82-94e0-4594c7991c19; domain=.stackoverflow.com; expires=Fri, 01-Jan-2055 00:00:
00 GMT; path=/; HttpOnly}]
Here is a .patch file other than http.r currently used by Atronix and Ren / C :
diff --git a/src/mezz/prot-http.r b/src/mezz/prot-http.r
index 426f115..dfa344a 100644
--- a/src/mezz/prot-http.r
+++ b/src/mezz/prot-http.r
@@ -11,16 +11,27 @@ REBOL [
}
Name: 'http
Type: 'module
- Version: 0.1.4
- File: %prot-http.r
+ Version: 0.1.45
+ File: %prot-http.r3
Purpose: {
This program defines the HTTP protocol scheme for REBOL 3.
}
- Author: ["Gabriele Santilli" "Richard Smolak"]
- Date: 26-Nov-2012
+ Author: ["Gabriele Santilli" "Richard Smolak" "Graham Chiu"]
+ notes: {modified to return an error object with the info object when manual redirect required - Graham}
+ Date: 27-April-2014
]
-sync-op: func [port body /local state] [
+digit: charset [ #"0" - #"9" ]
+alpha: charset [ #"a" - #"z" #"A" - #"Z" ]
+idate-to-date: func [ date [string!] /local day month year time zone]
+[
+ either parse date [ 5 skip copy day 2 digit space copy month 3 alpha space copy year 4 digit space copy time to space space copy zone to end ][
+ if zone = "GMT" [ zone: copy "+0" ]
+ to date! ajoin [ day "-" month "-" year "/" time zone ]
+ ][ none ]
+]
+
+sync-op: func [port body /local state ] [
unless port/state [open port port/state/close?: yes]
state: port/state
state/awake: :read-sync-awake
@@ -35,7 +46,11 @@ sync-op: func [port body /local state] [
]
body: copy port
if state/close? [close port]
- body
+ either port/spec/debug [
+ state/connection/locals
+ ][
+ body
+ ]
]
read-sync-awake: func [event [event!] /local error] [
switch/default event/type [
@@ -111,12 +126,34 @@ http-awake: func [event /local port http-port state awake res] [
make-http-error: func [
"Make an error for the HTTP protocol"
message [string! block!]
+ /inf obj
+ /otherhost new-url [url!]
] [
if block? message [message: ajoin message]
- make error! [
- type: 'Access
- id: 'Protocol
- arg1: message
+ case [
+ inf [
+ make error! [
+ type: 'Access
+ id: 'Protocol
+ arg1: message
+ arg2: obj
+ ]
+ ]
+ otherhost [
+ make error! [
+ type: 'Access
+ id: 'Protocol
+ arg1: message
+ arg3: new-url
+ ]
+ ]
+ true [
+ make error! [
+ type: 'Access
+ id: 'Protocol
+ arg1: message
+ ]
+ ]
]
]
http-error: func [
@@ -174,9 +211,11 @@ do-request: func [
make-http-request spec/method to file! any [spec/path %/]
spec/headers spec/content
]
-parse-write-dialect: func [port block /local spec] [
+parse-write-dialect: func [port block /local spec debug] [
spec: port/spec
- parse block [[set block word! (spec/method: block) | (spec/method: 'post)]
+ parse block [
+ opt [ 'headers ( spec/debug: true ) ]
+ [set block word! (spec/method: block) | (spec/method: 'post)]
opt [set block [file! | url!] (spec/path: block)] [set block block! (spec/headers: block) | (spec/headers: [])] [set block [any-string! | binary!] (spec/content: block) | (spec/content: none)]
]
]
@@ -197,7 +236,7 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
info/headers: headers: construct/with d1 http-response-headers
info/name: to file! any [spec/path %/]
if headers/content-length [info/size: headers/content-length: to integer! headers/content-length]
- if headers/last-modified [info/date: attempt [to date! headers/last-modified]]
+ if headers/last-modified [info/date: attempt [idate-to-date headers/last-modified]]
remove/part conn/data d2
state/state: 'reading-data
]
@@ -237,6 +276,9 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
| (info/response-parsed: 'version-not-supported)
]
]
+ if all [logic? spec/debug true? spec/debug] [
+ spec/debug: info
+ ]
switch/all info/response-parsed [
ok [
either spec/method = 'head [
@@ -276,7 +318,7 @@ check-response: func [port /local conn res headers d1 d2 line info state awake s
] [
res: do-redirect port headers/location
] [
- state/error: make-http-error "Redirect requires manual intervention"
+ state/error: make-http-error/inf "Redirect requires manual intervention" info
res: awake make event! [type: 'error port: port]
]
]
@@ -364,7 +406,7 @@ do-redirect: func [port [port!] new-uri [url! string! file!] /local spec state]
do-request port
false
] [
- state/error: make-http-error "Redirect to other host - requires custom handling"
+ state/error: make-http-error/otherhost "Redirect to other host - requires custom handling" to-url rejoin [new-uri/scheme "://" new-uri/host new-uri/path]
state/awake make event! [type: 'error port: port]
]
]
@@ -449,6 +491,7 @@ sys/make-scheme [
headers: []
content: none
timeout: 15
+ debug: none
]
info: make system/standard/file-info [
response-line:
source to share