title: How do I map my working curl command into a grpc-web call
body: <p>I am trying to get a working instance of <a href="https://github.com/grpc/grpc-web" rel="nofollow noreferrer">grpc-web</a>. I've got a backend service that looks like this.</p>
  
  <pre><code>var grpc      = require('grpc');
  var messages  = require('./example_pb');
  var service   = require('./example_grpc_pb');
  
  
  function exampleOne(call) {
      var response = new messages.ExampleOneRequest();
      call.write(response);
      call.end();
  }
  
  function main() {
     var server = new grpc.Server();
     server.addService(
         services.MyExampleService,
         {
             example : exampleOne
         }
      );
      server.bind('0.0.0.0:8050', grpc.ServerCredentials.createInsecure());
      server.start();
  }
  main();
  </code></pre>
  
  <p>I've tested this with a server side 'client', so now I am attempting to hook up the actual web browser based client. First I set up the proxy, which apparently is necesary? I decided to go with the GoLang based <a href="https://github.com/improbable-eng/grpc-web/tree/master/go/grpcwebproxy" rel="nofollow noreferrer">grpcwebproxy</a>, which seems like an acceptable choice according to the grpc-web documentation.</p>
  
  <pre><code>&gt;&gt; grpcwebproxy --backend_addr=localhost:8050 \                                                                                                                                                                       
  --server_tls_cert_file=/usr2/certs/server/localhost.localdomain.crt \                                                                                                                                          
  --server_tls_key_file=/usr2/certs/server/localhost.localdomain.key  
  </code></pre>
  
  <p>Output looks like this</p>
  
  <pre><code>INFO[0000] dialing to target with scheme: ""             system=system
  INFO[0000] ccResolverWrapper: sending new addresses to cc: [{localhost:8050 0  &lt;nil&gt;}]  system=system
  INFO[0000] listening for http on: [::]:8080             
  INFO[0000] listening for http_tls on: [::]:8443         
  INFO[0000] pickfirstBalancer: HandleSubConnStateChange: 0xc4201638a0, CONNECTING  system=system
  INFO[0000] pickfirstBalancer: HandleSubConnStateChange: 0xc4201638a0, READY  system=system
  </code></pre>
  
  <p>I am unable to get the web-browser implentation working, just getting some generic/CORS related 500 errors.</p>
  
  <p>I went back to my server side and decided to curl the proxy. It seems that http2 is not supported with my current version of curl, so I instead use <a href="https://github.com/fstab/h2c" rel="nofollow noreferrer">a tool called h2c</a>. </p>
  
  <p>Long story short, I try pinging the tls port 8443 and get the following (most promising).</p>
  
  <pre><code>&gt;&gt; ./h2c_linux_amd64 get https://localhost:8443/service.path/ExampleOne
  
  invalid gRPC request method
  </code></pre>
  
  <p>I try this</p>
  
  <pre><code>&gt;&gt; ./h2c_linux_amd64 get http://localhost:8443/service.path/ExampleOne
  
  http connections not supported.
  </code></pre>
  
  <p>I try this</p>
  
  <pre><code>&gt;&gt; ./h2c_linux_amd64 get http://localhost:8080/service.path/ExampleOne
  
  http connections not supported.
  </code></pre>
  
  <p>I try this</p>
  
  <pre><code>&gt;&gt; ./h2c_linux_amd64 get https://localhost:8080/service.path/ExampleOne
  
  Failed to connect to localhost:8080: tls: oversized record received with length 20527
  </code></pre>
  
  <p>I don't expect an instant "this is your solution" type answer, since there's a lot I left out, but does anyone have any suggestions on where to run with this?</p>
  
  <p>The error I got</p>
  
  <pre><code>"invalid gRPC request method"
  </code></pre>
  
  <p>seems the most promising, if generic. </p>
  
  <p>EDIT :</p>
  
  <p>Seem to have gotten a bit closer, at least debugging the server side. Went back to using curl. This was my command</p>
  
  <pre><code>curl 'https://localhost:8443/service.path/ExampleOne' \
  -H 'content-type: application/grpc-web+proto' \
  -H 'x-grpc-web: 1' \
  -H 'authority: localhost:8443' \
  --data-binary $'\x00\x00\x00\x00\x04\n\x02yo' \
  --insecure
  </code></pre>
  
  <p>With this command, I was able to make it through the grpcwebproxy, to my service, and back to the other side. Something about supplying curl with a binary string seems to do the trick. I say this because</p>
  
  <pre><code>curl 'https://localhost:8443/service.path/ExampleOne' \
  -H 'content-type: application/grpc-web+proto' \
  -H 'x-grpc-web: 1' \
  -H 'authority: localhost:8443' \
  --insecure
  </code></pre>
  
  <p>results in an error message of</p>
  
  <pre><code>gRPC requires HTTP/2
  </code></pre>
  
  <p>Now I need to map the above curl command into a valid grpc-web request. </p>
  
  <p>EDIT 2 :</p>
  
  <p>I am now at the point where I think I require a cert. The code from the browser is hitting my grpcwebproxy, but I am seeing the error message</p>
  
  <pre><code>2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45056: remote error: tls: unknown certificate authority
  2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45058: remote error: tls: unknown certificate authority
  2018/10/17 12:21:56 http2: server: error reading preface from client 127.0.0.1:45060: remote error: tls: unknown certificate authority
  </code></pre>
  
  <p>This occurs in the output of grpcwebproxy, so I know the request is at least making it there.</p>
  
  <p>I'm thinking I got around this previously with curl by including the --insecure tag... not sure how to replicate this in the browser.</p>