基于LR的HTTP协议接口性能测试脚本实例
背景介绍
XXX项目性能测试中新增业务场景:XX设备的在线激活,因为存在多用户同时在线激活,故需进行性能测试以确认后台服务器系统在多用并发时功能是否正常,性能指标是否满足规格要求。用户使用场景为用户通过XX设备平台(类似客户端)触发激活请求,该请求经过中间系统处理并最终被Licnese后台服务器处理并响应。客户端与服务器经过了广域网环境,无设备在线激活业务操作界面。
场景和现状
XX设备平台通过http协议与中转系统进行交互,中转系统将http协议的消息转换为Web Service(SOAP)消息并转送给Licnese服务器进行处理,XX设备发出的http消息数据是经过加密处理的。已提供XX设备激活模拟工具(.exe文件+配置文件)和加解密dll文件/加解密jar包。.exe文件为win32控制台程序编写的模拟激活业务的工具,模拟工具执行时间很短,在几秒钟就完成激活业务(与XXX服务器发生五次交互),试图通过LR工具试录制脚本,发现无法录制到模拟工具发出的请求消息脚本。
方案确定
在LR中通过手工编写http协议脚本,在LR中模拟设备在线激活业务与中转系统交互,由于提供的加解密DLL文件并非C/C++语言写的,所以LR中选择http协议时无法直接调用加解密DLL,但因为提供了加解密jar包,可以在本地java环境中部署该jar包,在命令行中执行java命令来进行加解密操作,最终确定通过手工编写一个C的DLL,在该DLL中编写调用命令行并获取命令行结果的函数,在LR中加载并调用该DLL来实现数据的加解密, 另外,因为加解密后的数据为二进制数据,所以需要使用web_custom_request函数发送二进制消息体,如对二进制消息体的处理过程中需要使用循环,出于执行效率的考虑,可将这部分代码一并放入DLL中文件。
脚本
#ifndef _GLOBALS_H
#define _GLOBALS_H //--------------------------------------------------------------------
// Include Files
#include "lrun.h"
#include "web_api.h"
#include "lrw_custom_body.h" //--------------------------------------------------------------------
// Global Variables
//#define TESTDLL 0 //--------------------------------初始化--------------------------------
//获取安全码的局部变量
char szSecurityCodeBody[]; //存放Body
char szPdtName[]; //产品名称
char szPdtVer[]; //产品版本号
char szDevESN[]; //生成ESN,20-30位随机数字和字母
char szDevIndex[]; //生成devIndex,设备ESN哈希后取前四个字节....
char szSecurityCodBodyEnc[];//存放加密后的Body
char getSecurityCode_requestData[];//存放待解密data数据
char getSecurityCode_requestDataDnc[];//存放解密后的data数据
char vuserid_str[]; //组装临时文件名
char curtime_str[];
char TmpFileName[]; //临时文件名
int iRet = -; //加解密函数返回值
int ContentLength = ;
const char *SecurityCodeTou = "securityCode=";
char *SecurityCodeTmp = NULL;
const char *resCodeTou = "resCode=";
char *resCodeTmp = NULL;
int resCode = ;
char *delim = "&";
char requestDataDnc_Tmp[];//临时存放各响应解密后的data数据 //获取订单授权信息
char szAuthorizeBody[];
char szOrdLac[];
char szAuthorizeBodyEnc[];
char getAuthInfo_requestData[];//存放待解密data数据
char getAuthInfo_requestDataDnc[];//存放解密后的data数据
const char *authInfoTou = "authInfo=";
char *authInfoTmp = NULL; //在线激活
char szActDevLicenseBody[];
char szActDevLicenseBodyEnc[];
char actDevLicense_requestData[];//存放待解密data数据
char actDevLicense_requestDataDnc[];//存放解密后的data数据 //在线下载
char szDownLoadOnlineBody[];
char szDownLoadOnlineBodyEnc[];
char getDevLicense_requestData[];//存放待解密data数据
char getDevLicense_requestDataDnc[];//存放解密后的data数据 //释放会话资源
char szReleaseSessionBody[];
char szJsessionid[];
char szReleaseSessionBodyEnc[];
char relSesRsr_requestData[];//存放待解密data数据
char relSesRsr_requestDataDnc[];//存放解密后的data数据 //文件内容校验
const char *ProductNameTou = "Product=";
char *ProductNameTmp = NULL;
char ProductNameTmp_STR[];
char *ProductName_delim = "\n";
const char *VersionTou = "Version=";
char *VersionTmp = NULL;
char VersionTmp_STR[];
char *Version_delim = "\n";
const char *EsnTou = "Esn=\"";
char *EsnTmp = NULL;
char EsnTmp_STR[];
char *Esn_delim = "\"\n";
int strcmp_result = ; //比较结果,相等为0 #endif // _GLOBALS_H
vuser_init()
{ int iLoadDllRes1 = -; //char szRes[4096] = {0}; //加密后的字符串,一定要定义足够大,防止越界!!!
//char szRes[4096] = "3d9d1defa4044f28e228b43de69b48ca9c992f974d184bc353905bee18d4890614eed06bce9a237da6a636043c456b3831e62ddf6ad7571487b38afc6a0ee1041b32f4ecf69c1d135f79e51ff71684132458d5d1935ddc8c700bf9552b06c80dd568cb4711a2d841674874d16570c3ac0efd5c8e2201e98788fdaa11763cf968f7b7b800655c26d3731fda05362ff59b6a9ec1caa8e06adf9db3900ef26c4dd898cc462f7597ee6800053e5748cc97584419b3f7b60a301bdb034701a9e97ee62749b1d9308deef976e1eaa103123ac2db17bc5e86545a6ad75711fc2442434fd0c9d365baf6267c12b070d1836b8e0e843c70232644a963a06a14357c78de0d";
//int iRet = -1;
//char szRes2[4096] = {0}; //解密后的字符串
//char hello[100] = "hello";
//char hello[100] = "version=1.0&reqType=getSecurityCode&prdName=USG5560&prdVer=V300R001&devIndex=CEA9"; iLoadDllRes1 = lr_load_dll("dencdll.dll");
if ( != iLoadDllRes1)
{
lr_output_message("Notify:Load Dll error: dencdll.dll");
return -;
} //----------------------------------------------测试加密----------------------------------------------
/*
* 打印hello的加密结果
* 注意:1. SdpEndecTest文件夹、commons-codec-1.8.jar、libscpjavainterface.dll、log4j-1.2.15.jar、
* scpjavainterface.jar、SdpEndecApi.jar、vcgscpjavainterface.dll等均要放到“D:\dm\sdp\systemdll\”目录下
* 函数原型: int Encrypt(int iType, const char* szSecurityCode, const char* szOri, const char* szFileName, char *szRes)
* iType: 类型
* szSecurityCode: 安全码
* szOri:需要被加密的字符串;
* szFileName:临时文件(建议一个用户创建一个);
* szRes: 加密后的字符串
*
*/ //iRet = Encrypt(0,"",hello,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile1",szRes);
//lr_output_message("Notify:The result = %d, the encrypt are: %s",iRet,szRes); // iRet = Decrypt(0,"",szRes,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile2",szRes2);
// lr_output_message("Notify:The result = %d, the decrypt are: %s",iRet,szRes2); return ;
}
Action()
{
web_set_max_html_param_len(""); START:
//--------------------------------初始化--------------------------------
memset(szSecurityCodeBody, '\0',sizeof(szSecurityCodeBody));
memset(szSecurityCodBodyEnc, '\0',sizeof(szSecurityCodBodyEnc));
memset(szPdtName, '\0',sizeof(szPdtName));
memset(szPdtVer, '\0',sizeof(szPdtVer));
memset(szDevESN, '\0',sizeof(szDevESN));
memset(szDevIndex, '\0',sizeof(szDevIndex));
memset(szAuthorizeBody, '\0',sizeof(szAuthorizeBody));
memset(szOrdLac, '\0',sizeof(szOrdLac));
memset(szActDevLicenseBody, '\0',sizeof(szActDevLicenseBody));
memset(szAuthorizeBodyEnc, '\0',sizeof(szAuthorizeBodyEnc)); memset(szActDevLicenseBodyEnc, '\0',sizeof(szActDevLicenseBodyEnc));
memset(szDownLoadOnlineBody, '\0',sizeof(szDownLoadOnlineBody));
memset(szReleaseSessionBody, '\0',sizeof(szReleaseSessionBody));
memset(szJsessionid, '\0',sizeof(szJsessionid));
memset(getSecurityCode_requestData,'\0',sizeof(getSecurityCode_requestData));
memset(getSecurityCode_requestDataDnc,'\0',sizeof(getSecurityCode_requestDataDnc));
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
memset(vuserid_str,'\0',sizeof(vuserid_str));
memset(curtime_str,'\0',sizeof(curtime_str));
memset(TmpFileName,'\0',sizeof(TmpFileName)); memset(actDevLicense_requestData,'\0',sizeof(actDevLicense_requestData));
memset(actDevLicense_requestDataDnc,'\0',sizeof(actDevLicense_requestDataDnc));
memset(ProductNameTmp_STR,'\0',sizeof(ProductNameTmp_STR));
memset(VersionTmp_STR,'\0',sizeof(VersionTmp_STR));
memset(EsnTmp_STR,'\0',sizeof(EsnTmp_STR));
memset(szDownLoadOnlineBodyEnc,'\0',sizeof(szDownLoadOnlineBodyEnc));
memset(getDevLicense_requestData,'\0',sizeof(getDevLicense_requestData));
memset(getDevLicense_requestDataDnc,'\0',sizeof(getDevLicense_requestDataDnc));
memset(szReleaseSessionBodyEnc,'\0',sizeof(szReleaseSessionBodyEnc));
memset(relSesRsr_requestData,'\0',sizeof(relSesRsr_requestData)); memset(relSesRsr_requestDataDnc,'\0',sizeof(relSesRsr_requestDataDnc));
memset(getAuthInfo_requestData,'\0',sizeof(getAuthInfo_requestData));
memset(getAuthInfo_requestDataDnc,'\0',sizeof(getAuthInfo_requestDataDnc)); strcpy(szSecurityCodeBody,"version=1.1&reqType=getSecurityCode&prdName=");
strcpy(szAuthorizeBody,"version=1.1&reqType=getAuthInfo&prdName=");
strcpy(szActDevLicenseBody,"version=1.1&reqType=actDevLicense&prdName=");
strcpy(szDownLoadOnlineBody,"version=1.1&reqType=getDevLicense&prdName=");
strcpy(szReleaseSessionBody,"version=1.1&reqType=relSesRsr&jsessionid=");
strcpy(szOrdLac,lr_eval_string("{Param_OrdLac}"));
strcpy(szPdtName,lr_eval_string("{Param_PdtName}")); //获取产品名称
strcpy(szPdtVer, lr_eval_string("{Param_PdtVer}")); //获取产品版本号 //USG5560,V300R001,PSCE59A36540B14
//USG5560,V300R001,T69YGLB7A405
//USG5560,V300R001,PSCE59A36540B12
//---调试用ESN
//strcpy(szDevESN,lr_eval_string("{Param_ESN_Part1}"));
//strcat(szDevESN,lr_eval_string("{Param_ESN_Part2}"));
//strcpy(szDevESN,"456789ASWABCDHSJEUWYDSWDF");
strcpy(szDevESN,lr_eval_string("{Param_ESN}")); //对szDevESN进行HASH //取前四个字节得到szDevIndex ASDE
//strcpy(szDevIndex,"SWDF");
strcpy(szDevIndex,lr_eval_string("{Param_DevIndex}")); lr_output_message("----------szOrdLac:%s, szPdtName:%s, szPdtVer:%s, szDevESN:%s, szDevIndex:%s----------", szOrdLac,szPdtName,szPdtVer,szDevESN,szDevIndex); //固定头
web_add_auto_header("Accept",
"text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
web_add_auto_header("Accept-Language",
"zh-cn,zh;q=0.5");
web_add_auto_header("Accept-Encoding",
"gzip,deflate");
web_add_auto_header("Connection",
"keep-alive");
web_remove_auto_header("Content-Type",
LAST);
web_remove_auto_header("Cache-Control",
LAST);
web_remove_auto_header("User-Agent",
LAST); //--------------------------------获取安全码-------------------------------
//封装body
strcat(szSecurityCodeBody,szPdtName);
strcat(szSecurityCodeBody,"&prdVer=");
strcat(szSecurityCodeBody,szPdtVer);
strcat(szSecurityCodeBody,"&devIndex=");
strcat(szSecurityCodeBody,szDevIndex);
lr_output_message("Notify:The szSecurityCodeBody: %s",szSecurityCodeBody); //临时文件名生成
strcpy(TmpFileName,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile");
strcpy(vuserid_str,lr_eval_string("{vuserid_Param}"));
strcpy(curtime_str,lr_eval_string("{curtime_Param}")); strcat(TmpFileName,vuserid_str);
strcat(TmpFileName,"_");
strcat(TmpFileName,curtime_str); //加密szSecurityCodeBody
iRet = Encrypt(,"",szSecurityCodeBody,TmpFileName,szSecurityCodBodyEnc);
lr_output_message("----------iRet:%d,TmpFileName:%s,szSecurityCodBodyEnc:%s----------", iRet,TmpFileName,szSecurityCodBodyEnc); //放入参数中
lr_save_string(szSecurityCodBodyEnc,"getSecurityCodeBody_Param");
//lr_save_string(destHexCode,"getSecurityCodeBody_Param"); //关联data内容
web_reg_save_param_ex(
"ParamName=getSecurityCode_requestData_Param",
"LB=data=",
"RB=",
SEARCH_FILTERS,
LAST); //关联Content-Length的值
web_reg_save_param_ex(
"ParamName=ContentLength_Param",
"LB=Content-Length: ",
"RB=\r\n",
SEARCH_FILTERS,
"Scope=HEADERS",
LAST); //关联会话ID
web_reg_save_param_ex(
"ParamName=jsessionid_Param",
"LB=JSESSIONID=",
"RB=;",
SEARCH_FILTERS,
LAST); //事物开始
lr_start_transaction("GetSecurityCode"); //发起获取安全码请求
web_custom_request("web_custom_request",
"URL=http://{Param_serverIP}/LSP/device/licOnlineActivation.do?type=0",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTTP",
"BodyBinary={getSecurityCodeBody_Param}",
LAST); lr_end_transaction("GetSecurityCode", LR_AUTO); ContentLength = atoi(lr_eval_string("{ContentLength_Param}")) - strlen("type=0&data="); //解密data内容
memcpy(getSecurityCode_requestData,lr_eval_string("{getSecurityCode_requestData_Param}"),ContentLength);
iRet = Decrypt(,"",getSecurityCode_requestData,ContentLength,TmpFileName,getSecurityCode_requestDataDnc);
lr_output_message("----------iRet:%d,getSecurityCode_requestData:%s,getSecurityCode_requestDataDnc: %s----------",iRet,getSecurityCode_requestData,getSecurityCode_requestDataDnc); //提取resCode
strcpy(requestDataDnc_Tmp,getSecurityCode_requestDataDnc);
resCodeTmp = (char *)strstr(requestDataDnc_Tmp,resCodeTou);
if (NULL == resCodeTmp)
{
lr_error_message("resCodeTmp is NULL!");
//return -1;
goto START;
}
resCodeTmp += strlen(resCodeTou);
resCodeTmp = (char *)strtok(resCodeTmp,delim);
resCode = atoi(resCodeTmp);
lr_output_message("----------resCode:%d----------",resCode); //判断响应的返回码是否正确,如果不正确就退出!
if (!=resCode && !=resCode)
{
//return -1;
goto START;
} //提取安全码
SecurityCodeTmp = (char *)strstr(getSecurityCode_requestDataDnc,SecurityCodeTou);
if (NULL == SecurityCodeTmp)
{
//return -1;
goto START;
}
SecurityCodeTmp += strlen(SecurityCodeTou);
lr_output_message("----------SecurityCodeTmp:%s----------",SecurityCodeTmp); //--------------------------------获取订单授权信息--------------------------------
//封装body
strcat(szAuthorizeBody,szPdtName);
strcat(szAuthorizeBody,"&prdVer=");
strcat(szAuthorizeBody,szPdtVer);
strcat(szAuthorizeBody,"&devEsn=");
strcat(szAuthorizeBody,szDevESN);
strcat(szAuthorizeBody,"&ordLac=");
strcat(szAuthorizeBody,szOrdLac); //临时文件名生成
strcpy(TmpFileName,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile");
strcpy(vuserid_str,lr_eval_string("{vuserid_Param}"));
strcpy(curtime_str,lr_eval_string("{curtime_Param}"));
strcat(TmpFileName,vuserid_str);
strcat(TmpFileName,"_");
strcat(TmpFileName,curtime_str); //加密szAuthorizeBody
iRet = Encrypt(,SecurityCodeTmp,szAuthorizeBody,TmpFileName,szAuthorizeBodyEnc);
lr_output_message("----------iRet:%d, szAuthorizeBodyEnc: %s----------",iRet,szAuthorizeBodyEnc); //放入参数中
lr_save_string(szAuthorizeBodyEnc,"getAuthBody_Param"); //关联data内容
web_reg_save_param_ex(
"ParamName=getAuthInfo_requestData_Param",
"LB=data=",
"RB=",
SEARCH_FILTERS,
LAST); //关联Content-Length的值
web_reg_save_param_ex(
"ParamName=ContentLength_Param",
"LB=Content-Length: ",
"RB=\r\n",
SEARCH_FILTERS,
"Scope=HEADERS",
LAST); lr_start_transaction("GetOrderAuthorInfo"); web_custom_request("web_custom_request",
"URL=http://{Param_serverIP}/LSP/device/licOnlineActivation.do;jsessionid={jsessionid_Param}?type=1",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTTP",
"BodyBinary={getAuthBody_Param}",
LAST);
lr_end_transaction("GetOrderAuthorInfo", LR_AUTO); ContentLength = atoi(lr_eval_string("{ContentLength_Param}")) - strlen("type=0&data="); //解密data内容
memcpy(getAuthInfo_requestData,lr_eval_string("{getAuthInfo_requestData_Param}"),ContentLength);
iRet = Decrypt(,SecurityCodeTmp,getAuthInfo_requestData,ContentLength,TmpFileName,getAuthInfo_requestDataDnc);
lr_output_message("----------iRet:%d, getAuthInfo_requestDataDnc: %s----------",iRet,getAuthInfo_requestDataDnc); //提取resCode
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,getAuthInfo_requestDataDnc);
resCodeTmp = (char *)strstr(requestDataDnc_Tmp,resCodeTou);
if (NULL == resCodeTmp)
{
lr_error_message("resCodeTmp is NULL!");
//return -1;
goto START; }
resCodeTmp += strlen(resCodeTou);
resCodeTmp = (char *)strtok(resCodeTmp,delim);
resCode = atoi(resCodeTmp);
lr_output_message("Notify:resCode:%d",resCode); //判断响应的返回码是否正确,为100,如果不正确就退出!
if (!=resCode && !=resCode && !=resCode)
{
lr_error_message("resCode is not 100 !");
//return -1;
goto START;
} //提取授权信息/
/*
authInfoTmp = (char *)strstr(getAuthInfo_requestDataDnc,authInfoTou);
if (NULL == authInfoTmp)
{
lr_error_message("authInfoTmp is NULL!");
return -1; }
authInfoTmp += strlen(authInfoTou);
lr_output_message("Notify:authInfoTmp:%s",authInfoTmp);
*/ //--------------------------------在线激活--------------------------------
//封装body
strcat(szActDevLicenseBody,szPdtName);
strcat(szActDevLicenseBody,"&prdVer=");
strcat(szActDevLicenseBody,szPdtVer);
strcat(szActDevLicenseBody,"&devEsn=");
strcat(szActDevLicenseBody,szDevESN);
strcat(szActDevLicenseBody,"&ordLac=");
strcat(szActDevLicenseBody,szOrdLac); //临时文件名生成
strcpy(TmpFileName,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile");
strcpy(vuserid_str,lr_eval_string("{vuserid_Param}"));
strcpy(curtime_str,lr_eval_string("{curtime_Param}"));
strcat(TmpFileName,vuserid_str);
strcat(TmpFileName,"_");
strcat(TmpFileName,curtime_str); //加密szActDevLicenseBody
iRet = Encrypt(,SecurityCodeTmp,szActDevLicenseBody,TmpFileName,szActDevLicenseBodyEnc);
lr_output_message("----------iRet:%d, szActDevLicenseBodyEnc: %s----------",iRet,szActDevLicenseBodyEnc); //放入参数中
lr_save_string(szActDevLicenseBodyEnc,"actDevLicenseBody_Param"); //关联data内容
web_reg_save_param_ex(
"ParamName=actDevLicense_requestData_Param",
"LB=data=",
"RB=",
SEARCH_FILTERS,
LAST); //关联Content-Length的值
web_reg_save_param_ex(
"ParamName=ContentLength_Param",
"LB=Content-Length: ",
"RB=\r\n",
SEARCH_FILTERS,
"Scope=HEADERS",
LAST); lr_start_transaction("ActiveOnline"); web_custom_request("web_custom_request",
"URL=http://{Param_serverIP}/LSP/device/licOnlineActivation.do;jsessionid={jsessionid_Param}?type=1",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTTP",
"BodyBinary={actDevLicenseBody_Param}",
LAST); lr_end_transaction("ActiveOnline", LR_AUTO); ContentLength = atoi(lr_eval_string("{ContentLength_Param}")) - strlen("type=0&data="); //解密data内容
memcpy(actDevLicense_requestData,lr_eval_string("{actDevLicense_requestData_Param}"),ContentLength);
iRet = Decrypt(,SecurityCodeTmp,actDevLicense_requestData,ContentLength,TmpFileName,actDevLicense_requestDataDnc);
lr_output_message("----------iRet:%d, actDevLicense_requestDataDnc: %s----------",iRet,actDevLicense_requestDataDnc); //提取resCode
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,actDevLicense_requestDataDnc); //因为strtok会破坏源字符串,因此放在一个临时区域中
resCodeTmp = (char *)strstr(requestDataDnc_Tmp,resCodeTou);
if (NULL == resCodeTmp)
{
lr_error_message("resCodeTmp is NULL!");
//return -1;
goto START; }
resCodeTmp += strlen(resCodeTou);
resCodeTmp = (char *)strtok(resCodeTmp,delim);
resCode = atoi(resCodeTmp);
lr_output_message("----------resCode:%d----------",resCode); //判断响应的返回码是否正确,为100,如果不正确就退出!
if (!=resCode && !=resCode && !=resCode)
{
lr_error_message("resCode is not 100 !");
//return -1;
goto START;
} if ( == resCode)
{
goto DOWNLOADSTEP;
} //提取license文件信息中的产品名称
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,actDevLicense_requestDataDnc);
ProductNameTmp = (char *)strstr(requestDataDnc_Tmp,ProductNameTou);
if (NULL == ProductNameTmp)
{
lr_error_message("ProductNameTmp is NULL!");
//return -1;
goto START; }
ProductNameTmp += strlen(ProductNameTou);
ProductNameTmp = (char *)strtok(ProductNameTmp,ProductName_delim);
lr_output_message("Notify:ProductNameTmp:%s",ProductNameTmp); //提取license文件信息中的版本号
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
//strcpy(requestDataDnc_Tmp,getDevLicense_requestDataD); //jzq
strcpy(requestDataDnc_Tmp,actDevLicense_requestDataDnc);
VersionTmp = (char *)strstr(requestDataDnc_Tmp,VersionTou);
lr_output_message("actDevLicense_requestDataDnc:%s,requestDataDnc_Tmp:%s", actDevLicense_requestDataDnc,requestDataDnc_Tmp);
if (NULL == VersionTmp)
{
lr_error_message("VersionTmp is NULL!");
//return -1;
goto START; }
VersionTmp += strlen(VersionTou);
VersionTmp = (char *)strtok(VersionTmp,Version_delim);
lr_output_message("Notify:VersionTmp:%s",VersionTmp); //提取license文件信息中的ESN
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
//strcpy(requestDataDnc_Tmp,getDevLicense_requestDataDnc); //jzq
strcpy(requestDataDnc_Tmp,actDevLicense_requestDataDnc);
EsnTmp = (char *)strstr(requestDataDnc_Tmp,EsnTou);
if (NULL == EsnTmp)
{
lr_error_message("Esn is NULL!");
//return -1;
goto START; }
EsnTmp += strlen(EsnTou);
EsnTmp = (char *)strtok(EsnTmp,Esn_delim);
lr_output_message("Notify:EsnTmp:%s",EsnTmp); //数据校验....1.需要用到安全码;2.需要用到刚才请求的返回值。校验规则:"产品名称、版本号、ESN"三者是否跟最初一致?如果不一致就事务报错!!!
//校验产品名称
memcpy(ProductNameTmp_STR,ProductNameTmp,strlen(szPdtName));
strcmp_result = strcmp(szPdtName,ProductNameTmp_STR);
if ( != strcmp_result) {
lr_error_message("strcmp_result:%d ProductName is not same!!!",strcmp_result);
//return -1;
goto START;
} //校验版本
memcpy(VersionTmp_STR,VersionTmp,strlen(szPdtVer));
strcmp_result = strcmp(szPdtVer,VersionTmp_STR);
if ( != strcmp_result) {
lr_error_message("strcmp_result:%d Version is not same!!!",strcmp_result);
//return -1;
goto START;
} //校验Esn
memcpy(EsnTmp_STR,EsnTmp,strlen(szDevESN));
strcmp_result = strcmp(szDevESN,EsnTmp_STR);
if ( != strcmp_result) {
lr_error_message("strcmp_result:%d Esn is not same!!!",strcmp_result);
//return -1;
goto START;
} goto RELEASESESSIONSTEP; DOWNLOADSTEP:
//--------------------------------在线下载--------------------------------
//封装body
strcat(szDownLoadOnlineBody,szPdtName);
strcat(szDownLoadOnlineBody,"&prdVer=");
strcat(szDownLoadOnlineBody,szPdtVer);
strcat(szDownLoadOnlineBody,"&devEsn=");
strcat(szDownLoadOnlineBody,szDevESN);
strcat(szDownLoadOnlineBody,"&ordLac=");
strcat(szDownLoadOnlineBody,szOrdLac); //临时文件名生成
strcpy(TmpFileName,"D:\\dm\\sdp\\LicenseLog\\TmpFile\\TmpFile");
strcpy(vuserid_str,lr_eval_string("{vuserid_Param}"));
strcpy(curtime_str,lr_eval_string("{curtime_Param}"));
strcat(TmpFileName,vuserid_str);
strcat(TmpFileName,"_");
strcat(TmpFileName,curtime_str); //加密szDownLoadOnlineBody
iRet = Encrypt(,SecurityCodeTmp,szDownLoadOnlineBody,TmpFileName,szDownLoadOnlineBodyEnc);
lr_output_message("----------iRet:%d, szDownLoadOnlineBodyEnc: %----------s",iRet,szDownLoadOnlineBodyEnc); //放入参数中
lr_save_string(szDownLoadOnlineBodyEnc,"getDevLicenseBody_Param"); //设置能关联到得最大值
web_set_max_html_param_len(""); //关联data内容
web_reg_save_param_ex(
"ParamName=getDevLicense_requestData_Param",
"LB=data=",
"RB=",
SEARCH_FILTERS,
LAST); //关联Content-Length的值
web_reg_save_param_ex(
"ParamName=ContentLength_Param",
"LB=Content-Length: ",
"RB=\r\n",
SEARCH_FILTERS,
"Scope=HEADERS",
LAST); lr_start_transaction("DownloadOnline"); web_custom_request("web_custom_request",
"URL=http://{Param_serverIP}/LSP/device/licOnlineActivation.do;jsessionid={jsessionid_Param}?type=1",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTTP",
"BodyBinary={getDevLicenseBody_Param}",
LAST); lr_end_transaction("DownloadOnline", LR_AUTO); ContentLength = atoi(lr_eval_string("{ContentLength_Param}")) - strlen("type=0&data="); //解密data内容
memcpy(getDevLicense_requestData,lr_eval_string("{getDevLicense_requestData_Param}"),ContentLength);
iRet = Decrypt(,SecurityCodeTmp,getDevLicense_requestData,ContentLength,TmpFileName,getDevLicense_requestDataDnc);
lr_output_message("----------iRet:%d, getDevLicense_requestDataDnc: %s----------",iRet,getDevLicense_requestDataDnc); //提取resCode
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,getDevLicense_requestDataDnc);
resCodeTmp = (char *)strstr(requestDataDnc_Tmp,resCodeTou);
if (NULL == resCodeTmp)
{
lr_error_message("resCodeTmp is NULL!");
//return -1;
goto START; }
resCodeTmp += strlen(resCodeTou);
resCodeTmp = (char *)strtok(resCodeTmp,delim);
resCode = atoi(resCodeTmp);
lr_output_message("Notify:resCode:%d",resCode); //判断响应的返回码是否正确,为100,如果不正确就退出!
if (!=resCode && !=resCode)
{
//return -1;
goto START;
} //提取license文件信息中的产品名称
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,getDevLicense_requestDataDnc); //因为strtok会破坏源字符串,因此放在一个临时区域中
ProductNameTmp = (char *)strstr(requestDataDnc_Tmp,ProductNameTou);
if (NULL == ProductNameTmp)
{
lr_error_message("ProductNameTmp is NULL!");
//return -1;
goto START; }
ProductNameTmp += strlen(ProductNameTou);
ProductNameTmp = (char *)strtok(ProductNameTmp,ProductName_delim);
lr_output_message("----------ProductNameTmp:%s----------",ProductNameTmp); //提取license文件信息中的版本号
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,getDevLicense_requestDataDnc); //因为strtok会破坏源字符串,因此放在一个临时区域中
VersionTmp = (char *)strstr(requestDataDnc_Tmp,VersionTou);
if (NULL == VersionTmp)
{
lr_error_message("VersionTmp is NULL!");
//return -1;
goto START; }
VersionTmp += strlen(VersionTou);
VersionTmp = (char *)strtok(VersionTmp,Version_delim);
lr_output_message("----------VersionTmp:%s----------",VersionTmp); //提取license文件信息中的ESN
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,getDevLicense_requestDataDnc); //因为strtok会破坏源字符串,因此放在一个临时区域中
EsnTmp = (char *)strstr(requestDataDnc_Tmp,EsnTou);
if (NULL == EsnTmp)
{
lr_error_message("Esn is NULL!");
//return -1;
goto START; }
EsnTmp += strlen(EsnTou);
EsnTmp = (char *)strtok(EsnTmp,Esn_delim);
lr_output_message("----------EsnTmp:%s----------",EsnTmp); //数据校验....1.需要用到安全码;2.需要用到刚才请求的返回值。校验规则:"产品名称、版本号、ESN"三者是否跟最初一致?如果不一致就事务报错!!!
//校验产品名称
memcpy(ProductNameTmp_STR,ProductNameTmp,strlen(szPdtName));
strcmp_result = strcmp(szPdtName,ProductNameTmp_STR);
if ( != strcmp_result)
{
lr_error_message("strcmp_result:%d ProductName is not same!",strcmp_result);
//return -1;
goto START;
} //校验版本
memcpy(VersionTmp_STR,VersionTmp,strlen(szPdtVer));
strcmp_result = strcmp(szPdtVer,VersionTmp_STR);
if ( != strcmp_result)
{
lr_error_message("strcmp_result:%d Version is not same!",strcmp_result);
//return -1;
goto START;
} //校验Esn
memcpy(EsnTmp_STR,EsnTmp,strlen(szDevESN));
strcmp_result = strcmp(szDevESN,EsnTmp_STR);
if ( != strcmp_result)
{
lr_error_message("strcmp_result:%d Esn is not same!",strcmp_result);
//return -1;
goto START;
} RELEASESESSIONSTEP:
//--------------------------------释放会话资源--------------------------------
//封装body
strcpy(szJsessionid,lr_eval_string("{jsessionid_Param}"));
strcat(szReleaseSessionBody,szJsessionid); //加密szReleaseSessionBody
iRet = Encrypt(,"",szReleaseSessionBody,TmpFileName,szReleaseSessionBodyEnc);
lr_output_message("----------iRet:%d, szReleaseSessionBodyEnc: %s----------",iRet,szReleaseSessionBodyEnc); //放入参数中
lr_save_string(szReleaseSessionBodyEnc,"relSesRsrBody_Param"); //关联data内容
web_reg_save_param_ex(
"ParamName=relSesRsr_requestData_Param",
"LB=data=",
"RB=",
SEARCH_FILTERS,
LAST); //关联Content-Length的值
web_reg_save_param_ex(
"ParamName=ContentLength_Param",
"LB=Content-Length: ",
"RB=\r\n",
SEARCH_FILTERS,
"Scope=HEADERS",
LAST); lr_start_transaction("ReleaseSession"); web_custom_request("web_custom_request",
"URL=http://{Param_serverIP}/LSP/device/licOnlineActivation.do;jsessionid={jsessionid_Param}?type=0",
"Method=POST",
"TargetFrame=",
"Resource=0",
"Referer=",
"Mode=HTTP",
"BodyBinary={relSesRsrBody_Param}",
LAST); lr_end_transaction("ReleaseSession", LR_AUTO); ContentLength = atoi(lr_eval_string("{ContentLength_Param}")) - strlen("type=0&data="); //解密data内容
memcpy(relSesRsr_requestData,lr_eval_string("{relSesRsr_requestData_Param}"),ContentLength);
iRet = Decrypt(,"",relSesRsr_requestData,ContentLength,TmpFileName,relSesRsr_requestDataDnc);
lr_output_message("----------iRet:%d, relSesRsr_requestDataDnc: %s----------",iRet,relSesRsr_requestDataDnc); //提取resCode
memset(requestDataDnc_Tmp,'\0',sizeof(requestDataDnc_Tmp));
strcpy(requestDataDnc_Tmp,relSesRsr_requestDataDnc);
resCodeTmp = (char *)strstr(requestDataDnc_Tmp,resCodeTou);
if (NULL == resCodeTmp)
{
lr_error_message("resCodeTmp is NULL!");
//return -1;
goto START; }
resCodeTmp += strlen(resCodeTou);
resCodeTmp = (char *)strtok(resCodeTmp,delim);
resCode = atoi(resCodeTmp);
lr_output_message("----------resCode:%d----------",resCode); return ;
}
DLL源码
头文件dencdll.h:
_declspec(dllexport) int Encrypt(int iType, const char *szSecurityCode, const char *szOri, const char *szFileName, char *szRes); _declspec(dllexport) int Decrypt(int iType, const char *szSecurityCode, const unsigned char *szOri, int iOriLen, const char *szFileName, char *szRes);
源文件dencdll.c:
#include "dencdll.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h> /*
函数介绍:调用加密批处理命令进行加密操作,并将加密结果转换成十六进制的形式以供web_custom_request函数使用。(当没有安全码传入时使用enc0.bat进行加密,
如:enc0.bat enc 0 "string";当需要安全码传入时使用enc1.bat进行加密,如:enc1.bat enc 1 安全码 "string") 参数:iType--类型:0不传入安全码,1传入安全码; szSecurityCode--安全码; szOri--待加密的字符串; szFileName--临时文
件名(包含文件绝对路径); szRes--返回的密文串,调用者负责申请足够的内存 返回值:0--成功; 非0--失败
*/
int Encrypt(int iType, const char *szSecurityCode, const char *szOri, const char *szFileName, char *szRes)
{
char *szCommand = NULL;
FILE *pFile = NULL;
char szTmp1[];
char szTmp2[];
const char *szTmp3 = "cd C:\\dm\\sdp\\systemdll\\SdpEndecTest\\bin";
char szTmp4 = '\0';
int iLen = ;
int i = ;
char szResTmp[];
char curHexCode[]; memset(szTmp1,'\0',sizeof(szTmp1));
memset(szTmp2,'\0',sizeof(szTmp2));
memset(szResTmp,'\0',sizeof(szResTmp));
memset(curHexCode,'\0',sizeof(curHexCode)); //判断传入的参数是否齐全
if(NULL==szOri || NULL==szFileName || NULL==szRes)
{
return -;
} //判断是否需要传入安全码
if( == iType)
{
strcpy(szTmp1,"enc0.bat enc 0");
}
else if( == iType)
{
strcpy(szTmp1,"enc0.bat enc 1");
}
else
{
return -;
} //申请内存用于存放加密命令串
szCommand = (char *)malloc(strlen(szOri)+strlen(szTmp1)+strlen(szFileName)+);
if(NULL == szCommand)
{
return -;
}
sprintf(szCommand,"%s %s \"%s\" > %s",szTmp1,szSecurityCode,szOri,szFileName); //进入到加解密批处理命令执行目录下
system(szTmp3); //执行加密命令行,命令执行结果重定向到临时文件中
system(szCommand); //释放存放加密命令串的内存
free(szCommand); //读临时文件
pFile = fopen(szFileName,"r+");
if(NULL == pFile)
{
return -;
} while(!feof(pFile))
{
fread(szTmp2,sizeof(szTmp2)-,,pFile);
strcat(szResTmp,szTmp2);
memset(szTmp2,'\0',sizeof(szTmp2));
} //文件尾处理
iLen = strlen(szResTmp);
if((<iLen) && iscntrl(szResTmp[iLen-]))
{
szResTmp[iLen-] = '\0';
} //将字符流转换成十六进制形式
iLen = strlen(szResTmp);
for(i=; i<iLen; i+=)
{
memset(curHexCode,'\0',sizeof(curHexCode));
curHexCode[] = '\\';
curHexCode[] = 'x';
curHexCode[] = szResTmp[i];
curHexCode[] = szResTmp[i+];
strcat(szRes, curHexCode);
} //关闭文件
fclose(pFile);
pFile = NULL; return ;
} /*
函数介绍:调用解密批处理命令进行解密操作。(当没有安全码传入时使用dec0.bat进行解密;当需要安全码传入时使用dec1.bat进行解密) 参数:iType--类型:0不传入安全码,1传入安全码; szSecurityCode--安全码; szOri--待解密的密文串;iOriLen--密文串的长度;szFileName--临时文
件名(包含文件绝对路径); szRes--返回的解密后的字符串,调用者负责申请足够的内存 返回值:0--成功; 非0--失败
*/
int Decrypt(int iType, const char *szSecurityCode, const unsigned char *szOri, int iOriLen, const char *szFileName, char *szRes)
{
char *szCommand = NULL;
FILE *pFile = NULL;
char szTmp1[];
char szTmp2[];
int iLen = ;
int i = ;
char hexCodeString[];
char curHexCode[];
const char *szTmp3 = "cd C:\\dm\\sdp\\systemdll\\SdpEndecTest\\bin"; memset(szTmp1,'\0',sizeof(szTmp1));
memset(szTmp2,'\0',sizeof(szTmp2));
memset(curHexCode,'\0',sizeof(curHexCode));
memset(hexCodeString,'\0',sizeof(hexCodeString)); //将密文串格式化为十六进制形式
for (i=; i<iOriLen; i++)
{
sprintf(curHexCode, "%02X", szOri[i]);
strcat(hexCodeString, curHexCode);
memset(curHexCode,'\0',sizeof(curHexCode));
} //判断传入的参数是否齐全
if(NULL==szOri || NULL==szFileName || NULL==szRes)
{
return -;
} //判断是否需要传入安全码
if( == iType)
{
strcpy(szTmp1,"dec0.bat dec 0");
}
else if( == iType)
{
strcpy(szTmp1,"dec0.bat dec 1");
}
else
{
return -;
} //申请内存用于存放解密命令串
szCommand = (char *)malloc(strlen(hexCodeString)+strlen(szTmp1)+strlen(szFileName)+);
if(NULL == szCommand)
{
return -;
}
sprintf(szCommand,"%s %s \"%s\" > %s",szTmp1,szSecurityCode,hexCodeString,szFileName); //进入到加解密批处理命令执行目录下
system(szTmp3); //执行解密命令行,命令执行结果重定向到临时文件中
system(szCommand); //释放存放加密命令串的内存
free(szCommand); //读临时文件
pFile = fopen(szFileName,"r+");
if(NULL == pFile)
{
return -;
} while(!feof(pFile))
{
fread(szTmp2,sizeof(szTmp2)-,,pFile);
strcat(szRes,szTmp2);
memset(szTmp2,'\0',sizeof(szTmp2));
} //文件尾处理
iLen = strlen(szRes);
if((<iLen) && iscntrl(szRes[iLen-]))
{
szRes[iLen-] = '\0';
} //关闭文件
fclose(pFile);
pFile = NULL; return ;
}
基于LR的HTTP协议接口性能测试脚本实例的更多相关文章
- Loadrunner Webservice接口性能测试脚本编写优化总结
本文主要介绍使用Loadrunner Webservice接口性能测试脚本编写及优化总结. 1.Webservice协议脚本编写流程 下面介绍使用Loadrunner 11调用Webservice接口 ...
- JMeter之Http协议接口性能测试
一.不同角色眼中的接口 1.1,开发人员眼中的接口 1.2,测试人员眼中的接口 二.Http协议基本介绍 2.1,常见的接口协议 1.:2. :3. :4.:5.: 6. 2.2,Http协议栈 ...
- JMeter之Http协议接口性能测试--基础
一.不同角色眼中的接口 1.1,开发人员眼中的接口 1.2,测试人员眼中的接口 二.Http协议基本介绍 2.1,常见的接口协议 1.:2. :3. :4.:5.: 6. 2.2,Http协议栈 ...
- LR编写webservice协议接口
转自:http://lovesoo.org/use-loadrunner-call-webservice-interface-testing-optimization-summary.html 本文主 ...
- sockt-浅谈接口性能测试脚本编写
平时我们做的都是http请求的接口测试,初次接触socket接口还是有点不知如何下手,其实他如http接口请求区别并不是很大,也是接口的链接-发送数据-断开连接这三大步骤来实现: 以下文章转载自:ht ...
- LR中测试dubbo接口的脚本
import lrapi.lr;import com.alibaba.dubbo.config.ApplicationConfig;import com.alibaba.dubbo.config.Re ...
- 基于php的银行卡实名认证接口调用代码实例
银行卡二元素检测,检测输入的姓名.银行卡号是否一致. 银行卡实名认证接口:https://www.juhe.cn/docs/api/id/188 <?php // +-------------- ...
- 接口性能测试方案 白皮书 V1.0
一. 性能测试术语解释 1. 响应时间 响应时间即从应用系统发出请求开始,到客户端接收到最后一个字节数据为止所消耗的时间.响应时间按软件的特点再可以细分,如对于一个 C/S 软件的响应时间可以细分为网 ...
- 基于LR的Oracle应用性能测试
最近对一个oracle ERP系统的INV模块进行性能测试,因为之前大部分都是测试web类型的应用,在这方面经验较少,期间也遇到了不少问题,因此有必要作些总结,以备后忘.首先先简单了解下测试对象相关的 ...
随机推荐
- GDUT 校赛01 dp
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABT8AAAILCAIAAAChHn9YAAAgAElEQVR4nOy9f4il13nneUGgxrRYux ...
- poj 3468 成段增减
Sample Input 10 5 1 2 3 4 5 6 7 8 9 10 Q 4 4 Q 1 10 Q 2 4 C 3 6 3 Q 2 4 Sample Output 4 55 9 15 #inc ...
- 二分查找法 java
前几天去面试,让我写二分查找法,真是哔了狗! 提了离职申请,没事写写吧! 首先二分查找是在一堆有序的序列中找到指定的结果. public class Erfen { public static int ...
- Open Xml SDK 引文
什么是Open Xml SDK? 什么是Open Xml? 首先,我们得知道,Open Xml为何物? 我们还是给她起个名字——就叫 “开放Xml”,以方便我们中文的阅读习惯.之所以起开放这个名字,因 ...
- 关于InputStream.read()方法的阻塞原理的测试
最近在一家公司做java实习,写了个网络字节采集器.写了个单例TCPServer来采集数据,其中用到了InputStream.read()来读取数据.产生了一系列问题,下面做下总结: 关于while( ...
- Unity3d中SendMessage 用法简单笔记
Message相关有3条指令:SendMessage ("函数名",参数,SendMessageOptions) //GameObject自身的ScriptBroadcastMes ...
- 不容易系列之二[HDU2042]
不容易系列之二 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- 生成跨语言的类型声明和接口绑定的工具(Djinni )
Djinni 是一个用来生成跨语言的类型声明和接口绑定的工具,主要用于 C++ 和 Java 以及 Objective-C 间的互通. 示例接口定义文件: # Multi-line comments ...
- 【BZOJ】1090: [SCOI2003]字符串折叠(dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1090 随便yy一下.. 设f[i,j]表示i-j的最小长度 f[i, j]=min{j-i+1, f ...
- 解决EasyUI-Datagrid和LinqToEntity结合应用时排序问题
我们在做WEB页面时,时常会选择JQuery框架的Datagrid,如Ext.EasyUI.Flexigrid,数据访问则采用LinqToSQL或LinqToEntity.UI用Jquery框架的目的 ...