Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: POST examples ...

From: gjones05:mail:orion at: 4-Jun-2001 10:48

From: "Petr Krenzelok" ...
> I thought I will kill someone for putting "function" into website in > lowercase. I spent nearly one hour figuring out what is the problem
.... I think we've all had that happen. Frustrating.
> yes, but I am not using ftp. I am using http post method, so I don't
know if
> such aproach is even possible ...
OK, not trying to beat a dead horse here, but what the heck. The same principle can be applied to http get requests. This example grabs the second half of Microsoft's home page. from-port: open/direct http://www.microsoft.com to-port: open/direct %//windows/desktop/log.txt from-port: skip from-port 8000 while [data: copy/part from-port 1000][append to-port data] close from-port close to-port However, you need to make the request with a 'post request, so I shamelessly hacked Martin Johannesson's http-post.r (the original url is no longer correct, so I also updated it). I commented the major changes so that you could see what I've done compared to the original. You will see that this method could be readily cleaned up and made more generic and encapsulated. Watch for wrapped lines!!! ;============================= REBOL [ Title: "Simple HTTP POST" File: %http-post.r Author: "Martin Johannesson" Email: [d95-mjo--nada--kth--se] Date: 30-Jun-1999 Purpose: { This script sends a "form" to a webserver using the POST method. The included example translates a string in English to German by posting the data to AltaVista's translation web page and then parsing the reply. } Category: [web util net 4] Comment: {Shamelessly hacked by Scott Jones for demonstrating tight http control for my good, friend Petr Krenzelok ;-} ] 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-form: func [ {Post a form to a web server} url "The URL to post to" data [block!] "A block of name/value pairs to represent the form" /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 HTTP-Post-Header: make object! [ Accept: "*/*" User-Agent: reform ["REBOL" system/version] Host: port-spec/host 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^/" net-utils/export HTTP-Post-Header "^/" encoded-data ] ;dropped lines refinement and added direct http-port: open/direct [ scheme: 'tcp port-id: port-spec/port-id timeout: port-spec/timeout host: port-spec/host user: port-spec/user pass: port-spec/pass ] ;inserts 'post request insert http-port http-request ;now grabbing header stuff 1 byte at a time ;so that we can get content length ;look for two newlines in a row data: make string! 1000 while [not parse/all data [to "^/^/" to end]][ append data copy/part http-port 1 ] ;parses out the content length into ret-length ;which is left as a string for now parse data [thru "Content-Length: " copy ret-length to "^/" to end] ;print ret-length ;now get the rest of the file in what ever proportions you want data: make string! 1000 l-port: open/direct %//windows/desktop/log.txt ;uncomment the next line if you wish to skip some amount of info ;http-port: skip http-port 2000 while [data: copy/part http-port 1000][append l-port data] close http-port close l-port comment { 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 ] english-to-german: func [ {Translates a string in English to German, using babelfish.altavista.com} english-text "String in english" ][ not-lt-gt: complement charset [#"<" #">"] tag-rule: ["<" some not-lt-gt ">"] tmp: http-post-form http://babelfish.altavista.com/tr reduce [ "doit" "done" "urltext" english-text "lp" "en_de" ] comment { if none? find tmp/HTTP-Response "200" [return join "Error: " tmp/HTTP-Response] either parse tmp/content [ thru "Auf Deutsch:" to "<font" thru ">" copy trans to "<" to end ][ return trans ][ return "Error: Unable to parse Babelfish HTML" ] } ] english-to-german "hello, how are you?" ;===============================
> One crazy thought: would it be possible to use http port 'awake field
for
> calling the fucntion, which would count current buffer size and could
update
> the progress bar?
It seems like there should be some way, knowing the total length and the chunk lengths. Hope this one helps *and* solve the problem. --Scott Jones