PageRenderTime 30ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Units/MMLAddon/internets.pas

http://github.com/moparisthebest/Simba
Pascal | 447 lines | 387 code | 50 blank | 10 comment | 37 complexity | c0bd8e2c4bf967860902b689b075b786 MD5 | raw file
Possible License(s): GPL-3.0
  1. unit internets;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, httpsend, blcksock, MufasaTypes, math, ssl_openssl;
  6. function GetPage(URL: String): String;
  7. type
  8. { THTTPClient }
  9. THTTPClient = class(TObject)
  10. private
  11. HTTPSend : THTTPSend;
  12. fHandleCookies : boolean;
  13. PostVariables : TStringList;
  14. Client : TObject;
  15. public
  16. OpenConnectionEvent : TOpenConnectionEvent;
  17. procedure SetHTTPUserAgent(agent : string);
  18. function GetHTTPPage(url : string ) : string;
  19. function PostHTTPPage(Url: string; PostData: string): string;overload;
  20. function PostHTTPPage(Url: string): string;overload;
  21. function GetRawHeaders: string;
  22. procedure ClearPostData;
  23. procedure AddPostVariable(VarName, VarValue: string);
  24. procedure SetProxy(pHost, pPort : String);
  25. constructor Create(Owner : TObject; HandleCookies : boolean = true);
  26. destructor Destroy;override;
  27. end;
  28. { TMInternet }
  29. TMInternet = class(TObject)
  30. protected
  31. Client : TObject;
  32. Connections : TList;
  33. HTTPClients : TList;
  34. public
  35. OpenConnectionEvent : TOpenConnectionEvent;
  36. function GetPage(URL: String): String;
  37. function CreateHTTPClient(HandleCookies : boolean = true) : integer;
  38. function GetHTTPClient(Index : integer) : THTTPClient;
  39. procedure FreeHTTPClient(Index: Integer);
  40. constructor Create(Owner : TObject);
  41. destructor Destroy;override;
  42. end;
  43. { TSock }
  44. TSock = class(TObject)
  45. private
  46. Sock: TTCPBlockSocket;
  47. Timeout: integer;
  48. Client: TObject;
  49. public
  50. function RecvBufferStr(Length: integer): string;
  51. function RecvString: string;
  52. function Recv: string;
  53. procedure Send(Data: string);
  54. procedure Connect(IP, Port: string);
  55. procedure Close;
  56. procedure SetTimeout(Time: integer);
  57. procedure Bind(IP, Port: string);
  58. procedure Listen;
  59. function Accept: TTCPBlockSocket;
  60. procedure Info(out IP, Port: string);
  61. constructor Create(Owner: TObject; Socket: TTCPBlockSocket = nil);
  62. destructor Destroy; override;
  63. end;
  64. { TSocks }
  65. TSocks = class(TObject)
  66. protected
  67. Client: TObject;
  68. SockList: TList;
  69. public
  70. function CreateSocket: integer;
  71. function CreateSocketEx(Socket: TTCPBlockSocket): integer;
  72. function GetSocket(Index: integer): TSock;
  73. procedure FreeSocket(Index: integer);
  74. constructor Create(Owner : TObject);
  75. destructor Destroy; override;
  76. end;
  77. var
  78. ProxyHost, ProxyPort : String;
  79. implementation
  80. uses
  81. Client;
  82. { OTHER }
  83. function GetPage(URL: String): String;
  84. var
  85. HTTP : THTTPSend;
  86. begin;
  87. HTTP := THTTPSend.Create;
  88. Result := '';
  89. try
  90. if HTTP.HTTPMethod('GET', URL) then
  91. begin
  92. SetLength(result,HTTP.Document.Size);
  93. HTTP.Document.Read(result[1],length(result));
  94. end;
  95. finally
  96. HTTP.Free;
  97. end;
  98. end;
  99. function TMInternet.GetPage(URL: String): String;
  100. var
  101. Continue : boolean = true;
  102. begin
  103. Result := '';
  104. if Assigned(OpenConnectionEvent) then
  105. begin;
  106. OpenConnectionEvent(Self,url,continue);
  107. if not Continue then
  108. exit;
  109. end;
  110. Result := Internets.GetPage(url);
  111. end;
  112. { TMInternet }
  113. function TMInternet.CreateHTTPClient(HandleCookies: boolean = true): integer;
  114. begin;
  115. Result := HTTPClients.Add(THTTPClient.Create(Client,HandleCookies));
  116. THttpClient(HTTPClients[result]).OpenConnectionEvent:= OpenConnectionEvent;
  117. end;
  118. function TMInternet.GetHTTPClient(Index: integer): THTTPClient;
  119. begin
  120. if (index < 0) or (index >= HTTPClients.Count) then
  121. raise exception.CreateFmt('GetHTTPClient: Trying to acces an index(%d) that is out of range',[index]);
  122. if HTTPClients[index] = nil then
  123. raise exception.CreateFmt('GetHTTPClient: Trying to acces an index(%d) that is freed',[index]);
  124. result := THTTPClient(httpclients[index]);
  125. end;
  126. procedure TMInternet.FreeHTTPClient(Index: Integer);
  127. begin
  128. if (index < 0) or (index >= HTTPClients.Count) then
  129. raise exception.CreateFmt('FreeHTTPClient: Trying to free an index(%d) that is out of range',[index]);
  130. if HTTPClients[index] = nil then
  131. raise exception.CreateFmt('FreeHTTPClient: Trying to free an index(%d) that is already freed',[index]);
  132. THTTPClient(HTTPClients[index]).Free;
  133. HTTPClients[index] := nil;
  134. end;
  135. constructor TMInternet.Create(Owner: TObject);
  136. begin
  137. inherited Create;
  138. client := Owner;
  139. Connections := TList.Create;
  140. HTTPClients := TList.Create;
  141. end;
  142. destructor TMInternet.Destroy;
  143. var
  144. i : integer;
  145. begin
  146. for i := Connections.Count -1 downto 0 do
  147. if Connections[i] <> nil then
  148. begin
  149. TObject(Connections[i]).Free;
  150. TClient(Client).Writeln(Format('Connection[%d] has not been freed in the script, freeing it now.',[i]));
  151. end;
  152. for i := HTTPClients.Count -1 downto 0 do
  153. if HTTPClients[i] <> nil then
  154. begin
  155. THTTPClient(HTTPClients[i]).Free;
  156. TClient(Client).Writeln(Format('HTTPClient[%d] has not been freed in the script, freeing it now.',[i]));
  157. end;
  158. Connections.Free;
  159. HTTPClients.Free;
  160. inherited Destroy;
  161. end;
  162. { THTTPClient }
  163. procedure THTTPClient.SetHTTPUserAgent(agent: string);
  164. begin
  165. HTTPSend.UserAgent := agent;
  166. end;
  167. function THTTPClient.GetHTTPPage(url: string): string;
  168. var
  169. Continue : boolean = true;
  170. begin
  171. Result := '';
  172. if Assigned(OpenConnectionEvent) then
  173. begin;
  174. OpenConnectionEvent(Self,url,continue);
  175. if not Continue then
  176. exit;
  177. end;
  178. if not fHandleCookies then
  179. HTTPSend.Cookies.Clear;
  180. if (ProxyHost <> '') and (ProxyPort <> '') then
  181. begin
  182. HTTPSend.ProxyHost := ProxyHost;
  183. HTTPSend.ProxyPort := ProxyPort;
  184. end;
  185. HTTPSend.MimeType := 'text/html';
  186. try
  187. if HTTPSend.HTTPMethod('GET',url) then
  188. begin;
  189. SetLength(result,HTTPSend.Document.Size);
  190. HTTPSend.Document.Read(result[1],length(result));
  191. end else
  192. result := '';
  193. except
  194. on e : exception do
  195. TClient(Client).Writeln('THTTPClient error: ' + e.message);
  196. end;
  197. end;
  198. function THTTPClient.PostHTTPPage(Url: string; PostData: string): string;
  199. begin
  200. if (ProxyHost <> '') and (ProxyPort <> '') then
  201. begin
  202. HTTPSend.ProxyHost := ProxyHost;
  203. HTTPSend.ProxyPort := ProxyPort;
  204. end;
  205. HTTPSend.MimeType := 'application/x-www-form-urlencoded';
  206. HTTPSend.Document.Clear;
  207. HTTPSend.Document.Write(Postdata[1],length(postdata));
  208. try
  209. if HTTPSend.HTTPMethod('POST',url) then
  210. begin;
  211. SetLength(result,HTTPSend.Document.Size);
  212. HTTPSend.Document.Read(result[1],Length(result));
  213. end else
  214. result := '';
  215. except
  216. on e : exception do
  217. TClient(Client).Writeln('THTTPClient error: ' + e.message);
  218. end;
  219. end;
  220. function THTTPClient.PostHTTPPage(Url: string): string;
  221. var
  222. PostData : string;
  223. i : integer;
  224. Continue : boolean = true;
  225. begin
  226. Result := '';
  227. if Assigned(OpenConnectionEvent) then
  228. begin;
  229. OpenConnectionEvent(Self,url,continue);
  230. if not Continue then
  231. exit;
  232. end;
  233. PostData := '';
  234. for i := 0 to PostVariables.Count - 1 do
  235. PostData := PostData + PostVariables[i] +'&';
  236. if Length(PostData) > 1 then
  237. setlength(postdata,length(postdata) - 1); //Wipe away that last &
  238. result := PostHTTPPage(url,postdata);
  239. end;
  240. function THTTPClient.GetRawHeaders: string;
  241. begin
  242. Result := HTTPSend.Headers.Text;
  243. end;
  244. procedure THTTPClient.ClearPostData;
  245. begin
  246. PostVariables.Clear;
  247. end;
  248. procedure THTTPClient.AddPostVariable(VarName, VarValue: string);
  249. begin
  250. PostVariables.Add(Varname + '=' + VarValue);
  251. end;
  252. procedure THTTPClient.SetProxy(pHost, pPort : String);
  253. begin
  254. ProxyHost := pHost;
  255. ProxyPort := pPort;
  256. end;
  257. constructor THTTPClient.Create(Owner : TObject; HandleCookies : boolean = true);
  258. begin
  259. inherited Create;
  260. Client := Owner;
  261. HTTPSend := THTTPSend.Create;
  262. fHandleCookies:= HandleCookies;
  263. PostVariables := TStringList.Create;
  264. end;
  265. destructor THTTPClient.Destroy;
  266. begin
  267. HTTPSend.Free;
  268. PostVariables.Free;
  269. inherited Destroy;
  270. end;
  271. { TSocks }
  272. function TSocks.CreateSocket: integer;
  273. begin;
  274. Result := SockList.Add(TSock.Create(Client));
  275. end;
  276. function TSocks.CreateSocketEx(Socket: TTCPBlockSocket): integer;
  277. begin;
  278. Result := SockList.Add(TSock.Create(Client, Socket));
  279. end;
  280. function TSocks.GetSocket(Index: integer): TSock;
  281. begin
  282. if (not (InRange(Index, 0, SockList.Count))) then
  283. raise exception.CreateFmt('GetSocket: Trying to acces an index(%d) that is out of range', [index]);
  284. if (SockList[index] = nil) then
  285. raise exception.CreateFmt('GetSocket: Trying to acces an index(%d) that is freed', [index]);
  286. Result := TSock(SockList[Index]);
  287. end;
  288. procedure TSocks.FreeSocket(Index: Integer);
  289. begin
  290. if (not (InRange(Index, 0, SockList.Count))) then
  291. raise exception.CreateFmt('GetSocket: Trying to free an index(%d) that is out of range', [index]);
  292. if (SockList[index] = nil) then
  293. raise exception.CreateFmt('GetSocket: Trying to free an index(%d) that is already freed', [index]);
  294. TSock(SockList[Index]).Free;
  295. SockList[Index] := nil;
  296. end;
  297. constructor TSocks.Create(Owner : TObject);
  298. begin
  299. inherited Create;
  300. Client := Owner;
  301. SockList := TList.Create;
  302. end;
  303. destructor TSocks.Destroy;
  304. var
  305. i: integer;
  306. begin
  307. for i := SockList.Count - 1 downto 0 do
  308. if SockList[i] <> nil then
  309. begin
  310. TSock(SockList[i]).Free;
  311. TClient(Client).WriteLn(Format('Socket[%d] has not been freed in the script, freeing it now.',[i]));
  312. end;
  313. SockList.Free;
  314. inherited Destroy;
  315. end;
  316. { TSock }
  317. function TSock.RecvBufferStr(Length: integer): string;
  318. begin
  319. Result := Sock.RecvBufferStr(Length, Timeout);
  320. if (Sock.LastError <> 0) then
  321. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  322. end;
  323. function TSock.RecvString: string;
  324. begin
  325. Result := Sock.RecvString(Timeout);
  326. if (Sock.LastError <> 0) then
  327. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  328. end;
  329. function TSock.Recv: string;
  330. begin
  331. Result := Sock.RecvPacket(Timeout);
  332. if (Sock.LastError <> 0) then
  333. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  334. end;
  335. procedure TSock.Send(Data: string);
  336. begin
  337. Sock.SendString(Data);
  338. if (Sock.LastError <> 0) then
  339. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  340. end;
  341. procedure TSock.Connect(IP, Port: string);
  342. begin
  343. Sock.Connect(IP, Port);
  344. if (Sock.LastError <> 0) then
  345. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  346. end;
  347. procedure TSock.Close;
  348. begin
  349. Sock.CloseSocket;
  350. if (Sock.LastError <> 0) then
  351. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  352. end;
  353. procedure TSock.SetTimeout(Time: integer);
  354. begin
  355. Timeout := Time;
  356. end;
  357. procedure TSock.Bind(IP, Port: string);
  358. begin
  359. Sock.Bind(IP, Port);
  360. if (Sock.LastError <> 0) then
  361. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  362. end;
  363. procedure TSock.Listen;
  364. begin
  365. Sock.Listen;
  366. end;
  367. function TSock.Accept: TTCPBlockSocket;
  368. var
  369. Socket: TTCPBlockSocket;
  370. begin
  371. Socket := TTCPBlockSocket.Create;
  372. Socket.Socket := Sock.Accept;
  373. Result := Socket;
  374. if (Sock.LastError <> 0) then
  375. raise Exception.Create('Socket Error ' + IntToStr(Sock.LastError) + ': ' + Sock.LastErrorDesc);
  376. end;
  377. procedure TSock.Info(out IP, Port: string);
  378. begin
  379. IP := Sock.GetRemoteSinIP;
  380. Port := IntToStr(Sock.GetRemoteSinPort);
  381. end;
  382. constructor TSock.Create(Owner: TObject; Socket: TTCPBlockSocket = nil);
  383. begin
  384. inherited Create;
  385. Client := Owner;
  386. Timeout := 1500;
  387. if (Socket <> nil) then
  388. Sock := Socket
  389. else
  390. Sock := TTCPBlockSocket.Create;
  391. end;
  392. destructor TSock.Destroy;
  393. begin
  394. Sock.Free;
  395. inherited Destroy;
  396. end;
  397. end.