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.

Table of Contents

Highest level: READ or WRITE on urls

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).

Lower level: synchronous READ or WRITE with keep-alive

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 port

Now, 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 port

however 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 port

QUERY

After 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 port

INFO 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!

Lowest level: asynchronous operation

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 port

The 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.
⚠️ **GitHub.com Fallback** ⚠️