[racket] mime/multipart parsing

From: Jordan Schatz (jordan at noionlabs.com)
Date: Sat Jan 7 13:41:57 EST 2012

Thank you Matthew,

The message I was using did have CRLF line endings, but it had one too
many:

----------------------------------------------------------------------
#lang racket

(require net/mime)

(define message-string
  (let ([sep "\r\n"])
    (string-append 
     sep ;;This message starts with a \r\n <- EXTRA CRLF
     "--9nbsYRvJBLRyuL4VOuuejw9LcAy" sep
     "Content-Type: multipart/mixed; boundary=NdzDrpIQMsJKtfv9VrXmp4YwCPh" sep
     sep
     "--NdzDrpIQMsJKtfv9VrXmp4YwCPh" sep
     "X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fvp9087NYEpkzGNlaGCpPMGXBQA=" sep
     "Location: /buckets/invoices/keys/RAQpCw8SssXlXVhiGAGYXsVmwvk" sep
     "Content-Type: application/json" sep
     "Link: </buckets/invoices>; rel='up'" sep
     "Etag: 1qS8Wrr2vkTBxkITOjo33K" sep
     "Last-Modified: Wed, 04 Jan 2012 17:12:32 GMT" sep
     sep
     "{ 'date': '11/02/2011' }" sep
     "--NdzDrpIQMsJKtfv9VrXmp4YwCPh--" sep)))

(define ip
  (open-input-string
   message-string))

(let* ([analyzed (mime-analyze ip)] ;; port -> #<message>
       [our-entity (message-entity analyzed)] ;; grab #<entity> of this message
       [parts (entity-parts our-entity)] ;; #<entity> -> list of (inner) #<message>
       [inner-message (first parts)] ;; I only have one, grab it
       [inner-entity (message-entity inner-message)] ;; get its #<entity> part
       [body-proc (entity-body inner-entity)] ;; create a proc that returns the #<entity> body
       [tmp (open-output-string)]) 
  (write (message-fields inner-message)) ;;Should be a string of headers? Actual '()
  (body-proc tmp) ;; call proc to get message body, it needs an output port
  (write (get-output-string tmp))) ;; Should be json data? Actual ""
----------------------------------------------------------------------

It looks like the message I am working with doesn't conform to RFC. But
it also seems like a sane thing for the net/mime library to check for and
handle? If so I should be able to add it and send a pull request.

Shalom,
Jordan

On Sat, Jan 07, 2012 at 06:12:22AM +0100, Matthew Flatt wrote:
> I think the main problem is that the input string has LF newlines, and
> it needs to have CRLF newlines. You'll also want a terminating CRLF.
> 
> With those changes, then `(message-fields inner-message)' instead of
> `(entity-fields inner-entity)' will get you the headers that include
> "X-Riak-Vclock: ...". The result of `(entity-fields inner-entity)'
> would correspond to a further multipart document in the inner message.
> 
> At Fri, 6 Jan 2012 20:17:21 -0700, Jordan Schatz wrote:
> > I'm having difficulties parsing mime multipart messages (probably I
> > missed something in the docs again). I have this code:
> > 
> > ----------------------------------------------------------------------
> > #lang racket
> > 
> > (require net/mime)
> > 
> > (define ip
> >   (open-input-string
> >    "--9nbsYRvJBLRyuL4VOuuejw9LcAy
> > Content-Type: multipart/mixed; boundary=NdzDrpIQMsJKtfv9VrXmp4YwCPh
> > 
> > --NdzDrpIQMsJKtfv9VrXmp4YwCPh
> > X-Riak-Vclock: a85hYGBgzGDKBVIcypz/fvp9087NYEpkzGNlaGCpPMGXBQA=
> > Location: /buckets/invoices/keys/RAQpCw8SssXlXVhiGAGYXsVmwvk
> > Content-Type: application/json
> > Link: </buckets/invoices>; rel='up'
> > Etag: 1qS8Wrr2vkTBxkITOjo33K
> > Last-Modified: Wed, 04 Jan 2012 17:12:32 GMT
> > 
> > { 'date': '11/02/2011' }
> > --NdzDrpIQMsJKtfv9VrXmp4YwCPh--"))
> > 
> > (let* ([analyzed (mime-analyze ip)] ;; port -> #<message>
> >        [our-entity (message-entity analyzed)] ;; grab #<entity> of this message
> >        [parts (entity-parts our-entity)] ;; #<entity> -> list of (inner) 
> > #<message>
> >        [inner-message (first parts)] ;; I only have one, grab it
> >        [inner-entity (message-entity inner-message)] ;; get its #<entity> part
> >        [body-proc (entity-body inner-entity)] ;; create a proc that returns the 
> > #<entity> body
> >        [tmp (open-output-string)]) 
> >   (write (entity-fields inner-entity)) ;;Should be a list of string of headers? 
> > Actual '()
> >   (body-proc tmp) ;; call proc to get message body, it needs an output port
> >   (write (get-output-string tmp))) ;; Should be json data? Actual ""
> > ----------------------------------------------------------------------
> > 
> > I thought it would write the headers, and message body, but instead I get
> > an empty list, and an empty string. I've been at it for a few hours and I
> > don't see what is wrong....
> > 
> > Thanks : )
> > Jordan
> > ____________________
> >   Racket Users list:
> >   http://lists.racket-lang.org/users


Posted on the users mailing list.