Schemes HTTP - r3n/rebol-wiki GitHub Wiki
Schemes > HTTP
The HTTP scheme implements an HTTP 1.1 client as a port handler. HTTP ports can be used at different level of abstraction.
At the highest level, you can just read an url:
result: read http://www.rebol.com/RESULT will contain the HTML page found at http://www.rebol.com/. The operation is synchronous.
It is also possible to do a POST request to a CGI script using:
result: write http://yourhost.com/cgi-bin/myscript.cgi {Posted data}Or, do any other kind of HTTP request with:
result: write http://yourhost.com/path/to/file [method [Header: "Value"] {Request contents}]where method is a word used as the request method (eg. GET, POST, HEAD etc.), custom HTTP headers can be passed as a block (evaluated like with make object! block), and the request contents can be supplied as a string or binary value. (Method, headers and content are optional; the method defaults to POST for a WRITE request.) A common example is:
result: write http://www.rebol.com/ [head]for doing a HEAD request; in this case, since the result has no content, RESULT will be a block containing the file name (can be different from the requested one in case of a redirect), the file size in bytes (if the server reports it) and the file's last modification date (if the server reports it).
With HTTP/1.1 servers, it is possible to do many requests with a single TCP connection. This can be done with:
port: open http://www.rebol.com/
result: read portNow, it is possible to do more requests on the same port. Calling READ again will repeat the previous request; to request new files, use WRITE:
result2: write port [get %file1.html]
result3: write port [get %file2.html]It is also possible to use:
port/spec/path: %file3.html
result4: read porthowever we suggest using WRITE instead. Other request methods etc. can be used as described above:
result5: write port [method %target-file [Header: "Value"] {Request contents}]When finished with all the requests, you should close the port:
close portAfter doing a request with READ or WRITE as described above, it is possible to use QUERY to obtain more information on the response.
port: open http://www.rebol.com/
result: read port
info: query port
close portINFO will be an object with the following fields:
- name
- file name
- size
- file size in bytes (may be none)
- date
- file modification date (may be none)
- type
- always 'file
- response-line
- HTTP response line as a string (eg. "HTTP/1.1 200 Ok")
- response-parsed
- parsed response line (one of 'ok, 'redirect, 'see-other, 'unauthorized, 'client-error, 'server-error, 'proxy-auth, 'not-modified, 'use-proxy, 'no-content, 'info or 'version-not-supported); note that you don't normally see most of them at this level of abstraction - you either have 'ok or get an actual error
- headers
- HTTP response headers as an object!
At the lowest level, the HTTP handler can behave asynchronously. You set an awake function for the port and then react to port events.
port: make port! http://www.rebol.com/
port/awake: func [event] [
switch event/type [
connect [read event/port]
done [print copy event/port return true]
]
false
]
open port
wait portThe wait is interrupted as soon as the awake function returns TRUE. The events you can get are:
- read
- some data has been read (can be used to report progress, eg. show length? port)
- wrote
- some data has been written (eg still making request)
- connect
- connection has been established, ready to make request (you can call READ or WRITE at this point)
- ready
- port is ready for new request (you get this after doing a request, if the server allows sending more; you can call READ or WRITE again at this point to do more requests)
- done
- response has been received completely, you can get the data with copy port or check headers etc. with query port
- close
- server closed connection, no more requests can be done
- error
- there's been an error, you can get the actual error! value with error: query port
- custom
- if event/code is 0, the response has been received completely, but has not been processed yet. This can be used for custom processing of the response: if you return true, no further processing is done (no check for error or redirect and so on) so you can get the response-line (or response-parsed) and the response headers with query port and do any processing on your own.