Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 19, 2013
- 1548 views
I have a very old one, written for Euphoria 2.3, but it should still work with 4.0
Jim, I can't get that to receive my http_post() call. I wonder if I'm doing this right. Here's my code:
I do have some questions regarding your code. I'll comment on them below.
public function transfer(sequence fPath) sequence result = "FAIL" object filetxt filetxt = read_file( fPath ) if not atom(filetxt) then sequence data, fname fname = filename( fPath ) data = { { "name", fname }, { "company", url:encode(COMPANY_NAME) }, { "transfer", "true" },
What's all this stuff? company? transfer? Does your real cgi-script require them? The one I sent you does not - and it does not support them. (name isn't necessary either, since the filename is included in the one for data.)
You only need two - "data" and "size".
{ "data", filetxt, fname, "text/plain", ENCODE_BASE64 } }
This should be fine with a better cgi-script. However, the one I sent you doesn't support BASE64 encoding. If you use it, it'll work, but the final uploaded file will be BASE64 encoded, and you'll have to decode it yourself.
result = http_post( "http://my.ip.address/files/transfer.esp", { MULTIPART_FORM_DATA, data } ) end if if not equal(result[2],"SUCCESS!") then ERR_MESSAGE = result[2] else ERR_MESSAGE = "" end if return equal(result[2],"SUCCESS!") end function
Why are you checking if it equals "SUCCESS!" ? My cgi-script does not return this string. It returns a line of HTML, pointing to the newly uploaded file. Try printing out result[2] - it should be that line of HTML on success, or an empty string on failure.
Do I have to send CONTENT_LENGTH? I thought http_post() would package that up for me (or the OS would know it), but can't find confirmation.
http_post() does it for you. Take a look at the function itself, but search for Content-Length rather than CONTENT_LENGTH.
I take it back. When I tried this program out, I realized that it doesn't seem to set it up correctly with ENCODING_NONE, as the CONTENT_LENGTH variable (which should be set by Apache from the Content-Length header that http_post() sets) was empty. (Although Apache seems to set it for ENCODING_BASE64 - weird. Maybe it's just easier for Apache to be smart when the file is encoded in BASE64.)
Anyways, you will need to set a size parameter.
Here's the version of your code that I managed to get working.
-- test.exu include std/net/http.e include std/pretty.e include std/io.e include std/net/url.e include std/filesys.e constant COMPANY_NAME="dummy" object ERR_MESSAGE = "" public function transfer(sequence fPath) sequence result = "FAIL" object filetxt filetxt = read_file( fPath ) if not atom(filetxt) then sequence data, fname fname = filename( fPath ) data = { --{ "name", fname }, --{ "company", url:encode(COMPANY_NAME) }, --{ "transfer", "true" }, --{ "data", filetxt, fname, "text/plain", ENCODE_BASE64 } { "data", filetxt, fname, "text/plain", ENCODE_NONE }, {"size", sprintf("%d", length(filetxt))} } --result = http_post( "http://my.ip.address/files/transfer.esp", { MULTIPART_FORM_DATA, data } ) result = http_post( "http://localhost/files/upload.exu", { MULTIPART_FORM_DATA, data } ) end if if not equal(result[2],"SUCCESS!") then ERR_MESSAGE = result[2] else ERR_MESSAGE = "" end if return equal(result[2],"SUCCESS!") end function pretty_print(1, transfer("test.exu")) puts(1,"\n*"&ERR_MESSAGE&"*\n")