module Netmime:sig
..end
Contents
The tutorial has been moved to
Netmime_tut
. Parsers for MIME
headers are now in Netmime_header
. Parser and printers for MIME
channels are now in Netmime_channels
.typestore =
[ `File of string | `Memory ]
`Memory
means in-memory, `File name
means in the file name
. The body
is stored in decoded form (i.e. without transfer encoding).exception Immutable of string
mime_header_ro
, and mime_body_ro
),
and after that the full class type including write access is defined
(mime_header
, and mime_body
).
The idea is that you can write functions that take an ro value as input to indicate that they do not modify the value. For example:
let number_of_fields (h:#mime_header_ro) =
List.length (h#fields)
This function accepts both mime_header
, and mime_header_ro
values as
input, but the typing ensures that the function cannot mutate anything.
There is another way to ensure that a header or body is not modified.
The read-only flag can be set when creating the object, and this flag
causes that all trials to modify the value will raise the exception
Immutable
. Of course, such trials of mutation are only detected at
run-time.
The advantage of the read-only flag is that it even works if
mutation depends on a condition, but it can be ensured that this
condition is never true. Furthermore, typing is much simpler (getting
subtyping correct can be annoying).
class type mime_header_ro =object
..end
class type mime_header =object
..end
class type mime_body_ro =object
..end
class type mime_body =object
..end
(mime_header, mime_body)
as simple MIME
message with one header and one body. Of course, this simple representation
does not support multi-part messages (attachments). For that reason,
the complex_mime_message
was invented: The body can be further
structured as a sequence of parts that are complex messages themselves.
For example, a mail message with an attachment is usually represented as
(mail_header, `Parts [ (main_header, `Body main_body);
(att_header, `Body att_body) ] )
Here, mail_header
is the real header of the mail message.
main_header
is the header of the main message, usually
only containing the content type of main_body
, the body
of the main message. The attachment has also its own
att_header
, again usually only containing the content type,
and the data of the attachment can be found in att_body
.
Nowadays, mails have often even a more complicated structure
with `Parts
containing nested `Parts
. As complex_mime_message
is recursive, any kind of nesting can be easily represented.
typecomplex_mime_message =
mime_header * complex_mime_body
typecomplex_mime_body =
[ `Body of mime_body | `Parts of complex_mime_message list ]
typecomplex_mime_message_ro =
mime_header_ro * complex_mime_body_ro
typecomplex_mime_body_ro =
[ `Body of mime_body_ro
| `Parts of complex_mime_message_ro list ]
`Parts []
, i.e. `Parts
together with an empty list, is
considered as illegal. Such a value cannot be transformed into
printable text.typemime_message =
mime_header * [ `Body of mime_body ]
typemime_message_ro =
mime_header_ro * [ `Body of mime_body_ro ]
class basic_mime_header :(string * string) list ->
mime_header
mime_header
.
val basic_mime_header : (string * string) list -> mime_header
class wrap_mime_header :#mime_header ->
mime_header
class wrap_mime_header_ro :#mime_header_ro ->
mime_header
val wrap_mime_header_ro : #mime_header_ro -> mime_header
class memory_mime_body :string ->
mime_body
mime_body
where the value is stored
in-memory.
val memory_mime_body : string -> mime_body
class file_mime_body :?fin:bool -> string ->
mime_body
mime_body
where the value is stored
in an external file.
val file_mime_body : ?fin:bool -> string -> mime_body
class wrap_mime_body :#mime_body ->
mime_body
class wrap_mime_body_ro :#mime_body_ro ->
mime_body
val wrap_mime_body_ro : #mime_body_ro -> mime_body
val wrap_complex_mime_message_ro : complex_mime_message_ro -> complex_mime_message