0

I'm trying to send a protobuf over http post to java spring server from node js client.

message.serializeBinary() gives me a uint8 bytes array which I tried to encode with new StringDecoder('utf8').write(<bytes>). And I send it over post with npm request-promise:

 const request = require('request-promise')
 const options = {
  uri: <some url>,
  method: 'POST',
  qs: {
    'attr1': 'value1',
    'attr2': new StringDecoder('utf8').write(message.serializeBinary())
  }
}
request(options).then(console.log).catch(console.log)

This hits spring server endpoint

@ResponseBody String endpoint(@RequestParam String attr1, @RequestParam String attr2) {
  // This is raising InvalidProtocolBufferException
  var message = Message.parseFrom(attr2.getBytes(StandardCharsets.UTF_8));  
}

Looks like encoding issue to me, I'm not sure what encoding to use to transport a protocol buffer over http. Or If i'm doing something else wrong, please point it out too.

Chakradar Raju
  • 2,691
  • 2
  • 26
  • 42
  • Hi sir, I also encountered this error the same as yours. How did you solve it? – Arman Ortega Sep 01 '19 at 09:56
  • 1
    Problem was sending it in query string, which is truncated based on url length restrictions, I started passing it as form data and that fixed it. – Chakradar Raju Sep 03 '19 at 07:21
  • If you made sure to keep your records on the smaller side, Base64 encoding the protobuf should work as well – nico Apr 13 '21 at 10:22

1 Answers1

1

tl;dr Solution is to change qs to form

const options = {
  uri: <some url>,
  method: 'POST',
  form: {
    'attr1': 'value1',
    'attr2': new StringDecoder('utf8').write(message.serializeBinary())
  }
}

Problem was passing encoded protobuf as query string parameter, which is part of url. Url has variable length restriction based on browser, better to pass it as form data. See What is the maximum length of a URL in different browsers?

Chakradar Raju
  • 2,691
  • 2
  • 26
  • 42