I've been trying to update Ross-Gill's Twitter API for REBOL2 to support uploading media. From looking at its source, the REBOL cookbook, the codeconscious site, and other questions here, my understanding is that read/custom
is the preferred way to POST
data to websites.
However, I haven't been able to find any real documentation on read/custom
. For example: Does it support sending multipart/form-data
? (I've managed to work around this by manually composing each part, but it doesn't seem to work for all image files on Twitter's end and is a bit of a hack). Does read/custom
only return text on an HTTP/1.0 200 OK
response? (It appears so, which is problematic when I receive HTTP/1.0 202 Accepted
and need to read the resulting data). Is there a reason that read/custom/binary
doesn't appear to send binary data correctly without converting the data using to-string
?
TL;DR: Is there good documentation on REBOL2's read/custom
somewhere? Alternatively, is read/custom
only meant for basic POST
s and I should be using ports and handling the HTTP responses manually?
You guessed right, read/custom
is meant for simple HTTP posts, handling web forms data only (that is why it will fail on binary data). No official documentation for it. But that is not an issue as you can access the source code of the HTTP implementation:
probe system/schemes/HTTP
There you can see that /custom
refinement supports two keywords, post
and header
(for setting custom HTTP headers). It also appears that even if you use both keywords, Content-Type
will be forced to application/x-www-form-urlencoded
no matter what (which is probably the reason why your binary data gets rejected by the server, as the provided mime type is wrong).
In order to work around that, you can save the HTTP object, modify its implementation to fit your needs and reload it.
Saving:
save %http-scheme.r system/schemes/HTTP
Reloading:
system/schemes/HTTP: do load %http-scheme.r
If you just disable the hard-coded Content-Type
setting in the HTTP code, and then provide your own one using header
keyword, it should work fine, even with binary data:
read/custom <url> [header [Content-Type: <...>] post <data>]
Hope this helps.