1. Sending a File Over HTTP
- Posted by euphoric (admin) Aug 07, 2013
- 2044 views
How do you send a large file over the Internet via HTTP with a Euphoria program?
I can program both the client and server (and both are programmed in Euphoria), I just need to know the best way. Is it necessary to use multi-part from the Euphoria program to push a file to a server?
Thanks!
2. Re: Sending a File Over HTTP
- Posted by ChrisB (moderator) Aug 07, 2013
- 2012 views
Hi
Coincidental, this topic has just become live for me again, I've just received a test account, the login details, and the specs from my supplier. I have a suspicion that euphoria can't as yest post a text file (I could be wrong), but am about to start writing test programs)
http://openeuphoria.org/forum/120643.wc#120643
Chris
3. Re: Sending a File Over HTTP
- Posted by useless_ Aug 07, 2013
- 2014 views
How do you send a large file over the Internet via HTTP with a Euphoria program?
I can program both the client and server (and both are programmed in Euphoria), I just need to know the best way. Is it necessary to use multi-part from the Euphoria program to push a file to a server?
Thanks!
Use POST, but why use http?
useless
4. Re: Sending a File Over HTTP
- Posted by useless_ Aug 07, 2013
- 2032 views
Hi
Coincidental, this topic has just become live for me again, I've just received a test account, the login details, and the specs from my supplier. I have a suspicion that euphoria can't as yest post a text file (I could be wrong), but am about to start writing test programs)
http://openeuphoria.org/forum/120643.wc#120643
Chris
I was using POST with Eu years ago, but i don't recall if any of it made it into the official Eu releases, i think everything i put into http.e was removed/rewritten, and eunet was sorta ignored by everyone.
useless
5. Re: Sending a File Over HTTP
- Posted by useless_ Aug 07, 2013
- 2012 views
Come to remember it, i was using Eu to http files on the internet in the v3.1 days, back when i was more useful and Tiggr was online. Peoples on irc could get urls from her to the domain she seemed to be on back then, but what would happen is a php script on the webhost sent the user req to an Eu app running on my home computer, which then sent the reply back upstream to the host and then to the user, and if necessary uploaded a 2nd file to the webhost and gave the url to it in the reply to the user. People on irc hated the idea because they had to launch a browser to get the file. The people were too lazy to click on an url and let a browser open. Tiggr could also download, read, and reply to email. Just some of the code i deleted later.
useless
6. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 07, 2013
- 2030 views
How do you send a large file over the Internet via HTTP with a Euphoria program?
I can program both the client and server (and both are programmed in Euphoria), I just need to know the best way. Is it necessary to use multi-part from the Euphoria program to push a file to a server?
Thanks!
Using multi-part appears to be supported.
Here's an example from the http test: http://scm.openeuphoria.org/hg/euphoria/file/01eab55e774d/tests/t_net_http.e
-- multipart form data sequence file_content = "Hello, World. This is an icon. I hope that this really works. I am not really sure but we will see" object data = { { "size", sprintf("%d", length(file_content)) }, { "file", file_content, "example.txt", "text/plain", ENCODE_BASE64 } } -- post file script gets size and file parameters, calls decode_base64, and sends -- back SIZE\nDECODED_FILE_CONTENTS. The test script is written in Perl to test against -- modules we did not code, i.e. CGI and Base64 in this case. object content = http_post("http://test.openeuphoria.org/post_file.cgi", { MULTIPART_FORM_DATA, data }) if atom(content) or length(content) < 2 then test_fail("multipart form file upload") else test_equal("multipart form file upload", data[1][2] & "\n" & file_content, content[2]) end if
7. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 07, 2013
- 2010 views
Hi
Coincidental, this topic has just become live for me again, I've just received a test account, the login details, and the specs from my supplier. I have a suspicion that euphoria can't as yest post a text file (I could be wrong), but am about to start writing test programs)
http://openeuphoria.org/forum/120643.wc#120643
Chris
Aren't you using curl or libcurl for that? Posting a text file the standard way should work just fine with the stdlib, but your case is not standard.
Untested, but I just mocked up a version of http.e that should do what you need. See http://openeuphoria.org/pastey/229.wc
Here's how you'd call it (assuming that it works):
-- custom data sequence file_content = "COMMAND\tORDER\r\nAUTH\t\YES\r\n..." -- if you have a text file in the right format with the right data, -- you should be able to just read its contents into file_content as -- a flat sequence -- post file script gets size and file parameters, calls decode_base64, and sends -- back SIZE\nDECODED_FILE_CONTENTS. The test script is written in Perl to test against -- modules we did not code, i.e. CGI and Base64 in this case. object content = http_post("http://confidential/program.cgi", { RAW_POST_DATA, "application/x-what-goes-here", file_content })
Your posts didn't specify if a particular content-type was required, and if so what that should be (e.g application/x-what-goes-here). Your data interface specs should have this information.
8. Re: Sending a File Over HTTP
- Posted by m_sabal Aug 08, 2013
- 1943 views
Euphoria can open sockets on a specified port, and send and receive bytes on that socket. That means Euphoria is capable of doing anything with sockets that the peer allows. The effort required to accomplish that goal, however, is a balance of what convenience functions already exist and how much you have to write yourself.
9. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 08, 2013
- 1943 views
How do you send a large file over the Internet via HTTP with a Euphoria program?
I can program both the client and server (and both are programmed in Euphoria), I just need to know the best way. Is it necessary to use multi-part from the Euphoria program to push a file to a server?
Thanks!
Use POST, but why use http?
useless
Ah, yes! POST! Why didn't I think of that. Thanks, kat!
What else would I use, BTW?
10. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 08, 2013
- 1944 views
Using multi-part appears to be supported.
Here's an example...
Awesome! Thanks, jim! I'll look into that.
11. Re: Sending a File Over HTTP
- Posted by useless_ Aug 08, 2013
- 1900 views
How do you send a large file over the Internet via HTTP with a Euphoria program?
I can program both the client and server (and both are programmed in Euphoria), I just need to know the best way. Is it necessary to use multi-part from the Euphoria program to push a file to a server?
Thanks!
Use POST, but why use http?
useless
Ah, yes! POST! Why didn't I think of that. Thanks, kat!
What else would I use, BTW?
You could use PUT, it's like a hybrid FTP in the HTTP protocol. I imagine not everyone supports it.
https://www.google.com/search?q=PUT+http
useless
12. Re: Sending a File Over HTTP
- Posted by useless_ Aug 08, 2013
- 1939 views
Euphoria can open sockets on a specified port, and send and receive bytes on that socket. That means Euphoria is capable of doing anything with sockets that the peer allows. The effort required to accomplish that goal, however, is a balance of what convenience functions already exist and how much you have to write yourself.
Very true. If i wanted to POST a file in the next 30 seconds, i'd use wget and switches:
--post-data=STRING use the POST method; send STRING as the data. --post-file=FILE use the POST method; send contents of FILE.
But if i had some time and wanted to make the process smarter, more versatile, i'd naturally whip up an Euphoria app. Or if i wanted to use PUT, because afaik wget v1.11.4 doesn't support it.
useless
13. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 15, 2013
- 1761 views
OK, HTTP POST experts... What does a server-side program look like when receiving a MULTIPART HTTP POST request?
14. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 15, 2013
- 1777 views
OK, HTTP POST experts... What does a server-side program look like when receiving a MULTIPART HTTP POST request?
You mean a cgi script running under Apache 2.2, or a full HTTP server written in Euphoria?
15. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 16, 2013
- 1702 views
OK, HTTP POST experts... What does a server-side program look like when receiving a MULTIPART HTTP POST request?
You mean a cgi script running under Apache 2.2, or a full HTTP server written in Euphoria?
I just mean a Euphoria CGI script running under Apache!
Let me add that I was using GET and parsing it just fine with the getenv("QUERY_STRING"). However, QUERY_STRING is empty and STDIN is -1 when trying to use POST.
Thanks!
16. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 16, 2013
- 1722 views
OK, HTTP POST experts... What does a server-side program look like when receiving a MULTIPART HTTP POST request?
You mean a cgi script running under Apache 2.2, or a full HTTP server written in Euphoria?
I just mean a Euphoria CGI script running under Apache!
Let me add that I was using GET and parsing it just fine with the getenv("QUERY_STRING"). However, QUERY_STRING is empty and STDIN is -1 when trying to use POST.
Thanks!
I have a very old one, written for Euphoria 2.3, but it should still work with 4.0
#!/usr/bin/env exu puts(1,"Content-type: text/html\n\n") without warning include file.e include dll.e include get.e include machine.e include misc.e function get_env(sequence s) return getenv(s) end function global function getenv(sequence x) object s s = get_env(x) if atom(s) then s = "" end if return s end function constant upload_dir = "../upload/" object nbytes, variables, notused function lowerit(object x) -- convert atom or sequence to lower case return x + (x >= 'A' and x <= 'Z') * 32 end function function get_base_file_name(sequence sf) integer i sf = reverse(sf) i = find('/', sf) if i then sf = sf[1..i-1] end if i = find('\\', sf) if i then sf = sf[1..i-1] end if i = find(':', sf) if i then sf = sf[1..i-1] end if while find(' ', sf) do sf[find(' ', sf)] = '_' end while sf = reverse(sf) return sf end function constant alphanum = "abcdefghijklmnopqrstuvwxyz" & "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & "0123456789." & "\\/:" --a hack, not really alphanum, but it makes things easier -- not an issue as files can never have these anyways function cleaner(sequence s) integer k k = 1 while k <= length(s) do if not find(s[k], alphanum) then s = s[1..k-1] & "%" & sprintf("%x", s[k]) & s[k+1..length(s)] k += 2 --we can skip the next 2 chars, they are part of --the curent char end if k += 1 end while return s end function nbytes = get_env("CONTENT_LENGTH") nbytes = value(nbytes) if nbytes[1] = GET_SUCCESS then nbytes = nbytes[2] else puts(1,"<html><body>Internal Server Error1<p>" & "Please try again at a later time.</body></html>") abort(1) end if variables = get_bytes(0,nbytes) object text, line, char, last text = {} line = {} last = -1 for j = 1 to length(variables) do char = variables[j] line &= char if char = '\n' and last = '\r' then text &= {line} line = {} end if last = char end for if equal(text[length(text)],"") then text = text[1..length(text)-1] end if variables = text variables = variables[2..length(variables)-1] notused = match("filename=", variables[1]) nbytes = get_base_file_name(variables[1][notused+length("filename=")+1..length(variables[1])-3]) variables = variables[3..length(variables)] notused = getenv("REMOTE_ADDR") --remote ip nbytes = upload_dir¬used&"-"&nbytes --remote ip & filename notused = open(nbytes, "w") if notused = -1 then printf(1, "<html><body>Couldn't open file %s.</body></html>", {nbytes}) abort(1) end if variables = variables[2..length(variables)] -- bizarre but ok - have random leftover blank line variables[length(variables)] = variables[length(variables)][1..length(variables[length(variables)])-2] if equal(variables[length(variables)],"") then variables = variables[1..length(variables)-1] end if for j = 1 to length(variables) do puts(notused, variables[j]) end for close(notused) printf(1, "<html><body>Fine. File is located <a href=\"%s\">here</a>. Good day.</body></html>", {cleaner(nbytes)})
17. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 19, 2013
- 1617 views
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.
18. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 19, 2013
- 1614 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:
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 } } 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
19. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 19, 2013
- 1603 views
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.
20. Re: Sending a File Over HTTP
- Posted by jimcbrown (admin) Aug 19, 2013
- 1598 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")
21. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 20, 2013
- 1534 views
Thanks for working with me, jim. My comments follow:
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?
You only need two - "data" and "size".
All that "stuff" is data I need to send to the server side script so I can organize the file I'm sending.
For example, the cgi-script will take the company and create a directory for it on the server to store the data being sent.
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 returns "SUCCESS!" on a successful completion of the requested activity.
Anyways, you will need to set a size parameter.
Even sending the size parameter, my cgi-script reports "Nothing received."
Here's the cgi-script I'm using (a modified version of yours that I'm using just for testing at the moment) called "transfer.esp":
#!c:/euphoria4.0.5/bin/eui.exe puts(1,"Content-type: text/html\n\n") without warning include std/filesys.e include std/dll.e include std/get.e include std/machine.e include std/sequence.e include std/io.e constant upload_dir = "licenses/" object nbytes, variables, notused, qstr constant alphanum = "abcdefghijklmnopqrstuvwxyz" & "ABCDEFGHIJKLMNOPQRSTUVWXYZ" & "0123456789." & "\\/:" --a hack, not really alphanum, but it makes things easier -- not an issue as files can never have these anyways function cleaner(sequence s) integer k k = 1 while k <= length(s) do if not find(s[k], alphanum) then s = s[1..k-1] & "%" & sprintf("%x", s[k]) & s[k+1..length(s)] k += 2 --we can skip the next 2 chars, they are part of --the curent char end if k += 1 end while return s end function nbytes = getenv("CONTENT_LENGTH") qstr = getenv("QUERY_STRING") -- testing received values here... if atom(qstr) then puts(1,"No query string.") else if length(qstr) > 0 then puts(1,"Query string: '" & qstr & "'") else puts(1,"Query string is empty.") end if end if if atom(nbytes) then nbytes = "" end if nbytes = value(nbytes) if nbytes[1] = GET_SUCCESS then nbytes = nbytes[2] else puts(1,"\n<html><body>Internal Server Error1<p>" & "Please try again at a later time.</body></html>") abort(1) end if variables = get_bytes(0,nbytes) object text, line, char, last text = {} line = {} last = -1 for j = 1 to length(variables) do char = variables[j] line &= char if char = '\n' and last = '\r' then text &= {line} line = {} end if last = char end for if length(text) > 0 then if equal(text[$],"") then text = text[1..$-1] end if variables = text variables = variables[2..length(variables)-1] notused = match("filename=", variables[1]) nbytes = filename(variables[1][notused+length("filename=")+1..length(variables[1])-3]) variables = variables[3..$] notused = getenv("REMOTE_ADDR") --remote ip if atom(notused) then notused = "" end if nbytes = upload_dir¬used&"-"&nbytes --remote ip & filename notused = open(nbytes, "w") if notused = -1 then printf(1, "\nCouldn't open file %s.", {nbytes}) abort(1) end if variables = variables[2..$] -- bizarre but ok - have random leftover blank line variables[$] = variables[$][1..length(variables[$])-2] if equal(variables[$],"") then variables = variables[1..$-1] end if for j = 1 to length(variables) do puts(notused, variables[j]) end for close(notused) puts(1, "SUCCESS!") else puts(1,"\nNothing received.") end if
Here's the function to call transfer.esp from the client side:
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_NONE }, { "size", sprintf("%d",{length(filetxt)}) } } puts(1,"\nsending this data:\n") pretty_print(1,data,{3}) result = http_post( "http://localhost/transfer.esp", { MULTIPART_FORM_DATA, data } ) end if puts(1,"\nFrom server:\n") pretty_print(1,result,{3}) if not equal(result[2],"SUCCESS!") then ERR_MESSAGE = result[2] else ERR_MESSAGE = "" end if return equal(result[2],"SUCCESS!") end function
I'm always getting "Query string is empty. Nothing received."
22. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 20, 2013
- 1539 views
I'm making progress... Will report back shortly.
23. Re: Sending a File Over HTTP
- Posted by euphoric (admin) Aug 20, 2013
- 1567 views
I've met with great success!
Client-side code:
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 = { { "data", filetxt, fname, "text/plain", ENCODE_NONE }, { "size", sprintf("%d",{length(filetxt)}) } } result = http_post( "http://12.345.678.90/files/transfer.esp?transfer=true&name=" & fname & "&company=" & url:encode(COMPANY_NAME), { MULTIPART_FORM_DATA, data } ) else message_box( "Could not backup '" & licFile & "'\n\nPlease try again later or contact us for help.", "SAT Transfer Error", MB_OK+MB_ICONERROR) 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
Server-side (cgi) code:
#!c:/euphoria4.0.5/bin/eui.exe puts(1,"Content-type: text/html\n\n") without warning include std/filesys.e include std/dll.e include std/get.e include std/machine.e include std/sequence.e include std/io.e include settings.e include shared.e object nbytes, qstr sequence params = "", text, LICENSES = get_setting("LICENSES") nbytes = getenv("CONTENT_LENGTH") qstr = getenv("QUERY_STRING") if atom(qstr) then puts(1,"No query string.") abort(1) else if length(qstr) > 0 then params = get_params( qstr ) else puts(1,"Query string is empty.") abort(1) end if end if if atom(nbytes) then nbytes = "" end if nbytes = value(nbytes) if nbytes[1] = GET_SUCCESS then nbytes = nbytes[2] else puts(1,"Internal error. Please try again later.") abort(1) end if text = get_bytes(0,nbytes) if length(text) > 0 and sequence(params) then sequence cname, fname, buDir, buFile, bfile = "transfer" integer i params[1] = lower(params[1]) i = find("company",params[1]) cname = params[2][i] i = find("name",params[1]) fname = params[2][i] if atom( dir( LICENSES & "\\" & cname & "\\" & bfile ) ) then system( "mkdir \"" & LICENSES & "\\" & cname & "\\" & bfile & "\"", 2 ) end if buDir = LICENSES & "\\" & cname & "\\" & bfile & "\\" buFile = buDir & cname & "-" & fname atom fn = open( buFile, "w" ) if fn = -1 then puts(1,"Could not open remote transfer file!") else puts(fn,text) close(fn) puts(1,"SUCCESS!") end if else puts(1,"Bad params or nothing received.") end if
The only problem (and it's not a problem for me, but might be for someone later down the line), is that variable 'text' needs to be parsed of its contents. Here's an example of what is received:
--rOQZtBFmBcvbVJhYJ13g Content-Disposition: form-data; name="data"; filename="foad.lic" Content-Type: text/plain Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis condimentum lobortis tempus. Morbi eros augue, vestibulum nec ultrices at, aliquet et metus. Quisque et orci sit amet mauris volutpat sagittis. Sed pretium eget ante at consequat. Proin leo mi, accumsan quis vestibulum ac, sagittis varius urna. Morbi eget lorem vel purus ullamcorper laoreet non in lectus. Donec ultrices adipiscing sem nec elementum. Phasellus eu ullamcorper eros, ut tincidunt risus. In fringilla justo quis erat dignissim suscipit. Vivamus in ullamcorper posuere. --rOQZtBFmBcvbVJhYJ13g Content-Disposition: form-data; name="size" 545 --rOQZtBFmBcvbVJhYJ13g--
The content of the file is between the blank line after "Content-Type: text/plain" and second marker (--rOQZtBFmBcvbVJhYJ13g). Do we already have a function that will parse this content?