main.cpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include "httptest.hpp"
  14. void usage()
  15. {
  16. puts("Usage:");
  17. puts(" httptest [optins]");
  18. puts("Options:");
  19. puts(" -c: start as a client, which is the default");
  20. puts(" -s: start as a server");
  21. puts(" -x: start as a proxy");
  22. puts(" -r <times> : number of times for the client to send the request");
  23. puts(" -t <number-of-threads> : number of concurrent threads for the client to send the request");
  24. puts(" -i <filename> : input file name the client uses as request, or the server uses as response");
  25. puts(" -o <filename> : out file name");
  26. puts(" -url <[http|https]://[user:passwd@]host:port/path>: when starting as a client, the url to request");
  27. puts(" -soap: add soap http headers to the input text, must be used together with -url");
  28. puts(" -action <soap-action> ");
  29. puts(" -h <host> : hostname/ip the client connects to");
  30. puts(" -p <port> : port the client connects to, or the server listens on");
  31. puts(" -lp <port> : for proxy mode, local port that the proxy listens on");
  32. puts(" -ssl : tells it to use https instead of http");
  33. puts(" -delay <seconds>: when used as a client, delay several seconds before sending the request");
  34. puts(" -dr/-ds/-dc <seconds>: used in server mode, delay before receive, send, and close");
  35. puts(" -sc <ssl-cofig-file> : the config file that ssl uses");
  36. puts(" -d <trace-level> : 0 no tracing, > 5 some tracing, > 10 all tracing. Default is 20");
  37. puts("");
  38. puts("sample config-file: ");
  39. puts("<EspProtocol name=\"https\" type=\"secure_http_protocol\" plugin=\"esphttp.dll\">");
  40. puts(" <certificate>certificate.cer</certificate>");
  41. puts(" <privatekey>privatekey.cer</privatekey>");
  42. puts(" <passphrase>quOmuY55ftGrdcRi2y70eQ==</passphrase>");
  43. puts(" <verify enable=\"true\" address_match=\"true\" accept_selfsigned=\"true\">");
  44. puts(" <ca_certificates path=\"ca\"/>");
  45. puts(" <revoked_certificates path=\"revoked.pem\"/>");
  46. puts(" <trusted_peers>");
  47. puts(" <peer cn=\"texas.distrix.com\"/>");
  48. puts(" <peer cn=\"california.distrix.com\"/>");
  49. puts(" <peer cn=\"ymaxp\"/>");
  50. puts(" </trusted_peers>");
  51. puts(" </verify>");
  52. puts("</EspProtocol>");
  53. puts("");
  54. puts("Common use cases:");
  55. puts("-Http client to get a certain url:");
  56. puts(" httptest -c -url http://images.google.com/imghp?hl=en&tab=gi&q=");
  57. puts("-Read in the request from a file which contains the http headers and body:");
  58. puts(" httptest -c -h 10.150.51.27 -p 8010 -i spray.txt");
  59. puts("-Read in request body from a file, add soap headers, then send it:");
  60. puts(" httptest -c -url http://username:password@10.150.51.27:8010/FilSpray -action http://10.150.51.27:8010/FileSpray/Spray -i sprayxml.txt");
  61. puts("-Httpserver to display requests:");
  62. puts(" httptest -s -p 8080");
  63. puts("-Proxy to forward all incoming requests to a certain ip/port");
  64. puts(" httptest -x -lp 8010 -h 10.150.51.27 -p 8010");
  65. puts("-Fully functional proxy:");
  66. puts(" httptest -x -lp 8080");
  67. exit(-1);
  68. }
  69. enum InstanceType
  70. {
  71. IT_UNKNOWN = 0,
  72. HTTPSERVER = 1,
  73. HTTPCLIENT = 2,
  74. HTTPPROXY = 3
  75. };
  76. int main(int argc, char* argv[])
  77. {
  78. InitModuleObjects();
  79. InstanceType itype = IT_UNKNOWN;
  80. int times = 1;
  81. int threads = 1;
  82. StringBuffer in_fname;
  83. StringBuffer out_fname;
  84. StringBuffer host;
  85. int port = 80;
  86. int localport = 80;
  87. bool use_ssl = false;
  88. bool add_soap_headers = false;
  89. StringBuffer scfname;
  90. StringBuffer url;
  91. const char* soapaction = NULL;
  92. int delay = 0;
  93. int recvDelay = 0, sendDelay = 0, blockDelay = 0;
  94. int i = 1;
  95. while(i<argc)
  96. {
  97. if (stricmp(argv[i], "-s")==0)
  98. {
  99. itype = HTTPSERVER;
  100. i++;
  101. }
  102. else if (stricmp(argv[i], "-c")==0)
  103. {
  104. itype = HTTPCLIENT;
  105. i++;
  106. }
  107. else if (stricmp(argv[i], "-x")==0)
  108. {
  109. itype = HTTPPROXY;
  110. i++;
  111. }
  112. else if (stricmp(argv[i],"-r")==0)
  113. {
  114. i++;
  115. times = atoi(argv[i++]);
  116. }
  117. else if (stricmp(argv[i],"-t")==0)
  118. {
  119. i++;
  120. threads = atoi(argv[i++]);
  121. }
  122. else if (stricmp(argv[i], "-h")==0)
  123. {
  124. i++;
  125. host.clear().append(argv[i++]);
  126. }
  127. else if (stricmp(argv[i], "-p")==0)
  128. {
  129. i++;
  130. port = atoi(argv[i++]);
  131. }
  132. else if (stricmp(argv[i], "-i") == 0)
  133. {
  134. i++;
  135. in_fname.clear().append(argv[i++]);
  136. }
  137. else if (stricmp(argv[i], "-o") == 0)
  138. {
  139. i++;
  140. out_fname.clear().append(argv[i++]);
  141. }
  142. else if (stricmp(argv[i], "-ssl") == 0)
  143. {
  144. use_ssl = true;
  145. i++;
  146. }
  147. else if (stricmp(argv[i], "-sc") == 0)
  148. {
  149. i++;
  150. scfname.clear().append(argv[i++]);
  151. }
  152. else if (stricmp(argv[i], "-lp") == 0)
  153. {
  154. i++;
  155. localport = atoi(argv[i++]);
  156. }
  157. else if (stricmp(argv[i], "-delay") == 0)
  158. {
  159. i++;
  160. delay = atoi(argv[i++]);
  161. }
  162. else if (stricmp(argv[i], "-dr") == 0)
  163. {
  164. i++;
  165. recvDelay = atoi(argv[i++]);
  166. }
  167. else if (stricmp(argv[i], "-ds") == 0)
  168. {
  169. i++;
  170. sendDelay = atoi(argv[i++]);
  171. }
  172. else if (stricmp(argv[i], "-dc") == 0)
  173. {
  174. i++;
  175. blockDelay = atoi(argv[i++]);
  176. }
  177. else if(stricmp(argv[i], "-url") == 0)
  178. {
  179. i++;
  180. url.append(argv[i++]);
  181. }
  182. else if (stricmp(argv[i], "-soap")==0)
  183. {
  184. add_soap_headers = true;
  185. i++;
  186. }
  187. else if (stricmp(argv[i], "-action")==0)
  188. {
  189. i++;
  190. soapaction = argv[i++];
  191. }
  192. else if (stricmp(argv[i], "-d")==0)
  193. {
  194. i++;
  195. httptest_tracelevel = atoi(argv[i++]);;
  196. }
  197. else
  198. {
  199. printf("Error: command format error\n");
  200. usage();
  201. }
  202. }
  203. try
  204. {
  205. Owned<IPropertyTree> sslconfig;
  206. if(scfname.length() > 0)
  207. sslconfig.setown(createPTreeFromXMLFile(scfname.str(), ipt_caseInsensitive));
  208. FILE* ofile = NULL;
  209. if(out_fname.length() != 0)
  210. {
  211. ofile = fopen(out_fname.str(), "a+");
  212. if(ofile == NULL)
  213. {
  214. printf("can't open file %s\n", out_fname.str());
  215. exit(-1);
  216. }
  217. }
  218. else
  219. {
  220. ofile = stdout;
  221. }
  222. if(itype == HTTPSERVER)
  223. {
  224. HttpServer server(port, in_fname.str(), ofile, use_ssl, sslconfig.get());
  225. server.setDelays(recvDelay, sendDelay, blockDelay);
  226. server.start();
  227. }
  228. else if(itype == HTTPPROXY)
  229. {
  230. HttpProxy proxy(localport, host.str(), port, ofile, use_ssl, sslconfig.get());
  231. proxy.start();
  232. }
  233. else
  234. {
  235. if(add_soap_headers && url.length() == 0)
  236. {
  237. printf("Error: when you use -soap option, you must provide the full url\ntype in \"%s -h\" for usage", argv[0]);
  238. return 0;
  239. }
  240. if(host.length() == 0 && url.length() == 0)
  241. {
  242. printf("Error: destination host or url required\n");
  243. usage();
  244. }
  245. if(add_soap_headers)
  246. {
  247. HttpClient client(threads, times, ofile);
  248. if(delay > 0)
  249. client.setDelay(delay);
  250. client.sendSoapRequest(url.str(), soapaction, in_fname.str());
  251. }
  252. else if(url.length() == 0)
  253. {
  254. HttpClient client(threads, times, host.str(), port, ofile, use_ssl, sslconfig.get());
  255. if(delay > 0)
  256. client.setDelay(delay);
  257. client.sendRequest(in_fname.str());
  258. }
  259. else
  260. {
  261. HttpClient client(threads, times, ofile);
  262. if(delay > 0)
  263. client.setDelay(delay);
  264. client.getUrl(url.str());
  265. }
  266. }
  267. fclose(ofile);
  268. }
  269. catch(IException *excpt)
  270. {
  271. StringBuffer errMsg;
  272. DBGLOG("Error - %d:%s", excpt->errorCode(), excpt->errorMessage(errMsg).str());
  273. return -1;
  274. }
  275. catch(...)
  276. {
  277. DBGLOG("Unknown exception");
  278. return -1;
  279. }
  280. releaseAtoms();
  281. return 0;
  282. }