Libevent 2 - write callback / infinite loop - libevent

I'm playing with Libevent as a server and I'm having a problem
Basically I'm using the example at the bottom of this page, http://www.wangafu.net/~nickm/libevent-book/Ref6_bufferevent.html:
I have the main/accept/readcb working well - however trying to understand the writecb.
Before I go further I want to make sure I have this correct.
When a client send (curl in this instance) sends some JSON, this is called in the read_callback, when I want to write back to the curl I use the write_callback.
the problem I have in short, when I do a curl with json. It requests that the server sends a http/1.1 100 continue before sending the JSON. I could ignore that but would rather not.
So this is what I have for my write callback:
void writecb(struct bufferevent *bev, void *ctx){
struct evbuffer *tmp = evbuffer_new();
evbuffer_add_printf(tmp, "HTTP/1.1 100 Continue\r\n\r\n");
bufferevent_write_buffer(bev, tmp);
evbuffer_free(tmp);
printf("finish sending data back to client!\n");
}
What happens is when I do a curl statement:
curl -vv -H "Content-Type: application/json" --data #test.json http://localhost:40714
On the console there is an infinite loop.
However if I put this code within the readcb, it works like a charm. So my question, what is the point of writecb? Is it when you finalize a write and what to close a connection you send 'stuff'?

The point of writecb is opposite to readcb: writecb is invoked by libevent automatically when there is enough room in the OUTPUT side of bufferevent for some new data to be written into.
Here you described a good example of infinite loop:
writecb was invoked by libevent (because there is enough room on OUTPUT side)
inside writecb you generating new data and writing it into the OUTPUT by bufferevent_write_buffer. Then writecb returns context back to libevent main loop.
libevent is passing all the data from OUTPUT to the kernel. And when done, libevent sees that a free place became available in OUTPUT buffer. This generates next writecb event and the callback is invoked again... And here is the infinite loop.

Related

Get console output of a jenkins job by sending the build number as a json parameter through api

I'm trying to get the job status by providing the build number as a parameter.
curl -s -S -u "Ashwin":"XXX" "http://XX.XXX.XXX.XX:8080/job/apitest/buildNum/logText/progressiveText?start=0"
The above snippet work absolutely fine. Is there anyway to send the build number as a json body.
In a word, no. The Jenkins API defines the query for the console log as a GET request, which (at least in the Jenkins API) does not contain a body. The primary parameters like job and build id are part of the URL path, and optional parameters are provided in the query string part of the URL.
This question strikes me as odd. Why can you not construct the query URL (which contains the build id as part of the URL path) in same way that you would construct the JSON structure that you propose sending in the body?

Looping in JMeter based on condition

I have a scenario where a HTTP request needs to be executed multiple times in two loops as said below:
-Thread Group
-While Controller
-While Controller
-HTTP Request
-BeanShell Post Processor(1)
-BeanShell Post processor(2)
HTTP Request:
https://xx.xxx.xx.xx/api/v1/xx/utilization?starttime=${starttime}&endtime=${endtime}&start=${mycounter}&limit=100
In first BeanShell Post Processor, I am incrementing only "mycounter" and I am expecting the while loop above that to execute till it goes false.
In the second BeanShell Processor, I am incrementing "startime" & "endtime" and I am epecting the while loop above it to execute till it goes false.
But, Observing that thinsg are not working as expected. Does my undertanding is correct. I see that the beanshell processors are not executing as per the WHile loops they fall under.
Any comments/Suggestions??
Add For Loop controller to the plan.
Please refer this link.

Wifi REST API GET call - how to concatenate and pass URL parameters?

I'm not too familiar with the arduino c+ language, but I would like to get this native code to work.
In curl this works:
curl "http://access.alchemyapi.com/calls/text/TextGetTextSentiment?text=i+feel+great&outputMode=json&apikey=my-apikey"^C
So I am trying to use a WiFi client for the same request but it seems the passing and parsing of the URL parameters is causing a problem.
sprintf(request,"/calls/text/TextGetTextSentiment?apikey=%s&text=%s&outputMode=%s","31adba6dfc3a879b88762f50efc9f892bd573207", "i+feel+great", "json");
Serial.println(request);
When I print the request, everything after the & gets truncated.
char serverName[] = "access.alchemyapi.com";
if(client.connect(serverName,port) == 1)
{
sprintf(outBuf,"GET %s HTTP/1.1",page);
client.println(outBuf);
sprintf(outBuf,"Host: %s",serverName);
client.println(outBuf);
client.println(F("Connection: close\r\n"));
}
This works (HTTP status 200, though with missing parameters error from the API service) if I only pass in 1 parameter.

OpenSSL: Specify packet size of application data

When I do something like this, apps/openssl s_client -connect 10.102.113.3:443 -ssl3, client-server communication is created using openSSL.
Now, I want to send application data from the client to the server. For example, after doing apps/openssl s_client -connect 10.30.24.45:443 -ssl3, I get something like this:
...certificate and session details...
---
GET /path/to/file
The GET /path/to/file all goes in one SSL record. I want to send it in multiple records.
I assume I have to edit apps/s_client.c, and find the place where the SSL_write or similar happens.
How do I go about something like that?
For a properly designed application the TCP packet sizes and SSL frame sizes should not matter. But there are badly designed applications out there which expect to get like the HTTP request inside a single read, which often means that it must be inside the same SSL frame. If you want to run tests against applications to check for this kind of behavior you either have to patch your s_client application or you might use something else, like
#!/usr/bin/perl
use strict;
use IO::Socket::SSL;
my $sock = IO::Socket::SSL->new('www.example.com:443') or die "$!,$SSL_ERROR";
print $sock "GE";
print $sock "T / HT";
print $sock "TP/1.0\r\n\r\n";
This will send the HTTP request header within 3 SSL frames (which might still get put together into the same TCP packet). Since on lots of SSL stacks (like OpenSSL) one SSL_read reads only a single SSL frame this will result in 3 reads necessary to read the full HTTP request.
Okay, I figured out that I needed to change the number of bytes I'm writing using the SSL_write.
This is a code snippet, starting at line 1662 of s_client.c:
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
{
k=SSL_write(con,&(cbuf[cbuf_off]), (unsigned int)cbuf_len);
.......
}
To make the application data be sent in multiple records instead of just the one, change the last parameter in the SSL_write.
For example, do this:
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
{
k=SSL_write(con,&(cbuf[cbuf_off]), 1);
.......
}
This will result in something like this:
Notice the multiple records for Application Data instead of just the one.

jmeter help - test around polling /w meta refresh

I am new to jmeter and am working on putting together a test plan. The hurdle I've encountered is as follows:
First, a POST is made to processForm.aspx
Then, the user is redirected to pleaseWait.aspx
This page either redirects immediately to results.aspx OR loads, with a META REFRESH tag set to refresh in 5 seconds (and this step is repeated).
Now -- I can get this to execute by doing the following:
HTTP Sampler POST to processForm.aspx
Assert Response contains "<something on pleaseWait.aspx>"
While LAST
HTTP Sampler GET to pleaseWait.aspx
Assert Response contains "<something on results.aspx>"
However -- I don't care for this method, because it results in failed assertions (even though things are working as expected). I am sure there must be some other way to do this? Anyone more familiar with JMeter than I?
UPDATE:
Got it going by using Regular Expression Extractor instead of Assertions.
1) Add a User Defined Variables section at Test Plan Root
2) Add a variable to it "LoginWait" and "false"
HTTP Sampler POST to processForm.aspx
RegEx Extract Response Body contains "<something on pleaseWait.aspx>" into LoginWait
While ${LoginWait}
HTTP Sampler GET to pleaseWait.aspx
RegEx Extract Response Body contains "<something on pleaseWait.aspx>" into LoginWait
...
You could try using "follow redirects" on your HTTP Request. It would eliminate the logic you need, and still get you to the page you're going.