Chain REST requests using restbed C++ - c++

I am trying to chain some REST requests using restbed lib and I have an issue.
So the work flow is something like this: the frontend sends a GET request to the backend. The backend does some processing and should return a reponse to the frontend but in the same time it should also POST the resposnse to another REST server.
void CCMService::get_method_handler(const shared_ptr< Session > session)
{
const auto request = session->get_request();
int content_length = request->get_header("Content-Length", 0);
session->fetch(content_length, [](const shared_ptr< Session > session, const Bytes & body)
{
std::vector<std::string> resultImages;
fprintf(stdout, "%.*s\n", (int)body.size(), body.data());
const auto request = session->get_request();
const string parameter = request->get_path_parameter("camGroupId");
try
{
resultImages = prepareImages(parameter.c_str());
}
catch (const std::exception& e)
{
std::string error = e.what();
std::string message = "{error: \"" + error + "\"}";
throw std::exception(message.c_str());
}
fprintf(stderr, "Return response\n");
session->close(OK, resultImages[0], { { "Content-Length", std::to_string(resultImages[0].length())} });
fprintf(stderr, "Send tiles to inference\n");
//send POST request
sendResult(resultImages[1]);
});
}
void CCMService::sendResult(char* result)
{
auto request = make_shared< Request >(Uri("http://127.0.0.1:8080/api"));
request->set_header("Accept", "*/*");
request->set_header("Content-Type", "application/json");
request->set_method("POST");
request->set_header("Host", "http://127.0.0.1:8080");
//request->set_header("Cache-Control", "no-cache");
...
//create json from result - jsonContent
...
request->set_header("Content-Length", std::to_string(jsonContent.length()));
request->set_body(jsonContent);
auto settings = make_shared< Settings >();
auto response = Http::sync(request, settings);
print(response)
}
What happens is that when I do the POST request from sendResult function it immediately gets a error response and does not wait for the real response.
What am I doing wrong?
Thanks.

Related

Piping a API Gateway response to client through Lambda handler

I have a REST API using AWS API Gateway. The API is handled by a custom Lambda function. I have a /prompts endpoint in my API, for which the Lambda function will call Open AI API, send it the prompt, and stream the result to the user as it is being generated (which can take a few seconds).
I'm able to stream and handle the response from Open AI's API to my Lambda function.
I would now like to re-stream / pipe that response to the client.
My question is how to do that?
Is there a way to simply pipe the stream being received from Open AI API to my client?
My Lambda function is:
ry {
const res = await openai.createCompletion({
...params,
stream: true,
}, { responseType: 'stream' });
res.data.on('data', data => {
const lines = data.toString().split('\n').filter(line => line.trim() !== '');
for (const line of lines) {
const message = line.replace(/^data: /, '');
if (message === '[DONE]') {
// store the response to DynamoDB
storeRecord(content)
return content
}
try {
const parsed = JSON.parse(message);
content += parsed.choices[0].text
// ****** I want to send content to the front-end client... *******
} catch(error) {
console.error('Could not JSON parse stream message', message, error);
}
}
});
} catch (error) {
if (error.response?.status) {
console.error(error.response.status, error.message);
error.response.data.on('data', data => {
const message = data.toString();
try {
const parsed = JSON.parse(message);
console.error('An error occurred during OpenAI request: ', parsed);
} catch(error) {
console.error('An error occurred during OpenAI request: ', message);
}
});
} else {
console.error('An error occurred during OpenAI request', error);
}
}

How to hide some dom element if user hasn't jwt token in cookies

As cookies, it is unable to retrieve from client side. What's the solution we can get verify in _middleware and passing isAuth to client side in nextjs?
// pages/_middleware.ts
const JWT_SECRET = process.env.JWT_TOKEN as string;
export async function middleware(req: NextRequest, ev: NextFetchEvent) {
const { cookies } = req;
const token = cookies.appToken;
/*
Passing some value to client side if it is not login yet.
*/
if( !token ) {
}
try {
// verify the token
const { payload: jwtData } = await jose.jwtVerify(
token, new TextEncoder().encode( JWT_SECRET )
)
return NextResponse.next();
} catch (error) {
return NextResponse.next();
// return NextResponse.redirect(new URL('/login', req.url));
}
}

Invalid grant issue with Google OAuth authentication in Qt

I'm developing a Qt application and I want to use Google authentication for it. I created a Google API as explained in the following link: https://blog.qt.io/blog/2017/01/25/connecting-qt-application-google-services-using-oauth-2-0/ but I have a problem with it. It doesn't work in many cases and I get ProtocolInvalidOperationError(302) error for https://accounts.google.com/o/oauth2/token request URL in
QOAuthHttpServerReplyHandler::networkReplyFinished(QNetworkReply *reply)
method of Qt class.
Note that I override QOAuthHttpServerReplyHandler::networkReplyFinished(QNetworkReply *reply) to get this error, because it doesn't emit any signal in this case, and the return value for reply->readAll() is as below:
{
"error": "invalid_grant",
"error_description": "Malformed auth code."
}
My Login.cpp code is something as below:
Login::Login() {
google = new QOAuth2AuthorizationCodeFlow;
google->setScope("email");
google->setAuthorizationUrl("https://accounts.google.com/o/oauth2/auth");
google->setClientIdentifier(Utility::decrypt(encryptedClientId));
google->setAccessTokenUrl("https://accounts.google.com/o/oauth2/token");
google->setClientIdentifierSharedKey(Utility::decrypt(encryptedClientSecret));
connect(google, &QOAuth2AuthorizationCodeFlow::authorizeWithBrowser,
&QDesktopServices::openUrl);
connect(google,&QOAuth2AuthorizationCodeFlow::authorizationCallbackReceived,[=](const QVariantMap data){
QString code(data["code"].toString());
if(!code2.isEmpty())
{
const QUrl redirectUri= "http://localhost:56413/cb";
QJsonObject postdata;
postdata.insert("code",code);
postdata.insert("client_id", Utility::decrypt(encryptedClientId));
postdata.insert("client_secret", Utility::decrypt(encryptedClientSecret));
postdata.insert("redirect_uri", redirectUri.toString());
postdata.insert("grant_type","authorization_code");
QString serviceURL = "oauth2/v4/token";
NetworkManager::GetInstance()->Post(postdata,serviceURL,"https://www.googleapis.com/",[=](int statusCode,int resultnumber, QJsonObject obj){
if (statusCode >= 200 &&
statusCode < 300)
{
// it's ok, do nothing
}
else {
//show error
}
});
}
});
}
void Login::googleLoginButtonPressed() {
int googlePort = 56413;
if(replyHandler == nullptr)
replyHandler = new QOAuthHttpServerReplyHandlerArio(googlePort, this);
google->setReplyHandler(replyHandler);
QObject::connect(replyHandler, &QOAuthHttpServerReplyHandler::tokensReceived, [=](const QVariantMap &map) {
googleToken = map["id_token"].toString();
connect(google, &QOAuth2AuthorizationCodeFlow::granted, [=]() {
auto reply = google->get(QUrl("https://www.googleapis.com/plus/v1/people/me"));
connect_reply = connect(reply, &QNetworkReply::finished, [=]() {
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (statusCode >= 200 &&
statusCode < 300)
{
//NOW register or login the user with email
QJsonDocument jsonResponse = QJsonDocument::fromJson(reply->readAll().data());
email = jsonResponse.object().value("emails").toArray()[0].toObject().value("value").toString();
reply->deleteLater();
}
else {
//error
}
});
});
});
google->grant();
}
what's the problem?
Thanks for your help.
We have posted a lengthy document describing how to authenticate with Google SSO and Qt and this is one of the problems we discuss. I suspect the reason is that the login code returned by Google is URL-encoded, and Qt does not decode it automatically for you. So before you set your replyHandler, you need to invoke setModifyParametersFunction to decode it, in the middle of the flow.
google->setModifyParametersFunction([](QAbstractOAuth::Stage stage, QVariantMap* parameters) {
// Percent-decode the "code" parameter so Google can match it
if (stage == QAbstractOAuth::Stage::RequestingAccessToken) {
QByteArray code = parameters->value("code").toByteArray();
(*parameters)["code"] = QUrl::fromPercentEncoding(code);
}
});

Getting 500 Error while calling webservice from google app engine

I am trying to get the response from webservice- http://services.groupkt.com/state/get/IND/all .It is working fine normally through java code but when I have deployed in google app engine it is returning 500 error.
Following one is the code.
try {
// create HTTP Client
HttpClient httpClient = HttpClientBuilder.create().build();
// Create new getRequest with below mentioned URL
HttpGet getRequest = new HttpGet("http://services.groupkt.com/state/get/IND/all");
// Add additional header to getRequest which accepts application/xml data
getRequest.addHeader("accept", "application/json");
// Execute your request and catch response
HttpResponse response = httpClient.execute(getRequest);
// Check for HTTP response code: 200 = success
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : " + response.getStatusLine().getStatusCode());
}
// Get-Capture Complete application/xml body response
BufferedReader br = new BufferedReader(new InputStreamReader((response.getEntity().getContent())));
String output;
System.out.println("============Output:============");
// Simply iterate through XML response and show on console.
while ((output = br.readLine()) != null) {
System.out.println(output);
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
I have searched it.It is showing as internal server error.How can i fix it?

I am getting a 401 error when I am sending a soap request to a nav web service

I am trying to send an XML soap request to a dynamics nav web service. This is the XML from the WSDL. I have created a web access key and its the one in the key parameter of the XML.
<s11:Envelope xmlns:s11='http://schemas.xmlsoap.org/soap/envelope/'>
<s11:Body>
<ns1:Create xmlns:ns1='urn:microsoft-dynamics-schemas/page/customerws'>
<ns1:CustomerWS>
<ns1:Key>+gn8Nu4i7iW7D/g9vCaI8HZE5IEi1NBkTBqDp5QfXe4=</ns1:Key>
<ns1:Shipping_Advice></ns1:Shipping_Advice>
<ns1:Shipment_Method_Code></ns1:Shipment_Method_Code>
<ns1:Shipping_Agent_Code></ns1:Shipping_Agent_Code>
<ns1:Shipping_Agent_Service_Code></ns1:Shipping_Agent_Service_Code>
<ns1:Shipping_Time></ns1:Shipping_Time>
<ns1:Base_Calendar_Code></ns1:Base_Calendar_Code>
<ns1:Customized_Calendar></ns1:Customized_Calendar>
<ns1:Currency_Code></ns1:Currency_Code>
<ns1:Language_Code></ns1:Language_Code>
<ns1:VAT_Registration_No></ns1:VAT_Registration_No>
</ns1:CustomerWS>
</ns1:Create>
</s11:Body>
</s11:Envelope>
And this is the code that am using to send this request:
Console.WriteLine("We have started");
string pageName = "http://hrp-dmu.uganda.hrpsolutions.co.ug:9047/DynamicsNAV80/WS/Uganda%20Management%20Institute/Page/CustomerWS";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(pageName);
req.Method = "POST";
req.ContentType = "text/xml;charset=UTF-8";
req.ProtocolVersion = new Version(1, 1);
req.Headers.Add("SOAPAction", #"urn:microsoftdynamicsschemas/page/customerws:Create");
Console.WriteLine("After preparing request object");
string xmlRequest = GetTextFromXMLFile("E:\\tst3.xml");
Console.WriteLine("xml request : "+xmlRequest);
byte[] reqBytes = new UTF8Encoding().GetBytes(xmlRequest);
req.ContentLength = reqBytes.Length;
try
{
using (Stream reqStream = req.GetRequestStream())
{
reqStream.Write(reqBytes, 0, reqBytes.Length);
}
}
catch (Exception ex)
{
Console.WriteLine("GetRequestStreamException : " + ex.Message);
}
HttpWebResponse resp = null;
try
{
resp = (HttpWebResponse)req.GetResponse();
}
catch (Exception exc)
{
Console.WriteLine("GetResponseException : " + exc.Message);
}
string xmlResponse = null;
if (resp == null)
{
Console.WriteLine("Null response");
}
else
{
using (StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
xmlResponse = sr.ReadToEnd();
}
Console.WriteLine("The response");
Console.WriteLine(xmlResponse);
}
Console.ReadKey();
when using NavUserPassword Authentication you'll need a certificate.
See here on MSDN
Cheers!