magic.lambda.mime
magic.lambda.mime gives you the ability to parse and create MIME messages from Hyperlambda. This project contains the following slots.
- [mime.parse] - Parses a MIME message, and returns it as a lambda object
- [mime.create] - Creates a MIME message for you, and returns the entire message as text, being the MIME entity
- [.mime.parse] - Parses a native MimeEntity for you, and returns it as a lambda object (not for usage directly from Hyperlambda code)
- [.mime.create] - Creates a MIME message for you, and returns it as a native MimeEntity object (not for usage directly from Hyperlambda code)
How to use [mime.parse]
Below is an example of how parsing a MIME message might look like using [mime.parse].
// Actual message
.msg:"Content-Type: multipart/mixed; boundary=\"=-3O9TzEjuVDwt7d5uGDkV/Q==\"\n\n--=-3O9TzEjuVDwt7d5uGDkV/Q==\nContent-Type: text/plain\nContent-Disposition: attachment; filename=README.md\n\n# Your dynamic files folder\n\nSome README.md file\n\n--=-3O9TzEjuVDwt7d5uGDkV/Q==\nContent-Type: text/plain\n\nBar\n--=-3O9TzEjuVDwt7d5uGDkV/Q==--\n"
// Parsing the above message
mime.parse:x:@.msg
After evaluating the above, you’ll end up with something resembling the following.
mime.parse:multipart/mixed
entity:text/plain
headers
Content-Disposition:attachment; filename=README.md
content:"# Your dynamic files folder\n\nSome README.md file\n"
entity:text/plain
content:Bar
Notice how the slot creates a tree structure, perfectly resembling your original MIME message. It will also take care of MIME headers for you, adding these into a [headers] collection, on a per MIME entity basis, depending upon whether or not your message actually contains headers or not.
How to use [mime.create]
The [mime.create] slot is logically the exact opposite of the [mime.parse] slot, and can take (almost) the exact same input as its sibling produces as output. Below is an example.
mime.create:multipart/mixed
structured:false
entity:text/plain
content:this is the body text
entity:text/plain
content:this is another body text
Which of course wil result in something resembling the following after evaluation.
mime.create:"Content-Type: multipart/mixed; boundary=\"=-7+NI+p6PuOyQUzW5ihnXvw==\"\n\n--=-7+NI+p6PuOyQUzW5ihnXvw==\nContent-Type: text/plain\n\nthis is the body text\n--=-7+NI+p6PuOyQUzW5ihnXvw==\nContent-Type: text/plain\n\nthis is another body text\n--=-7+NI+p6PuOyQUzW5ihnXvw==--\n"
Notice - If you set its [structured] argument to boolean true
, the slot will return the MIME envelope headers
for the outermost MIME entity “detached” from the rest of the message. This is useful when you for some reasons don’t want
the headers for the outermost entity to be a part of the actual message, such as for instance when creating multipart/form-data
types of messages you need to transmit to some HTTP endpoint. If you do this, the return after executing the slot will
resemble the following.
mime.create
Content-Type:"multipart/mixed; boundary=\"=-EbMBZ3eHrSrMqtB2KHSv+A==\""
content:"--=-EbMBZ3eHrSrMqtB2KHSv+A==\nContent-Type: text/plain\n\nthis is the body text\n--=-EbMBZ3eHrSrMqtB2KHSv+A==\nContent-Type: text/plain\n\nthis is another body text\n--=-EbMBZ3eHrSrMqtB2KHSv+A==--\n"
This is useful if you for some reasons don’t want the Content-Type
to be a part of the MIME message itself, which is useful when creating HTTP envelopes and content for instance, where the Content-Type parts needs to be submitted separately as an HTTP header.
MIME headers
To supply MIME headers for individual MIME entites, you can add a [headers] section as a child to your [entity] node. Below is an example of how to construct a MIME text entity with an attachement, wrapped inside a multipart/mixed parent.
mime.create:multipart/mixed
entity:text/plain
content:Some text content
entity:text/markdown
headers
Content-Disposition:attachment; filename=README.md
content:Some Markdown content here
The above will create one multipart MIME entity with two children, where one of its children are declaring itself as an attachment, with the filename of “README.md” due to its Content-Disposition
header. If you parse the resulting MIME message using [mime.parse], you will end up with roughly what you started with.
You can add any headers you wish into individual MIME entities using the above syntax. The Content-Type
header will be ignored though, since it’s assumed to be the value of your [entity] node.
File attachments
If you want to attach physical files, it’s probably smart to attach these using [filename] as an alternative to loading the entire file into memory first. This will transmit the file directly from your file system to the socket, and never load the file into memory. This obviously preserves a lot of memoery for you, especially for large file.
If we’re to change the above code to illustrate how this ends up looking like, it would become something resembling the following.
mime.create:multipart/mixed
entity:text/plain
content:Some text content
entity:text/markdown
filename:/etc/README.md
Notice, if you supply a [filename] argument, then the library will automatically associate the correct Content-Disposition
header with your MIME entity, unless explicitly overridden by your code.