dca_interface  6.3.4
wac_samples/wacsample/main.cpp
1 /* IBM Source Code */
2 /* (C) Copyright IBM Corp. 2009, 2012 */
3 /* Licensed Materials - Property of IBM */
4 /* US Government Users Restricted Rights - Use duplication or disclosure restricted by GSA Schedule Contract with IBM Corp. */
5 
53 #include <string>
54 #include <vector>
55 #include <iostream>
56 #include <fstream>
57 #include <ctime>
58 
59 #ifdef WIN32
60 # include <winsock2.h>
61 #endif
62 
63 #include "dca/dca_base.h"
66 #include "dca/dca_callbacks.h"
67 
68 using namespace dca;
69 using namespace dca_wac;
70 
71 const std::string S_ToolName = "wacsample";
72 const std::string S_ToolVersion = "1.3";
73 
78 const std::string S_UsageString =
79  "<redist-folder> <ticket> <product> <input-file>\n"
80  " redist-folder - the folder where the DCA is installed to\n"
81  " ticket - a valid ticket\n"
82  " product - the product associated with your ticket\n\n"
83  " input-file - a file with sample input data in the following format:\n"
84  " 1st line: requestdata\n"
85  " 2nd line: URL\n"
86  " 3rd line: response\n"
87  " 4th line: requestdata...\n"
88  " Leave line blank if no request data URL or response data should be used\n"
89  " Note: At least one of the 3 lines must be non blank.\n"
90  " Note: A $(CR), $(LF) or $(CRLF) will be substituted with \\r, \\n and \\r\\n\n\n"
91  ;
92 
97 #ifdef WIN32
98 # define DCA_BINDIR "bin/Win32"
99 #else
100 # define DCA_BINDIR "bin/linux"
101 #endif
102 
107 #define DCA_INITDIR "init"
108 
112 #define DCA_LOGDIR "./logs"
113 
122 static void SetupInitData( const std::string& redist_folder, InitData& initData )
123 {
124  initData.binDir = redist_folder + DCA_BINDIR;
125  initData.initDir = redist_folder + DCA_INITDIR;
126  initData.logDir = DCA_LOGDIR;
127 }
128 
140 static bool StartupLibraries()
141 {
142 #ifdef WIN32
143  // Windows needs an extra socket-startup for this process to work
144  // correctly with e.g. IP(v6) input IP addresses
145  WORD wVersionRequested = MAKEWORD( 2, 2 );
146  WSADATA wsaData;
147  int err = WSAStartup( wVersionRequested, &wsaData );
148  if ( err != 0 ) {
149  std::cout << "Error on WSAStartup (" << err << ") occured, aborting" <<
150  std::endl;
151  return false;
152  }
153 #endif
154 
155  // init the 3rd party libraries
156  InitCUrl();
158  return true;
159 }
160 
167 static void ShutdownLibraries()
168 {
169  // deinit the 3rd party libraries
171  DeinitCUrl();
172 
173 #ifdef WIN32
174  // Cleanup Windows sockets for this process
175  WSACleanup();
176 #endif
177 }
178 
186 static void SetupLicense( const std::string& ticket, const std::string& product,
187  LicenseData& licenseData )
188 {
189  licenseData.ticket = ticket;
190  licenseData.product = product;
191 }
192 
199 static void SetupWacConnectionData( DbConnectionData& cData )
200 {
201  cData.useLocalDatabase = true;
202  cData.dbType = DBT_Wac;
203 }
204 
211 static void SetupUrlConnectionData( DbConnectionData& cData )
212 {
213  cData.useLocalDatabase = true;
214  cData.dbType = DBT_Url;
215 }
216 
222 static void PrintDbConnectionInfo( const DbConnection& aDbConnection )
223 {
224  DatabaseInformation databaseInformation =
225  aDbConnection.getDatabaseInformation();
226 
227  std::cout << "WAC Database Version: " << databaseInformation.versionString
228  << " as of " << databaseInformation.creationDateUTC << std::endl;
229 }
230 
231 
237 static void PrintLicenseInfo( const License& aLicense )
238 {
239  const time_t expirationDate = aLicense.getExpirationDate();
240  struct tm *expirationTime = localtime( &expirationDate );
241 
242  std::cout << "License Info:" << std::endl;
243  std::cout << " DCA is " << ( aLicense.isLicensed() ? "licensed." :
244  "not licensed." ) << std::endl;
245  std::cout << " MaxUsers:" << aLicense.getMaxUsers() <<
246  std::endl;
247  std::cout << " MaxSessions:" << aLicense.getMaxSessions() <<
248  std::endl;
249  std::cout << " Ticket:" << aLicense.getTicket() <<
250  std::endl;
251  std::cout << " Session:" << aLicense.getSession() <<
252  std::endl;
253  std::cout << " Last Message:" << aLicense.getLastMessage() <<
254  std::endl;
255  std::cout << " Expiration Date:" << asctime( expirationTime ) <<
256  std::endl;
257 }
258 
263 static void PrintToolHeader()
264 {
265  std::cout << "IBM DCA Sample: " << S_ToolName << " (" << S_ToolVersion << ")" << std::endl;
266 }
267 
273 static void PrintUsage( const char *name )
274 {
275  std::cout << name << " usage:" << std::endl;
276  std::cout << S_UsageString << std::endl;
277 }
278 
285 void PrintResults( const WacClassificationResult& aWacClassificationResult, const WacCategoriesInfo& aCategoriesInfo )
286 {
287  if( aWacClassificationResult == NullWacClassificationResult ) {
288  std::cout << "No results returned for the given request data" << std::endl;
289  }
290  else {
291 
292  std::cout << "Result from WAC Classification:" << std::endl;
293  DCA_APPLICATION_ID_TYPE appId = aWacClassificationResult.applicationId();
294  if( appId >= 0 ) {
295  std::cout << "Returned Application name=" <<
296  aCategoriesInfo.getApplications().byId( appId ).name() << std::endl;
297  }
298 
299  DCA_ACTION_ID_TYPE actionId = aWacClassificationResult.actionId();
300  if( actionId >= 0 ) {
301  std::cout << "Returned Action name=" <<
302  aCategoriesInfo.getActions().byId( actionId ).name() << std::endl;
303  }
304  }
305 }
306 
315 void DoCallWacClassification( const WacClassifier& aWacClassifier, const WacInputData& aWacInputData,
316  WacClassificationResult& aWacClassificationResult )
317 {
318  FunctionResult myFR = aWacClassifier.classify( aWacInputData, aWacClassificationResult );
319  if( !myFR ) {
320  std::cout << "Error returned from WAC Classification call. RC=" << myFR.getReturnCode() <<
321  ", Details:" << myFR.getDescription() << std::endl;
322  }
323 }
324 
329 void SubstituteCRLF( std::string& s )
330 {
331  if( s.empty() )
332  return;
333 
334  {
335  const std::string subst = "$(CR)";
336  const std::string newst = "\r";
337  size_t substlen = subst.length();
338  size_t newstlen = newst.length();
339  std::string::size_type i = 0, pos = 0;
340  while( ( i = s.find( subst, pos ) ) != std::string::npos ) {
341  s.replace( i, substlen, newst );
342  pos = i + newstlen;
343  }
344  }
345  {
346  const std::string subst = "$(LF)";
347  const std::string newst = "\n";
348  size_t substlen = subst.length();
349  size_t newstlen = newst.length();
350  std::string::size_type i = 0, pos = 0;
351  while( ( i = s.find( subst, pos ) ) != std::string::npos ) {
352  s.replace( i, substlen, newst );
353  pos = i + newstlen;
354  }
355  }
356  {
357  const std::string subst = "$(CRLF)";
358  const std::string newst = "\r\n";
359  size_t substlen = subst.length();
360  size_t newstlen = newst.length();
361  std::string::size_type i = 0, pos = 0;
362  while( ( i = s.find( subst, pos ) ) != std::string::npos ) {
363  s.replace( i, substlen, newst );
364  pos = i + newstlen;
365  }
366  }
367 }
368 
381 void TestWacClassification( const dca::DcaInstance& aDcaInstance,
382  const dca::UrlDbClassifier& aUrlClassifier,
383  const WacClassification& aWacClassification,
384  const WacClassifier& aWacClassifier,
385  const WacCategoriesInfo& aCategoriesInfo,
386  const std::string& aFile )
387 {
388  std::ifstream fstream( aFile.c_str(), std::ios::in );
389  if ( !fstream.is_open() ) return;
390 
391  std::string line;
392 
393  int i = 0;
394 
395  while ( std::getline(fstream, line) )
396  {
397  ++i;
398  if( line.empty() )
399  continue;
400 
401  while( line[line.length()-1] == '\r' || line[line.length()-1] == '\n' )
402  line.erase( line.length() - 1 );
403 
404  std::string requestLine = line;
405 
406  if( !std::getline(fstream, line) ) {
407  break;
408  }
409  std::string urlLine = line;
410 
411  if( !std::getline(fstream, line) ) {
412  break;
413  }
414  std::string responseLine = line;
415 
416  if( requestLine.empty() &&
417  urlLine.empty() &&
418  responseLine.empty() )
419  continue; // nothing specified?
420 
421  WacInputData myInputData;
422 
423  dca::UrlClassificationResults myUrlResults;
424 
425  if( !urlLine.empty() ) {
426  // invoke URL classification and check whether WAC Details are available
427  // of not suppress WAC classification calls
428 
429  dca::Url myUrl = dca::Url::create( aDcaInstance, urlLine );
430  FunctionResult myFR = aUrlClassifier.classify( myUrl, myUrlResults );
431  if( ! myFR ) {
432  std::cout << "Retrieved error on UrlClassification call rc=" <<
433  myFR.getReturnCode() << ", details=" << myFR.getDescription() <<
434  std::endl;
435  continue; // process next entry
436  }
437  if( !aWacClassification.wacDetailsAvailable( myUrlResults ) ) {
438  std::cout << "Given URL '" << urlLine << "' has no WAC related results available so continue with next entry"
439  << std::endl;
440  continue;
441  }
442 
443  myInputData.setUrlObject( myUrl );
444  }
445 
446  if( !requestLine.empty() ) {
447  SubstituteCRLF( requestLine );
448  myInputData.setRequestData( requestLine.c_str(), requestLine.length() );
449  }
450 
451  if ( !responseLine.empty() ) {
452  SubstituteCRLF( responseLine );
453  myInputData.setResponse( responseLine.c_str(), responseLine.length() );
454  }
455 
456  std::cout << "Starting WAC Classification #" << i <<
457  " (URL='" << urlLine << "', request length=" << requestLine.length() <<
458  ", response length=" << responseLine.length() <<
459  ")" << std::endl;
460 
461  WacClassificationResult myWacClassificationResult;
462 
463  DoCallWacClassification( aWacClassifier, myInputData, myWacClassificationResult );
464 
465  PrintResults( myWacClassificationResult, aCategoriesInfo );
466  std::cout << std::endl;
467  }
468 }
469 
477 int main( int argc, char *argv[] )
478 {
479  PrintToolHeader();
480 
481  int rc = 5;
482 
483  try {
484  if( argc < 5 ) {
485  PrintUsage( argv[0] );
486  return 5;
487  }
488 
489  std::string myRedistFolder = argv[ 1 ];
490  const std::string myTicket = argv[ 2 ];
491  const std::string myProduct = argv[ 3 ];
492  const std::string myFile = argv[ 4 ];
493 
494  if( myRedistFolder.empty() || myTicket.empty() ||
495  myProduct.empty() || myFile.empty() ) {
496  PrintUsage( argv[0] );
497  return 5;
498  }
499 
500  // check for trailing fileslash - and add if necessary
501  const char c = myRedistFolder[ myRedistFolder.length() - 1 ];
502  if( c != '/' && c != '\\' )
503  myRedistFolder += "/";
504 
505  // Initialize socket on Windows and 3rd party libraries
506  if( !StartupLibraries() )
507  return 5;
508 
509  {
510  // setup DCA directories
511  InitData myInitData;
512  SetupInitData( myRedistFolder, myInitData );
513 
514  // instantiate DCA API
515  DcaInstance myDca;
516  myDca = DcaInstance::create( myInitData );
517 
518  // setup license data
519  LicenseData myLicenseData;
520  SetupLicense( myTicket, myProduct, myLicenseData );
521  const License myLicense = myDca.createLicense( myLicenseData );
522 
523  PrintLicenseInfo( myLicense );
524 
525  if( myLicense.isLicensed( WacClassification::ID ) ) {
526  // variables necessary for the call to TestWacClassification()
527  WacClassification myWacClassification;
528  WacClassifier myWacClassifier;
529  WacCategoriesInfo myWacCategoriesInfo;
530 
531  { // create a WacClassifier & WacCategoriesInfo
532  DbConnectionData myWacConnectionData;
533  SetupWacConnectionData( myWacConnectionData );
534 
535  // A DbConnection data to a local database must exist to use WacClassification
536  const DbConnection myDbConnection = myDca.createDbConnection( myLicense, myWacConnectionData );
537 
538  std::cout << "WAC ";
539  PrintDbConnectionInfo( myDbConnection );
540 
541  // initialize the WAC Classification module
542  myWacClassification = WacClassification::create( myDca, myLicense );
543 
544  // create a WacClassifier to use in the TestWacClassification() function
545  // (statistics upload disabled)
546  WacClassifierOptions myWacClassifierOptions;
547  myWacClassifierOptions.enable_Feedback = false;
548 
549  myWacClassifier = myWacClassification.createClassifier( myDbConnection, myWacClassifierOptions );
550 
551  // create a categories info for printing out the result application and action as string per input data
552  myWacCategoriesInfo = myWacClassification.getCategoriesInfo();
553  }
554 
555  UrlDbClassifier myUrlClassifier;
556  { // create a UrlDbClassifier
557  DbConnectionData myUrlConnectionData;
558  SetupUrlConnectionData( myUrlConnectionData );
559 
560  const DbConnection myUrlConnection = myDca.createDbConnection( myLicense, myUrlConnectionData );
561  std::cout << "URL ";
562  PrintDbConnectionInfo( myUrlConnection );
563 
564  // initialize the URL Classification module
565  const UrlClassification myUrlClassification = UrlClassification::create( myDca, myLicense );
566 
567  // (embedded URL detection enabled, statistics and unknown url upload disabled)
568  UrlDbClassifierOptions myUrlDbClassifierOptions;
569  myUrlDbClassifierOptions.enable_EmbeddedUrlDetection = true;
570  myUrlDbClassifierOptions.detect_EmbeddedUrlsInUrlPath = true;
571  myUrlDbClassifierOptions.enable_Feedback = false;
572 
573  myUrlClassifier = myUrlClassification.createDbClassifier( myUrlConnection, myUrlDbClassifierOptions );
574  }
575 
576  // call classification routine
577  TestWacClassification( myDca, myUrlClassifier, myWacClassification,
578  myWacClassifier, myWacCategoriesInfo, myFile );
579 
580  rc = 0;
581  }
582  }
583  }
584  catch( const ExDca& ex ) {
585  std::cerr << "DCA Exception occured. Details: " << ex.getDescription() <<
586  " (" << ex.getReturnCode() << ")." << std::endl;
587  rc = 10;
588  }
589  catch( const std::exception& s ) {
590  std::cerr << "std::exception occured. Details: " << s.what() << "." << std::endl;
591  rc = 10;
592  }
593  catch(...) {
594  std::cerr << "Unknown exception caught." << std::endl;
595  rc = 10;
596  }
597 
598  // deinit the 3rd party libraries
599  ShutdownLibraries();
600 
601  return rc;
602 }
603 
604 
605 
bool enable_Feedback
This switches the Feedback feature on or off. This feature collects number of matched applications/ac...
WacAction byId(DCA_ACTION_ID_TYPE actionId) const
Returns the action with the given action id.
Is used to create a License object. A license first must be created with DcaInstance::createLicense t...
Definition: base_classes.h:547
Exception class used in the DCA.
Definition: base_classes.h:237
static Url create(const DcaInstance &aDcaInstance, const std::string &urlString)
Standard Url creation function.
const WacClassificationResult NullWacClassificationResult
Defines a constant unassigned WacClassificationResult you can use for checks. if ( myWacClassificatio...
void InitCUrl()
Initializes libcurl. Do not use any DCA function before initializing libcurl.
std::string initDir
the directory in which the DCA init files are stored
Definition: base_classes.h:266
std::string name(const std::string &localeString=std::string()) const
Returns the localized (display) name of the application.
int DCA_ACTION_ID_TYPE
Type for action ids.
Definition: base_types.h:42
bool wacDetailsAvailable(const dca::UrlClassificationResults &res) const
Returns whether or not a subsequent WAC classification may provide useful WAC information....
int getMaxSessions() const
Returns the maximum allowed sessions associated with your ticket/license.
time_t getExpirationDate() const
Returns the expiration date of the license in UTC.
std::string getDescription() const
Returns a description of the error.
Definition of the WacClassificationResult class.
DatabaseInformation getDatabaseInformation() const
Returns information about the underlying database.
Contains information about underlying database.
Definition: base_classes.h:834
DCA_RESULT_TYPE getReturnCode() const
Returns the last error code (if any).
FunctionResult classify(const Url &aUrl, UrlClassificationResults &urlResults) const
Performs the URL classification and returns the results.
static void SetupInitData(const std::string &redist_folder, InitData &initData)
Sets up the given initData by substituting the given redist_folder with DCA subdirectories.
std::string creationDateUTC
Definition: base_classes.h:842
DCA_ACTION_ID_TYPE actionId() const
If the classification was successful this is the matched action.
void setRequestData(const char *data, size_t data_length)
Sets up the buffer containing the (HTTP) request. This is assumed to contain US ASCII 7-Bit character...
std::string binDir
the directory in which the DCA binary (*.dca) files are stored
Definition: base_classes.h:265
This header includes initialization/deinitialization support functions for the 3rd party libraries us...
Sets up options for embedded URL detection and provided Feedback mechanism.
void SetOpenSslCallbacks()
Initializes the required callbacks for OpenSSL when using HTTPS or SSL connections in a multi-threade...
Definition of the WacInputData class.
Definition: wac_inputdata.h:49
Stores the connection data for a database.
Definition: base_classes.h:815
void UnsetOpenSslCallbacks()
Unsets the openssl callbacks. Do not call any DCA function after you have called this function.
int getMaxUsers() const
Returns the maximum allowed users associated with your ticket/license.
void DeinitCUrl()
Deinitializes libcurl. Do not call any DCA function after you have called this function.
Database connection class for a local or remote database.
Definition: base_classes.h:859
WacCategoriesInfo getCategoriesInfo() const
Retrieve the WacCategoriesInfo class.
This header includes all header files of the URL Classification Package.
#define DCA_LOGDIR
Relative directory for logfile(s).
Main class for the URL classification.
Package header file for the WAC (Web Application Classification) Package.
#define DCA_INITDIR
DCA subdirectory of the DCA initialization data.
dca::FunctionResult classify(const WacInputData &input, WacClassificationResult &result) const
Classification function that takes the given input and return its results (if any) in the provided re...
bool enable_Feedback
This switches the Feedback feature on or off. This is switched off by default.
DCA_RESULT_TYPE getReturnCode() const
Gets the code of the error.
Defintion of the WacClassifier class.
std::string name(const std::string &localeString=std::string()) const
Returns the localized (display) name of the action.
Results of an URL classification.
bool detect_EmbeddedUrlsInUrlPath
If set to true, you can specify that embedded URL detection is additionally performed in the path par...
URL database classifier class.
static void PrintToolHeader()
Prints out the name and the version of this sample.
Defintion of the WacClassification class.
Use a License to initialize a classification package or a toolbox package.
Definition: base_classes.h:560
WacActions getActions() const
Returns the contained WacActions.
const DbType DBT_Wac
Used for dca::DbConnection classes for Web Application Classification databases.
Container class for all WAC enumeration objects.
bool isLicensed(DCA_MODULE_ID_TYPE id=0, bool force=false) const
Checks whether the given License is valid for the given module id.
static void PrintLicenseInfo(const License &aLicense)
Prints out the information about the provided License.
std::string ticket
The ticket as provided in the license.
Definition: base_classes.h:548
This header includes all header files of the DCA Base Package.
std::string versionString
Definition: base_classes.h:840
bool useLocalDatabase
Set to true to connect to a local or custom database, set to false to use a remote database.
Definition: base_classes.h:821
Encapsulates the init and deinit of the DCA API.
Definition: base_classes.h:315
std::string product
The product code used with the license.
Definition: base_classes.h:549
const DbType DBT_Url
Used for DbConnection classes for URL classification.
WacClassifier createClassifier(const dca::DbConnection &aDbConnection, const WacClassifierOptions &aWacClassifierOptions=WacClassifierOptions()) const
Creates a WacClassifier that is used to classify WacInputData objects.
static UrlClassification create(const DcaInstance &aDcaInstance, const License &aLicense)
Creates the URL classification module by using the given DcaInstance and License.
std::string logDir
the directory in which the DCA log file should be created
Definition: base_classes.h:267
WacApplications getApplications() const
Returns the contained WacApplications.
void setUrlObject(const dca::Url &aUrl)
Sets up the Input Data object by using the given dca::Url object.
static void PrintUsage(const char *name)
Prints out the syntax of the sample.
std::string getLastMessage() const
Returns the last message received from our license server or if none available the last available mes...
void setResponse(const char *data, size_t data_length)
Sets up the buffer containing the (HTTP) response. This is assumed to contain US ASCII 7-Bit characte...
DbType dbType
The type of the database.
Definition: base_classes.h:820
std::string getDescription() const
Returns the description for the error or warning.
int DCA_APPLICATION_ID_TYPE
Type for application ids.
Definition: base_types.h:48
WacApplication byId(DCA_APPLICATION_ID_TYPE appid) const
Returns the application with the given application id.
Sets up options for the WAC classification.
std::string getTicket() const
Returns the ticket of the license as string.
bool enable_EmbeddedUrlDetection
If set to true embedded URL detection will be used in URL classification. This is switched on by defa...
#define DCA_BINDIR
DCA subdirectory of the DCA binaries.
Standard function result.
Definition: base_classes.h:148
std::string getSession() const
Returns the session of the license as string.
Encapsulates a URL object.
Definition: base_url.h:44
DCA_APPLICATION_ID_TYPE applicationId() const
If the classification was successful this is the matched application.
UrlDbClassifier createDbClassifier(const DbConnection &aDbConnection, const UrlDbClassifierOptions &options=UrlDbClassifierOptions()) const
Create a URL database classifier. The classifier is created by using the provided database connection...
const std::string S_UsageString
Usage string, displayed if a parameter is missing.
DbConnection createDbConnection(const License &aLicense, const DbConnectionData &dbcData, const ProxySettings &proxySettings=ProxySettings(), LogLevel aLogLevel=LOG_Initial) const
Creates a DbConnection object using the given DbConnectionData.
This structure is used to initialize the DcaInstance.
Definition: base_classes.h:264
static DcaInstance create(const InitData &initData)
Creates a DcaInstance, starts up the DCA API and initializes the required main module.
static void SetupLicense(const std::string &ticket, const std::string &product, LicenseData &licenseData)
Sets up the given licenseData by copying the given ticket and product strings.
License createLicense(const LicenseData &licData, const ProxySettings &proxySettings=ProxySettings(), LogLevel aLogLevel=LOG_Initial) const
Creates a License object using the given LicenseData.
int main(int argc, char *argv[])
The main routine.