Sunday, June 9, 2013

LoadRunner VuGen scripting - How to automatically download file from server and save it to local disk?

LoadRunner records file transferring from server and does not record file saving.

What to do, if you have to save transferred file to local disk?
Continue reading, and you will get the solution :)

You can download file from a server with the web_url function.
See an example:

Image downloading:
web_url("logo.gif",
"URL=http://www.google.com/intl/en_ALL/images/logo.gif",
"Resource=1",
"RecContentType=image/gif",
"Snapshot=t1.inf",
LAST);

This code downloads Google's logo image:

To save this image as file to local disk, we have to perform these steps:
Capture image from server's response
Save captured data to local disk

How to capture image from server's response?

Use web_reg_save_param function with the following boundaries - "LB=\r\n\r\n", "RB=". These boundaries allows to capture the whole data from a body of server's response. Function will look like:
web_reg_save_param("prmLogoImage", "LB=\r\n\r\n", "RB=", LAST);

This function should be placed before web_url function. After execution, prmLogoImage parameter will contain GIF-file.

I will clarify briefly the meaning of boundaries - "LB=\r\n\r\n" and "RB=".
Please, read the basic concepts of HTTP protocol, read Request message section:

HTTP response consists of the following:
Headers, such as HTTP/1.1 200 OK or Content-Length: 3473
An empty line
A message body, containg text of requested page or file

So, Header and Message body should be separated by empty line.
First CRLF (that is, a carriage return (CR = "\r") followed by a line feed (LF = "\n")) ends last header, and second CRLF ( = "\r\n") creates empty line. All data, followed by second CRLF, are treated as message body.
To summarize - "LB=\r\n\r\n" says "start capturing from the beginning of message body", empty right boundary "RB=" says "capture data till the end of message".

Open LoadRunner and enable logging of data, returned by server:


Then execute script containing initial web_url function, and open Replay log:


As you see, Replay log contains "\r\n\r\n" at the end of server's response.
Also, pay attention, that server returns the length of file to be downloaded (Content-Length: 8558).

Save captured data to local disk
Saving captured binary data (in our case, GIF file) requires additional step - we have to determine the length (= size) of captured data.

Tips: The simplest way - strlen function - is not correct. Imagine, that that captured data contains embedded NULL characters ('\0'):
"123\0qwe"
The real size of captured data = 7 bytes ('1', '2', '3', '\0', 'q', 'w', 'e').
But strlen function will return value 3, because it counts bytes before the first NULL character ('\0').

To calculate size of captured data use lr_eval_string_ext function:
lr_eval_string_ext ("{prmLogoImage}", strlen("{prmLogoImage}") /* = 14*/, &szBuf, &nLength, 0, 0,-1);

lr_eval_string_ext function copies captured data into szBuf array and places a size of captured data into nLength variable. That's easy, I hope :) If not, Help will help :)

Tips: There is another way to get known the size of file to be downloaded. Remember, that server returned the length of file (Content-Length: 8558). So, you can extract this value using Correlation.

And the last action is to save binary data from szBuf array into a local file. I used standard fwrite function from C programming language:
fwrite(szBuf, len, 1, hFile);

Well, please see the whole source code:

Click the block to expand the source code:
int WriteDataToFile(char *szFileName, const char *szBuf, int len)
{
int hFile;

hFile = fopen(szFileName,"wb");
.....

Execute the source code, and you will see, that new file will be created and saved automatically - "C:\LogoImage.gif". And this is what we needed - Google's logo image.