Returning Html as Response from grpc-gatway - go

Is there is a way i can return the content-type= " application/html" from the server.
grpc-gateway returning the response in key-value pair and browsers are unable parse it.
Proto Defination:
rpc Create (RegId) returns (Resp);
message RegId {
string id = 1;
}
message Resp {
string response = 1;
}
Returning response as HTML but in key-value pair.
How can i just return the html
{"response":"\u003chtml\u003e\u003cb\u003e Hey Developer \u003c/b\u003e\u003c/html\u003e"}

Try to use runtime.HTTPBodyMarshaler (https://github.com/grpc-ecosystem/grpc-gateway/issues/1881#issuecomment-797384040) for your grpc server, for example define runtime.ServeMuxOption in this way
runtime.WithMarshalerOption(runtime.MIMEWildcard, &runtime.HTTPBodyMarshaler{&runtime.JSONPb{EmitDefaults: true}})

Related

Is there a way to map local in proxyman based off of parameters attached to the body of a url?

I have a url:
https://cn.company.com/appv2/search
and want to have a different map local depending on the request coming with a different parameter in the body (i.e. it is NOT attached to the url like https://cn.company.com/appv2/search?cursor=abc. Instead it is in the body of the request { cursor: abc }.
Any idea on if this can be done in proxyman?
I basically want to be able to stub pagination through the proxy without waiting on a server implementation. So I'd have no cursor on the first request, server would return a cursor and then use that on the next request and get a different response from server on the request so that I can test out the full pagination flow.
Yes, it can be solved with the Scripting from Proxyman app.
Use Scripting to get the value of the request body
If it's matched, use Scripting to mimic the Map Local (Mock API also supports)
Here is the sample code and how to do it:
Firstly, call your request and make sure you can see the HTTPS Response
Right-Click on the request -> Tools -> Scripting
Select the Mock API checkbox if you'd like a Mock API
Use this code
/// This func is called if the Response Checkbox is Enabled. You can modify the Response Data here before it goes to the client
/// e.g. Add/Update/Remove: headers, statusCode, comment, color and body (json, plain-text, base64 encoded string)
///
async function onResponse(context, url, request, response) {
// get the value from the body request
var cursorValue = request.body["cursor"];
// Use if to provide a map local file
if (cursorValue === "abc") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_A.json";
} else if (cursorValue === "def") {
// Set Content Type as a JSON
response.headers["Content-Type"] = "application/json";
// Set a Map Local File
response.bodyFilePath = "~/Desktop/my_response_B.json";
}
// Done
return response;
}
Reference
Map Local with Scripting: https://docs.proxyman.io/scripting/snippet-code#map-a-local-file-to-responses-body-like-map-local-tool-proxyman-2.25.0+

How to send the data from a server to a client in the embedded messages in C++ using grpc?

I am implementing a simple client-server grpc-c++ based application. In the Hello rpc, I am taking the request and sending the fields of another message called SeverInfo as response. The problem is I exactly don't know how to send this ServerInfo data to a client from server side. We basically use set_fieldname(ex: set_name) for general datatypes to send the data but how should we send this serverInfo data to HelloResponse and then to HelloRequest. Can somebody please help me??
Below I am attaching the proto file.
syntax = "proto3";
package sample;
service Sample {
rpc Hello(HelloRequest) returns (HelloReply){}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
ServerInfo sinfo = 1;
}
message ServerInfo {
string name = 1;
string os = 2;
}
you can define another rpc in your service definitions like
service Sample {
rpc Hello(HelloRequest) returns (HelloReply){}
rpc GetServerInfo(HelloRequest) returns (ServerInfo){}
}
would that work for you?
Here is the answer that worked for me. Thank you.
ServerInfo* serverinfo=new ServerInfo();
serverinfo->set_name("");
serverinfo->set_os("");
HelloReply* rep;
rep->set_allocated_server(serverinfo);

Custom Bot always replies with an error

I am trying to send a webhook out from Teams, which is apparently accomplished with a Custom Bot. I am able to get the bot created and then I can do #botname stuff and the endpoint receives a payload.
However, the bot immediately replies with "Sorry, there was a problem encountered with your request". I get this error if I point the "Callback URL" to a requestb.in url or if I point it to my endpoint. This leads me to suspect the bot is expecting some specific response from the endpoint, but this isn't documented. My endpoint responds with a 202 and some json. Requestb.in responds with a 200 and "ok".
So, is it true that the bot requires a specific response payload and if so what is this payload?
That link above mentions Your custom bot will need to reply asynchronously to the HTTP request from Microsoft Teams. It will have 5 seconds to reply to the message before the connection is terminated. But there is no indication of how to satisfy this request, unless the custom bot will need to reply synchronously.
You need to return a JSON response with the keys 'text' and 'type' as shown in the example here
{
"type": "message",
"text": "This is a reply!"
}
In case you are using NodeJS, you can try this sample code
I created an azure function in C# as the callback for the custom bot and was initially sending back a json string but that didnt work. Finally I had to set the response object's Content and ContentType to get it working (as shown here). Here is the code for a simple bot that echoes back what the user types in the channel, feel free to adapt it to your scenario.
Custom MS Teams bot example code using azure functions
#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http.Headers;
using Newtonsoft.Json;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
// parse query parameter
string name = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
.Value;
// Get request body
dynamic data = await req.Content.ReadAsAsync<object>();
log.Info(JsonConvert.SerializeObject(data));
// Set name to query string or body data
name = name ?? data?.text;
Response res = new Response();
res.type = "Message";
res.text = $"You said:{name}";
var response = req.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent(JsonConvert.SerializeObject(res));
response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
return response;
}
public class Response {
public string type;
public string text;
}

Globally formatting .net Web Api response

I have a Web Api service that retrieves data from another service, which returns Json. I don't want to do anything to the response, I just want to return it directly to the client.
Since the response is a string, if I simply return the response, it contains escape characters and messy formatting. If I convert the response in to an object, the WebApi will use Json.Net to automatically format the response correctly.
public IHttpActionResult GetServices()
{
var data = _dataService.Get(); //retrieves data from a service
var result = JsonConvert.DeserializeObject(data); //convert to object
return Ok(result);
}
What I would like is to either A: Be able to return the exact string response from the service, without any of the escape characters and with the proper formatting, or B: Set a global settings that will automatically Deserialize the response so that the Web Api can handle it the way I am doing it already.
On Startup I am setting some values that describe how formatting should be handled, but apparently these aren't correct for what im trying to do.
HttpConfiguration configuration = new HttpConfiguration();
var settings = configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new DefaultContractResolver();
Do I need to create a custom ContractResolver or something? Is there one that already handles this for me?
Thanks
If you want to just pass through the json (Option A), you can do this
public IHttpActionResult GetServices() {
var json = _dataService.Get(); //retrieves data from a service
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}

How to load image list from REST API using angularJS

I have searched in this forum for quiet a bit and here's my problem -
I have a ng-repeat in my html which takes in a list of messages(Json object).
Each message JSON has a sender email address - e.g. abc#gmail.com
Now, I have to get the email address from the message and form another REST API request to fetch their images for e.g. - http://<>:8080/getImage/abc#gmail.com (email address dynamic)
So in my code, I'll have a ng-repeat and a ng-src pointing to the image REST URL
If there's no image in server, it returns a 404 and displays a broken image on the UI. How do I handle it? On the other hand, if I make a http request to determine if there's a success message and on failure return a default image, then the whole thing goes through an endless loop. I'll try to create a fiddle and include it for better explanation.
Use the error block to handle such behavior:
function($http) {
var restUrl = 'getImage/abc';
return {
fetchImage: function(imageId) {
var self = this;
return $http.get(restUrl + '/' + imageId).
success(function(data) {
return self.imageUrl = data;
}).
error(function(data) {
return self.imageUrl = "pathToDefaultImage";
});
},
...

Resources