Thanks everyone. This was exactly what I needed to get my brain in gear. It's working now -- I really appreciate the help.
On Tue, Nov 8, 2016 at 8:48 PM, David Storrs <[email protected]> wrote: > > > On Tue, Nov 8, 2016 at 6:03 PM, George Neuner <[email protected]> > wrote: > >> Hi David, >> >> HTTP is printable characters only. In general you need to do something >> like base64 encode raw byte data to get it across in any kind JSON wrapping. >> >> >> I'm not messing with XML, but I use the following for binary imagery: >> >> (send/back >> (if success >> ; succeeded >> (response/full 200 #"OK" >> (current-seconds) >> #"application/octet-stream" >> '() >> `(,result)) >> ; failed >> (response/full 404 #"REQUESTED OBJECT NOT FOUND" >> (current-seconds) >> #"application/text" >> '() >> '()) >> )) >> >> where "result" is the image bytestring I'm sending. This appears to the >> browser as if it is downloading a file, and is compatible with HTML img >> tags, etc. >> >> >> Maybe you don't need the XML wrapping? Or do it in 2 steps - send meta >> data as XML, and the raw bytes separately? >> > > Thanks, George, that's helpful. How is your data being transported, > though? You're returning a response object instead of an xexpr, but I don't > see where it's being encoded. > > > > > >> >> George >> >> >> >> On 11/8/2016 5:26 PM, David Storrs wrote: >> >> I'm still working with the protocol-buffers code in (planet >> murphy/protobuf). I want the web server to return a deserialized protocol >> buffer struct, then have the client deserialize it. I cannot make this >> work, and the problem is clearly due to the data being mangled by >> retrieving it from the HTTP port. How can I send binary data in an HTTP >> response and retrieve it on the other end without it being modified on the >> way? >> >> This is how the original request is made: >> (define p >> (post-impure-port >> (string->url "http://localhost:25678/file-chunk-info") >> (serialize-pbuf proto-buff-struct))) >> >> Here's the function that generates the response: >> >> (define/contract (send-response-pbuf msg-func thk) >> (->* (procedure? (-> any)) () response?) >> (define msg-name (symbol->string (object-name msg-func))) >> (response/xexpr `(html (body (p ,(~a msg-name " processed")))) >> #:mime-type (string->bytes/utf-8 >> "application/octet-stream") >> #:headers (list >> (header #"Transfer-Encoding" >> #"identity") >> (header #"Content-Encoding" >> #"identity") >> (header #"X-protocol-buffer-response" >> (serialize-pbuf (thk)))))) >> Here's what I've tried, none of which worked >> >> *) Basics >> - Verifying that the data arrives on the server intact. It does. >> - Verifying that (deserialize (serialize x)) works. It does. >> - Verifying that putting the data into a manually-constructed (response) >> struct, then pulling it out and deserializing it works. It does. >> >> *) Headers on the response >> - Setting Content-Type to application/octet-stream >> - Setting Transfer-Encoding to identity >> - Setting Content-Encoding to identity >> >> *) Retrieving the data client side through the post-impure-port >> - Pull the data out with (hash-ref (heads-string->dict (port->string p)) >> 'X-my-custom-header) >> - Parse the data manually using regexp-match against (port->bytes p) >> - Retrieve the data with (port->bytes-lines p) and deserialize the >> individual >> >> The error it's failing with is "<x> does not match expected data type", >> which means "you've given me a blob of bytes that cannot be parsed into the >> structure that you want me to parse them into." >> >> It only fails on protocol-buffer types that have embedded protocol-buffer >> messages, for what that's worth. >> >> This would be trivial if I could get the original response object before >> it was turned into a port, but I don't see how to do that. >> >> I am absolutely at my wits end, and I know this has to be simple. What >> am I missing? >> >> Dave >> >> >> > -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.

