REBOL [ Title: "Cookie Client" Date: 5-Aug-1999 File: %cookies-client.r Author: ["Martin Johannesson" "Andrew Grossman" "Graham Chiu"] Usage: { There are three words here which are very similar in function HTTP-GET To fetch a web page that requires a cookie of name "foo" and value "bar": tmp: http-get http://server.com/page.html ["foo" "bar"] To view the resulting page: print tmp/content If no cookie is required, use an empty list as the parameter tmp: http-get http://server.com/page.html [] HTTP-POST To post values to a web form that does not require cookies set tmp: http-post http://server.com/page.html ["name1" "value1" "name2" "value2" ... ] Note that the name and values pairs will be url encoded by http-post If cookies are returned, then one is placed into cookie-data, and the other is accessible as tmp/set-cookie HTTP-POSTC To post values to a web form that requires cookies set Preset the cookies values in global variables cookie-data, cookie-data2 tmp: http-postc http://server.com/page.html ["name1" "value1" "name2" "value2" ... ] Note that the name and values pairs will be url encoded by http-post, and the cookies must be pre-urlencoded. If cookies are returned, then one is placed into cookie-data, and the other is accessible as tmp/set-cookie } Purpose: { To grab cookies from the server and post form data. } Email: [grossdog@dartmouth.edu gchiu@compkarori.co.nz] Notes: { Modification of Andrew Grossman's cookies-client script by Graham Chiu. Modification of Martin Johannesson's POST script by Andrew Grossman. Orig. available at www.rebol.com in users' library. } library: [ level: 'advanced platform: none type: 'tool domain: 'web tested-under: none support: none license: none see-also: none ] ] cookie-data: "" cookie-data2: "" url-encode: func [ {URL-encode a string} data "String to encode" /local new-data ][ new-data: make string! "" normal-char: charset [ #"A" - #"Z" #"a" - #"z" #"@" #"." #"*" #"-" #"_" #"0" - #"9" ] if not string? data [return new-data] forall data [ append new-data either find normal-char first data [ first data ][ rejoin ["%" to-string skip tail (to-hex to-integer first data) -2] ] ] new-data ] http-post: func [ {Post a form to a web server without including cookie in the header for identification} url "The URL" data [block!] "A block of name/value pairs to represent the form data" /local encoded-data port-spec HTTP-Post-Header http-request buffer tmp-buffer ][ port-spec: make port! [ scheme: 'tcp port-id: 80 timeout: 0:10 ] net-utils/url-parser/parse-url port-spec url encoded-data: make string! "" foreach [name value] data [ append encoded-data rejoin [ url-encode name "=" url-encode value "&" ] ] remove back tail encoded-data remove back tail encoded-data HTTP-Post-Header: make object! [ Accept: "text/html" User-Agent: reform ["REBOL" system/version] ; Referer: "http://www.mtnsms.com/default.asp?action=login" Content-Type: "application/x-www-form-urlencoded" Content-Length: length? encoded-data ] http-request: rejoin [ "POST /" either found? port-spec/path [port-spec/path][""] either found? port-spec/target [port-spec/target][""] " HTTP/1.0" ] http-port: open/lines [ scheme: 'tcp port-id: port-spec/port-id timeout: port-spec/timeout host: port-spec/host user: port-spec/user pass: port-spec/pass ] insert http-port http-request insert http-port net-utils/export HTTP-Post-Header "^/" insert http-port encoded-data comment { print http-request print net-utils/export HTTP-Post-Header print encoded-data } buffer: make string! 10000 tmp-buffer: reform ["HTTP-Response:" pick http-port 1] while [not none? tmp-buffer] [ append buffer rejoin [tmp-buffer "^/"] tmp-buffer: pick http-port 1 ] close http-port parse buffer [ thru "Set-Cookie:" copy cookie-data to ";" ] HTTP-Header: make object! [ HTTP-Response: Date: Server: Last-Modified: none Accept-Ranges: Content-Encoding: Content-Type: none Content-Length: Location: Expires: Referer: Connection: none ] parse-header HTTP-Header buffer ] http-post-cookie: func [ {Post a form to a web server and include cookie in the header for identification} url "The URL" data [block!] "A block of name/value pairs to represent the form data" /local encoded-data port-spec HTTP-Post-Header http-request buffer tmp-buffer ][ port-spec: make port! [ scheme: 'tcp port-id: 80 timeout: 0:10 ] net-utils/url-parser/parse-url port-spec url encoded-data: make string! "" foreach [name value] data [ append encoded-data rejoin [ url-encode name "=" url-encode value "&" ] ] remove back tail encoded-data remove back tail encoded-data HTTP-Post-Header-Cookie: make object! [ Accept: "text/html" User-Agent: reform ["REBOL" system/version] ; Referer: "http://www.mtnsms.com/sms/" Cookie: join cookie-data [ "; " cookie-data2 ] Content-Type: "application/x-www-form-urlencoded" Content-Length: length? encoded-data ] http-request: rejoin [ "POST /" either found? port-spec/path [port-spec/path][""] either found? port-spec/target [port-spec/target][""] " HTTP/1.0" ] http-port: open/lines [ scheme: 'tcp port-id: port-spec/port-id timeout: port-spec/timeout host: port-spec/host user: port-spec/user pass: port-spec/pass ] insert http-port http-request insert http-port net-utils/export HTTP-Post-Header-Cookie "^/" insert http-port encoded-data comment { print http-request print net-utils/export HTTP-Post-Header-Cookie print encoded-data } buffer: make string! 10000 tmp-buffer: reform ["HTTP-Response:" pick http-port 1] while [not none? tmp-buffer] [ append buffer rejoin [tmp-buffer "^/"] tmp-buffer: pick http-port 1 ] close http-port HTTP-Header: make object! [ HTTP-Response: Date: Server: Last-Modified: none Accept-Ranges: Content-Encoding: Content-Type: none Content-Length: Location: Expires: Referer: Connection: none ] parse-header HTTP-Header buffer ] http-get: func [ {Retrieve a page from web server} url "The URL" data [block!] "A block of name/value pairs to represent the cookies" /local encoded-data port-spec HTTP-Post-Header http-request buffer tmp-buffer ][ port-spec: make port! [ scheme: 'tcp port-id: 80 timeout: 0:10 ] net-utils/url-parser/parse-url port-spec url encoded-data: make string! "" foreach [name value] data [ append encoded-data rejoin [ url-encode name "=" url-encode value "; " ] ] remove back tail encoded-data remove back tail encoded-data HTTP-Post-Header: make object! [ Accept: "*/*" User-Agent: reform ["REBOL" system/version] Host: port-spec/host ] HTTP-Post-Header-Cookie: make object! [ Accept: "*/*" User-Agent: reform ["REBOL" system/version] Host: port-spec/host Cookie: encoded-data ] http-request: rejoin [ "GET /" either found? port-spec/path [port-spec/path][""] either found? port-spec/target [port-spec/target][""] " HTTP/1.0^/" ] http-port: open/lines [ scheme: 'tcp port-id: port-spec/port-id timeout: port-spec/timeout host: port-spec/host user: port-spec/user pass: port-spec/pass ] insert http-port http-request if encoded-data > "" [ insert http-port net-utils/export HTTP-Post-Header-Cookie "^/" ][ insert http-port net-utils/export HTTP-Post-Header "^/" ] buffer: make string! 10000 tmp-buffer: reform ["HTTP-Response:" pick http-port 1] while [not none? tmp-buffer] [ append buffer rejoin [tmp-buffer "^/"] tmp-buffer: pick http-port 1 ] close http-port HTTP-Header: make object! [ HTTP-Response: Date: Server: Last-Modified: none Accept-Ranges: Content-Encoding: Content-Type: none Content-Length: Location: Expires: Referer: Connection: none Set-Cookie: none Set-Cookie: none ] parse-header HTTP-Header buffer ]