How to handle cookies with C++ code? - c++

I am looking for a way to handle sessions through cookies in C++. Can anybody please help me with some hints for the solution?

libcurl can help you with this. See "Cookies Without Chocolate Chips" here.

Assuming your C++ code is functioning as a CGI handler, it's merely a matter of reading and writing cookies in the requests and responses.
If your session data is small (less than 32 bytes or so), then you can store it all right in the cookie.
If you need to store more data, or want to share sessions between servers, then you will want to create unique and random IDs to represent your sessions. You should then take that ID and lookup the actual session data (in memory or in a database).
Everything I have written is 1990's CGI 101.
I guess in C++ land, it would look like this:
int main() {
map<string,string> headers = parseRequestHeaders(cin);
int64_t sessionId = 0;
SessionData *session = 0;
if (getSessionId(headers, &sessionId)) {
session = getSession(sessionId);
}
else {
session = newSession();
sessionId = session->id();
setCookie(sessionId);
}
// ...
}

Related

Is it possible to use AMAZON LEX to build a chatbot which connects with database and Web service stored on client side?

Our organization wants to develop a "LOST & FOUND System Application" using chatbot integrated in a website.
Whenever the user starts the conversation with the chatbot, the chatbot should ask the details of lost item or item found and it should store the details in database.
How can we do it ?
And can we use our own web-service because organization doesn't want to keep the database in Amazon's Server.
As someone who just implemented this very same situation (with a lot of help from #Sid8491), I can give some insight on how I managed it.
Note, I'm using C# because that's what the company I work for uses.
First, the bot requires input from the user to decide what intent is being called. For this, I implemented a PostText call to the Lex API.
PostTextRequest lexTextRequest = new PostTextRequest()
{
BotName = botName,
BotAlias = botAlias,
UserId = sessionId,
InputText = messageToSend
};
try
{
lexTextResponse = await awsLexClient.PostTextAsync(lexTextRequest);
}
catch (Exception ex)
{
throw new BadRequestException(ex);
}
Please note that this requires you to have created a Cognito Object to authenticate your AmazonLexClient (as shown below):
protected void InitLexService()
{
//Grab region for Lex Bot services
Amazon.RegionEndpoint svcRegionEndpoint = Amazon.RegionEndpoint.USEast1;
//Get credentials from Cognito
awsCredentials = new CognitoAWSCredentials(
poolId, // Identity pool ID
svcRegionEndpoint); // Region
//Instantiate Lex Client with Region
awsLexClient = new AmazonLexClient(awsCredentials, svcRegionEndpoint);
}
After we get the response from the bot, we use a simple switch case to correctly identify the method we need to call for our web application to run. The entire process is handled by our web application, and we use Lex only to identify the user's request and slot values.
//Call Amazon Lex with Text, capture response
var lexResponse = await awsLexSvc.SendTextMsgToLex(userMessage, sessionID);
//Extract intent and slot values from LexResponse
string intent = lexResponse.IntentName;
var slots = lexResponse.Slots;
//Use LexResponse's Intent to call the appropriate method
switch (intent)
{
case: /*Your intent name*/:
/*Call appropriate method*/;
break;
}
After that, it is just a matter of displaying the result to the user. Do let me know if you need more clarification!
UPDATE:
An example implementation of the slots data to write to SQL (again in C#) would look like this:
case "LostItem":
message = "Please fill the following form with the details of the item you lost.";
LostItem();
break;
This would then take you to the LostItem() method which you can use to fill up a form.
public void LostItem()
{
string itemName = string.Empty;
itemName = //Get from user
//repeat with whatever else you need for a complete item object
//Implement a SQL call to a stored procedure that inserts the object into your database.
//You can do a similar call to the database to retrieve an object as well
}
That should point you in the right direction hopefully. Google is your best friend if you need help with SQL stored procedures. Hopefully this helped!
Yes its possible.
You can send the requests to Lex from your website which will extract Intents and Entities.
Once you get these, you can write backend code in any language of your choice and use any DB you want.
In your use case, you might just want to use Lex. PostText will be main function you will be calling.
You will need to create an intent in Lex which will have multiple slots LosingDate, LosingPlace or whatever you want, then it will be able to get all these information from the user and pass it to your web application.

How to get CookieManager from JMeter SampleResult

I have a backend listener that posts JMeter results to an external server. It works for most parts. However, I'd like to get cookie info for failed requests. Backend listener only gets SampleResult and I don't see an API to access cookie info from SampleResult. Does anyone have an idea?
View Result Tree listener is able to print out request cookies, so there must be a way. However, it's not obvious what's the class name for that particular listener. If anyone can point me to that source code, it'll be a starting point.
With current JMeter implementation it is not possible unless your create your own AbstractBackendListenerClient implementation which will be cookies-aware.
Also depending on how do you parse result you can substitute a "not interesting" SampleResult field (for example Response Message) with cookie values for failed requests. It can be done using i.e. JSR223 PostProcessor and the following Groovy code
if (!prev.isSuccessful()) {
def manager = sampler.getCookieManager()
def cookies = new StringBuilder()
for (int i = 0; i < manager.getCookieCount(); i++) {
cookies.append(manager.get(i).getName()).append('=').append(manager.get(i).getValue())
}
prev.setResponseMessage(cookies.toString())
}
Hard to help without seeing some code, but one general direction could be this: you can check if your SampleResult is of type HTTPSampleResult, and if yes, get its cookies, using getCookies() method. Whole process could be wrapped as the following function:
public String getCookiesForHttpResult(SampleResult sampleResult) {
if (sampleResult instanceof HTTPSampleResult) {
HTTPSampleResult httpSampleResult = (HTTPSampleResult) sampleResult;
return httpSampleResult.getCookies();
}
// not HTTP result
return null;
}
Something like that is done in JMeter's RequestViewHTTP.java
Getting CookieManager in backend listener can be problematic, since it's mutable: by the time backend listener reads from CookieManager, list of cookies may be different from the time of request execution.

Where are the cookies stored?

I am sending a HTTPWebRequest from C# code and in response I am getting a cookie containing session ID. I am not able to locate the cookie in the public/non public members of response. However fiddler is capturing the cookie and its path is "/". Can anyone please tell me where should I look for this cookie? I have checked the folder "C:\Users\UserName\AppData\Roaming\Microsoft\Windows\Cookies" and its not there.
Cookies may be physically stored in different locations, depending on the browser.
I think you're better off getting the HttpWebRequest working with cookies.
See the answer to this question regarding adding a CookieContainer to the request object.
Every browser store cookies onto different locations
For example
Cookie information is stored in the profile folder, in two files.
Starting with Firefox 3.0 and SeaMonkey 2.0 the cookie information is
stored in the files cookies.sqlite and permissions.sqlite. In Firefox
2 or below and Mozilla Suite/SeaMonkey 1.x, cookies are stored in the
cookies.txt file and cookie site permissions are stored in the
hostperm.1 file. File Description cookies.sqlite cookies.txt Holds
all of your cookies, including login information, session data, and
preferences. permissions.sqlite hostperm.1 Holds preferences about
which sites you allow or prohibit to set cookies, to display images,
to open popup windows and to initiate extensions installation.
Cookie storage depends on both your browser and OS. In older browsers, they were just stored in a file path named something like "Cookies". Most modern browsers store cookies in some encrypted way, usually in a sqllite db flat file. If you could provide more info on what you are trying to track down via the actual local cookie storage (as opposed to using the browser's built in cookie browser), it would help get more info on where to look or alternatives for what you have in mind.
If you want to use persistent cookies with HttpWebRequest, you'll need to import wininet.dll to handle this (or you handle persistence yourself).
There's an example on MSDN in the Community Content section for WebRequest.Create Method.
snippet
[DllImport("wininet.dll", CharSet=CharSet.Auto , SetLastError=true)]
private static extern bool InternetGetCookie (string url, string name, StringBuilder data, ref int dataSize);
private static string RetrieveIECookiesForUrl(string url)
{
StringBuilder cookieHeader = new StringBuilder(new String(' ', 256), 256);
int datasize = cookieHeader.Length;
if (!InternetGetCookie(url, null, cookieHeader, ref datasize))
{
if (datasize < 0)
return String.Empty;
cookieHeader = new StringBuilder(datasize); // resize with new datasize
InternetGetCookie(url, null, cookieHeader, ref datasize);
}
// result is like this: "KEY=Value; KEY2=what ever"
return cookieHeader.ToString();
}

gSoap: How to set or change cookies on client in Qt?

I'am use next code for authorization on server by service, and get other service'methods using cookie identifer for authorizathion.
TerminalControllerBinding soapObj;
soap_init1(soapObj.soap, SOAP_C_UTFSTRING);
soapObj.endpoint = "http://192.168.*.*/path/to/service";
ns1__getTemplatesResponse *response = new ns1__getTemplatesResponse;
std::string auth_res = "";
soapObj.ns1__auth("user", "password", auth_res);
QString sessid = QString::fromStdString(auth_res);
qDebug() << sessid;
soapObj.soap->cookies = soap_cookie(soapObj.soap, "sessid", sessid.toAscii().data(), ".");
Server not getting cookie "sessid"
I am kind of confused by the code you posted: You allocate memory for ns1__getTemplatesResponse, then do some apparently unrelated stuff; in fact you do not reference it again at all. Furthermore soap_cookie is a struct and soap->cookies is basically a list. So there is no magic that transfers the cookies to the server here.
I think what you want is soap_set_cookie. You can find a little more information on client side cookies here, but there isn't any example code. Much more helpful however is actually the server side documentation (the handling of cookies doesn't differ much).
Also notice that you either need to compile with -DWITH_COOKIES or define the macro yourself in stdsoap.h if you haven't done so already.

Aggregate parallel results from different web services in Windows Azure

Webservice1 can receive a set of Lon/Lat variables. Based on these variables it returns a resultset of items nearby.
In order to create the resultset Webservice1 has to pass the variables to multiple webservices of our own and multiple external webservices. All these webservice return a resultset. The combination of these resultsets of these secondary Webservices is the resultset to be returned by Webservice1.
What is the best design approach within Windows Azure with costs and performance in mind?
Should we sequential fire requests from Webservice1 to the other webservices wait for a response and continue? Or can we eg use a queue where we post the variables to be picked up by the secondary webservices?
I think you've answered you're own question in the title.
I wouldn't worry about using a queue. Queues are great for sending information off to get dealt with by something else when it doesn't matter how long it takes to process. As you've got a web service that's waiting to return results, this is not ideal.
Sending the requests to each of the other web services one at a time will work and is the easiest option technically, but it won't give you the best performance.
In this situation I would send requests to each of the other web services in parallel using the Task Parallel Library. Presuming the order of the items that you return isn't important your code might look a bit like this.
public List<LocationResult> PlacesOfInterest(LocationParameters parameters)
{
WebService[] webServices = GetArrayOfAllWebServices();
LocationResult[][] results = new LocationResult[webServices.Count()][];
// Call all of the webservices parallel
Parallel.For((long)0,
webServices.Count(),
i =>
{
results[i] = webServices[i].PlacesOfInterest(parameters);
});
var finalResults = new List<LocationResult>();
// Put all the results together
for (int i = 0; i < webServices.Count(); i++)
{
finalResults.AddRange(results[i]);
}
return finalResults;
}