FWIW, here's some _very_ quick and dirty Javascript that reads and writes an
(earlier, cruftier version of) mime/multipart we used for texting a while
back. It not what you'd want to use in production but it's a useful sanity
check on implementability complexity I think.
<script type="text/javascript">
function println(txt) {
document.write(txt + '<br>');
}
function parseResponse(req) {
if (!req) {
println("no request");
return null;
}
var response = req.responseText;
var header = req.getResponseHeader('Content-Type');
var date = new Date();
var startTime = date.getMilliseconds();
var responses = [];
if (!response) {
println('no response');
return null;
}
if (!header) {
println('no header');
return null;
}
var boundaryidx = header.indexOf('boundary=');
if (boundaryidx == -1) {
println('header: [' +header + ']');
println('no boundary found');
return null;
}
boundary = header.substring(boundaryidx + 9);
var parts = response.split('--' + boundary);
var l = parts.length;
for (var i = 0; i < l; i++) {
var p = parts[i];
if (p == '--\r\n') continue;
if (p == '') continue;
var bodystartidx = p.indexOf('\r\n\r\n');
var rawheaders = p.substring(2,bodystartidx);
var rawbody = p.substring(bodystartidx+4,p.length);
var statuscode = null;
var statustext = null;
var headers = rawheaders.split('\r\n');
var status = headers[0];
var statuscodeindex = status.indexOf(':');
statuscode = status.substring(statuscodeindex+2);
var statustextindex = statuscode.indexOf(' ');
statustext = statuscode.substring(statustextindex+1);
statuscode = statuscode.substring(0, statustextindex);
var lh = headers.length;
var headerobjects = [];
for (var j = 0; j < lh; j++) {
var text = headers[j];
var delimidx = text.indexOf(':');
headerobjects.push({'name' : text.substring(0, delimidx),
'value' : text.substring(delimidx + 2)});
}
responses.push({'headers' : headerobjects, 'body' : rawbody,
'statuscode' : statuscode, 'statustext' : statustext});
}
date = new Date();
var endTime = date.getMilliseconds();
println('PARSE TIME (in milliseconds): ' + (endTime - startTime));
return responses;
}
function printResponses(responses) {
println('Dump Response Array');
if (!responses) {
println("no responses");
return;
}
var l = responses.length;
for (var i = 0; i < l; i++) {
var r = responses[i];
for (var j = 0; j < r.headers.length; j++) {
var ho = r.headers[j];
println('header[' + ho.name + '] = [' + ho.value + ']');
}
println('statuscode: [' + r.statuscode + ']');
println('statustext: [' + r.statustext + ']');
println('body: [' + r.body + ']');
println('------------------------------------');
}
}
function EXPECT_EQ(value, result, idx) {
if (idx >= result.length) {
return 'FAIL EXPECT_EQ. Index[' + idx + '] exceeds length[' +
result.length + ']';
}
if (value == result[idx]) {
return 'PASS EXPECT_EQ. Idx[' + idx + '] Expected[' + value + ']
Actual[' + result[idx] + ']';
}
return 'FAIL EXPECT_EQ. Idx[' + idx + '] Expected[' + value + ']
Actual[' + result[idx] + ']';
}
function saveXMLDoc(url, text, boundaryString) {
var req = null;
if(window.ActiveXObject) {
try {
req = new ActiveXObject('Msxml2.XMLHTTP');
} catch(e) {
try {
req = new ActiveXObject('Microsoft.XMLHTTP');
} catch(e) {
req = null;
}
}
} else if(window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
} catch(e) {
req = null;
}
}
if(req) {
req.open('POST', url, false);
req.setRequestHeader('Content-Type', 'multipart/mixed; boundary='
+ boundaryString);
req.send(text);
if (req.readyState == 4 && req.status == 200) {
return req;
}
return null;
}
function sendRequest() {
var boundaryString = 'batch-a73hdj3dy3mm347ddjjdf';
var boundary = '--' + boundaryString;
var text = '';
text += boundary + '\r\n';
text += 'X-Batch-Operation: POST /people/friends HTTP/1.1' +
'\r\n';
text += 'Host: container.org' + '\r\n';
text += '\r\n';
text += '...representation of new Person elided...' + '\r\n';
text += '\r\n';
text += boundary + '\r\n';
text += 'X-Batch-Operation: GET /people/friends/page=5&num=10'
+ '\r\n';
text += 'Host: container.org' + '\r\n';
text += '-batch-a73hdj3dy3mm347ddjjdf' + '\r\n';
text += 'If-None-Match: "837dyfkdi39df"' + '\r\n';
text += '\r\n';
text += boundary + '--\r\n';
return
saveXMLDoc('http://example.org/batch-proxy<http://warpgundy.corp.google.com:8000/rnr>',
text, boundaryString);
}
var req = sendRequest();
var resp = parseResponse(req);
printResponses(resp);
</script>
John Panzer (http://abstractioneer.org)
On Tue, Jun 24, 2008 at 6:13 PM, John Panzer <[EMAIL PROTECTED]> wrote:
> Yeah, this was talked about on Friday but I guess Cassie didn't have time
> to mail the list before going on vacation.
>
> It's possible to implement the spec (mime/multipart) in Javascript, in fact
> we did it a few months back as a sanity check, I'll need to dig up the code
> to send around.
>
> The discussion so far has been that it's faster to just implement the
> JSON-only batch format for now. The spec doesn't disallow this as the
> /batch-proxy URL can accept any MIME type you care to throw at it (and
> define), if we decide to standardize the JSON one we should probably write
> up some spec text though :). application/json batch can co-exist with
> mime/multipart easily enough if necessary.
>
> John Panzer (http://abstractioneer.org)
>
> On Tue, Jun 24, 2008 at 6:04 PM, Kevin Brown <[EMAIL PROTECTED]> wrote:
>
>> On Tue, Jun 24, 2008 at 5:54 PM, Chris Chabot <[EMAIL PROTECTED]> wrote:
>>
>> > Did you forget the apache meme? If it's not in my mailbox, it doesn't
>> exist
>> > ! :-)
>>
>>
>> Yeah, there's not really anything to send around though -- we talked about
>> it, but nobody really had a good idea about what to do. I assume that
>> Cassie
>> was taking care of it since she's been working in that area.
>>
>> Might be nice to keep us who are not privy to the google meetings involved
>> > in it? (both spec and shindig wise), else we'll end up having people
>> > spinning their wheels for nothing, and no one likes to loose time, even
>> just
>> > some heads up would be useful for the people involved. (we went by
>> cassie's
>> > words "as soon as the php guys implement batching you can flip the
>> switch",
>> > so i had no insight in nor hints to these discussions)
>>
>>
>> Well, there weren't actually any proposals for what to do, so there wasn't
>> anything to share. If someone has a good idea of how to do it and wants to
>> write it, by all means go for it. If you can make it work for PHP I'm sure
>> it can be adapted for Java (there's certainly no reason why the PHP code
>> has
>> to follow the lead of what's done in the Java base, after all).
>>
>>
>> > What's the problem, impossible to make such a request from javascript
>> > (something i could imagine)? In that case i guess at least we can keep
>> the
>> > work we did so far on the php side.
>>
>>
>> I don't know; David and Cassie had different opinions on the matter, so
>> they
>> talked to try to sort it out. I don't think they came to any conclusion on
>> the matter, so hopefully someone with better ideas will :).
>>
>>
>> >
>> > -- Chris
>> >
>> >
>> > On Jun 25, 2008, at 2:47 AM, Kevin Brown wrote:
>> >
>> > Several of us have been discussing this problem over at Google, but I
>> >> don't
>> >> know that there was a clear conclusion
>> >>
>> >
>> >
>>
>
>