Closed raadiy closed 2 years ago
Hi, due to restricted architecture it coulnd't implemented easily ATM. But you can hack it by using a custom filter and MessageContext.
First you should bypass body parsing by the engine. You should save it somewhere and nullify it.
Create a filter which creates a new Header and place content of body to it. Set request body to nullptr:
response->headers = pool->alloc<Header>("X-RealBody", request->body, response->headers);
request->body = nullptr;
https://github.com/loentar/ngrest/blob/master/tests/filters/src/TestFilterGroup.cpp#L111
Next create a service which takes only one parameter MessageContext and take the actual body from the header created in filter.
https://github.com/loentar/ngrest/blob/master/services/favicon/src/Favicon.cpp#L30
references:
https://github.com/loentar/ngrest/blob/master/core/common/src/Message.h#L59
Thank you. Will try this. Regards Raajesh
Hi Dmitry,
Thank you for the help. I created a test filter and test filter group as plugin and am able to see the data inside the preDispatch filter. However, inside the service, I am not able to access the data. I think I am doing something incorrect most likely inside the service. Could you please advise.
==== Following is the code snippet inside the preDispatch filter ====
if (context->request->body) {
printf("\n called predispatch <%s>\n", context->request->body);
context->response->headers = context->pool->alloc<Header>("X-RealBody",
context->request->body,
context->response->headers);
context->request->body = nullptr;
}
====
=== Following is the code snippet inside the HTTP PATCH helloworld service ===
std::string HelloWorld::patchHandler(ngrest::MessageContext &context)
{
char resp[1024];
ngrest::HttpResponse response = static_cast<ngrest::HttpResponse>(context.response);
ngrest::Header* headerContentType = context.pool->alloc
context.response->poolBody->putData(resp, 10);
printf("\npatch data <%s> <%s>\n", resp, context.request->body);
====
Regards Raajesh
your service operation should contain something like this:
ngrest::Header *headerBody = context.request->getHeader("X-RealBody");
if (headerBody != nullptr) {
const char* body = headerBody->value;
uint64_t bodySize = context.request->bodySize;
// use body and bodySize here
}
Thank you, will try this
Somehow with the code that you listed inside the service, the headerBody is always NULL, even though I am able to see it via the print in the filter.
because you should manipulate request headers within filter, not response. I did a typo :)
context->request->headers = context->pool->alloc<Header>("X-RealBody",
context->request->body,
context->request->headers);
I think the test filter has to be like this: if (context->request->body) {
context->request->headers = context->pool->alloc<Header>("X-RealBody",
190 context->request->body,
191 context->request->headers);
192 context->request->body = nullptr;
193 }
yes... i got it... thank you...
I have to do something like this for the response too, so that the service does not automatically send a json like this... "{ "result":...}".. I think I will have to do similar thing for response for the "PostDispatch" Filter.... correct?
Also - thank you once again for the help and immediate response. Best Regards Raajesh
I think it's enough to just write to response's poolBody, like Favicon service do:
https://github.com/loentar/ngrest/blob/master/services/favicon/src/Favicon.cpp#L40
okay, thank you
yes, it works.. thank you for resolving these issues
Hi,
Thank you for supporting the HTTP PATCH. It is very helpful. I have another request. Would it be possible for the NGREST HTTP methods to pass on the raw json it received, and let the application parse it. I find that you currently provide the parsed output. That is splendid. My request is in addition to what you provide, a seperate set of handlers, through which the application can access the raw Json. I have existing code that I would like to invoke from the ngrest handler. That way ngrest handler would just get a std::string with the json payload, and from the handler I would call the appropriate (pre-existing) function to parse and use it.
Regards Raajesh