PageRenderTime 119ms CodeModel.GetById 12ms RepoModel.GetById 1ms app.codeStats 0ms

/units/synapse/mimemess.pas

http://github.com/rofl0r/KOL
Pascal | 388 lines | 308 code | 43 blank | 37 comment | 15 complexity | b64ca0e82ae8804f344d9ccace22a984 MD5 | raw file
  1. {==============================================================================|
  2. | Project : Delphree - Synapse | 001.005.000 |
  3. |==============================================================================|
  4. | Content: MIME message object |
  5. |==============================================================================|
  6. | The contents of this file are Subject to the Mozilla Public License Ver. 1.1 |
  7. | (the "License"); you may not use this file except in compliance with the |
  8. | License. You may obtain a copy of the License at http://www.mozilla.org/MPL/ |
  9. | |
  10. | Software distributed under the License is distributed on an "AS IS" basis, |
  11. | WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for |
  12. | the specific language governing rights and limitations under the License. |
  13. |==============================================================================|
  14. | The Original Code is Synapse Delphi Library. |
  15. |==============================================================================|
  16. | The Initial Developer of the Original Code is Lukas Gebauer (Czech Republic).|
  17. | Portions created by Lukas Gebauer are Copyright (c)2000,2001. |
  18. | All Rights Reserved. |
  19. |==============================================================================|
  20. | Contributor(s): |
  21. |==============================================================================|
  22. | History: see HISTORY.HTM From distribution package |
  23. | (Found at URL: http://www.ararat.cz/synapse/) |
  24. |==============================================================================}
  25. {$WEAKPACKAGEUNIT ON}
  26. unit MIMEmess;
  27. interface
  28. uses
  29. KOL,
  30. MIMEpart, SynaChar, SynaUtil, MIMEinLn;
  31. type
  32. PMessHeader = ^TMessHeader;
  33. TMessHeader = object(TObj)
  34. private
  35. FFrom: string;
  36. FToList: PStrList;
  37. FSubject: string;
  38. FOrganization: string;
  39. FCustomHeaders: PStrList;
  40. public
  41. destructor Destroy; virtual;
  42. procedure Clear;
  43. procedure EncodeHeaders(Value: PStrList);
  44. procedure DecodeHeaders(Value: PStrList);
  45. property From: string read FFrom Write FFrom;
  46. property ToList: PStrList read FToList;
  47. property Subject: string read FSubject Write FSubject;
  48. property Organization: string read FOrganization Write FOrganization;
  49. property CustomHeaders: PStrList read FCustomHeaders;
  50. end;
  51. PMimeMess = ^TMimeMess;
  52. TMimeMess = object(TObj)
  53. private
  54. FPartList: PList;
  55. FLines: PStrList;
  56. FHeader: PMessHeader;
  57. FMultipartType: string;
  58. public
  59. destructor Destroy; virtual;
  60. procedure Clear;
  61. function AddPart: Integer;
  62. procedure AddPartText(Value: PStrList);
  63. procedure AddPartHTML(Value: PStrList);
  64. procedure AddPartHTMLBinary(Value, Cid: string);
  65. procedure AddPartBinary(Value: string);
  66. procedure EncodeMessage;
  67. procedure FinalizeHeaders;
  68. procedure ParseHeaders;
  69. procedure DecodeMessage;
  70. property PartList: PList read FPartList;
  71. property Lines: PStrList read FLines;
  72. property Header: PMessHeader read FHeader;
  73. property MultipartType: string read FMultipartType Write FMultipartType;
  74. end;
  75. function NewMessHeader : PMessHeader;
  76. function NewMimeMess : PMimeMess;
  77. implementation
  78. {==============================================================================}
  79. function NewMessHeader : PMessHeader;
  80. begin
  81. New(Result,Create);
  82. Result.FToList := NewStrList;//TStringList.Create;
  83. Result.FCustomHeaders := NewStrList;//TStringList.Create;
  84. end;
  85. destructor TMessHeader.Destroy;
  86. begin
  87. FCustomHeaders.Free;
  88. FToList.Free;
  89. inherited Destroy;
  90. end;
  91. {==============================================================================}
  92. procedure TMessHeader.Clear;
  93. begin
  94. FFrom := '';
  95. FToList.Clear;
  96. FSubject := '';
  97. FOrganization := '';
  98. FCustomHeaders.Clear;
  99. end;
  100. procedure TMessHeader.EncodeHeaders(Value: PStrList);
  101. var
  102. n: Integer;
  103. begin
  104. for n := FCustomHeaders.Count - 1 downto 0 do
  105. if FCustomHeaders.Items[n] <> '' then
  106. Value.Insert(0, FCustomHeaders.Items[n]);
  107. Value.Insert(0, 'x-mailer: Synapse - Delphi TCP/IP library by Lukas Gebauer');
  108. Value.Insert(0, 'MIME-Version: 1.0 (produced by Synapse)');
  109. Value.Insert(0, 'date: ' + Rfc822DateTime(Now));
  110. if FOrganization <> '' then
  111. Value.Insert(0, 'Organization: ' + InlineCode(FOrganization));
  112. if FSubject <> '' then
  113. Value.Insert(0, 'Subject: ' + InlineCode(FSubject));
  114. for n := 0 to FToList.Count - 1 do
  115. Value.Insert(0, 'To: ' + InlineEmail(FToList.Items[n]));
  116. Value.Insert(0, 'From: ' + InlineEmail(FFrom));
  117. end;
  118. procedure TMessHeader.DecodeHeaders(Value: PStrList);
  119. var
  120. s: string;
  121. x: Integer;
  122. cp: TMimeChar;
  123. begin
  124. cp := GetCurCP;
  125. Clear;
  126. x := 0;
  127. while Value.Count > x do
  128. begin
  129. s := NormalizeHeader(Value, x);
  130. if s = '' then
  131. Break;
  132. if Pos('FROM:', UpperCase(s)) = 1 then
  133. begin
  134. FFrom := InlineDecode(SeparateRight(s, ':'), cp);
  135. continue;
  136. end;
  137. if Pos('SUBJECT:', UpperCase(s)) = 1 then
  138. begin
  139. FSubject := InlineDecode(SeparateRight(s, ':'), cp);
  140. continue;
  141. end;
  142. if Pos('ORGANIZATION:', UpperCase(s)) = 1 then
  143. begin
  144. FOrganization := InlineDecode(SeparateRight(s, ':'), cp);
  145. continue;
  146. end;
  147. if Pos('TO:', UpperCase(s)) = 1 then
  148. begin
  149. FToList.Add(InlineDecode(SeparateRight(s, ':'), cp));
  150. continue;
  151. end;
  152. FCustomHeaders.Add(s);
  153. end;
  154. end;
  155. {==============================================================================}
  156. function NewMimeMess : PMimeMess;
  157. begin
  158. New(Result,Create);
  159. Result.FPartList := NewList;//TList.Create;
  160. Result.FLines := NewStrList;//TStringList.Create;
  161. Result.FHeader := NewMessHeader;//TMessHeader.Create;
  162. Result.FMultipartType := 'Mixed';
  163. end;
  164. destructor TMimeMess.Destroy;
  165. begin
  166. FHeader.Free;
  167. Lines.Free;
  168. PartList.Free;
  169. inherited Destroy;
  170. end;
  171. {==============================================================================}
  172. procedure TMimeMess.Clear;
  173. var
  174. n: Integer;
  175. begin
  176. FMultipartType := 'Mixed';
  177. Lines.Clear;
  178. for n := 0 to FPartList.Count - 1 do
  179. PMimePart(FPartList.Items[n]).Free;
  180. FPartList.Clear;
  181. FHeader.Clear;
  182. end;
  183. {==============================================================================}
  184. function TMimeMess.AddPart: Integer;
  185. var
  186. Part : PMimePart;
  187. begin
  188. Part := NewMimePart;
  189. FPartList.Add(Part);// Result := FPartList.Add(TMimePart.Create);
  190. Result := FPartList.Count -1;
  191. end;
  192. {==============================================================================}
  193. procedure TMimeMess.AddPartText(Value: PStrList);
  194. begin
  195. with PMimePart(FPartList.Items[AddPart])^ do
  196. begin
  197. Value.SaveToStream(DecodedLines);
  198. Primary := 'text';
  199. Secondary := 'plain';
  200. Description := 'Message text';
  201. Disposition := 'inline';
  202. CharsetCode := IdealCharsetCoding(Value.Text, TargetCharset,
  203. [ISO_8859_1, ISO_8859_2, ISO_8859_3, ISO_8859_4, ISO_8859_5,
  204. ISO_8859_6, ISO_8859_7, ISO_8859_8, ISO_8859_9, ISO_8859_10]);
  205. EncodingCode := ME_QUOTED_PRINTABLE;
  206. EncodePart;
  207. end;
  208. end;
  209. {==============================================================================}
  210. procedure TMimeMess.AddPartHTML(Value: PStrList);
  211. begin
  212. with PMimePart(FPartList.Items[AddPart])^ do
  213. begin
  214. Value.SaveToStream(DecodedLines);
  215. Primary := 'text';
  216. Secondary := 'html';
  217. Description := 'HTML text';
  218. Disposition := 'inline';
  219. CharsetCode := UTF_8;
  220. EncodingCode := ME_QUOTED_PRINTABLE;
  221. EncodePart;
  222. end;
  223. end;
  224. {==============================================================================}
  225. procedure TMimeMess.AddPartBinary(Value: string);
  226. var
  227. s: string;
  228. Part : PMimePart;
  229. begin
  230. Part := PMimePart(FPartList.Items[AddPart]);
  231. with Part^ do
  232. begin
  233. DecodedLines.LoadFromFile(Value);
  234. s := ExtractFileName(Value);
  235. MimeTypeFromExt(s);
  236. Description := 'Attached file: ' + s;
  237. Disposition := 'attachment';
  238. FileName := s;
  239. EncodingCode := ME_BASE64;
  240. EncodePart;
  241. end;
  242. end;
  243. procedure TMimeMess.AddPartHTMLBinary(Value, Cid: string);
  244. var
  245. s: string;
  246. begin
  247. with PMimePart(FPartList[AddPart])^ do
  248. begin
  249. DecodedLines.LoadFromFile(Value);
  250. s := ExtractFileName(Value);
  251. MimeTypeFromExt(s);
  252. Description := 'Included file: ' + s;
  253. Disposition := 'inline';
  254. ContentID := Cid;
  255. FileName := s;
  256. EncodingCode := ME_BASE64;
  257. EncodePart;
  258. end;
  259. end;
  260. {==============================================================================}
  261. procedure TMimeMess.EncodeMessage;
  262. var
  263. bound: string;
  264. n: Integer;
  265. Part : NewMimePart;
  266. begin
  267. FLines.Clear;
  268. if FPartList.Count = 1 then
  269. FLines.Assign(PMimePart(FPartList[0])^.Lines)
  270. else
  271. begin
  272. bound := GenerateBoundary;
  273. for n := 0 to FPartList.Count - 1 do
  274. begin
  275. FLines.Add('--' + bound);
  276. FLines.AddStrings(PMimePart(FPartList[n])^.Lines);
  277. end;
  278. FLines.Add('--' + bound + '--');
  279. Part := NewMimePart;
  280. with Part^ do
  281. try
  282. @Self.FLines.SaveToStream(DecodedLines);
  283. Primary := 'Multipart';
  284. Secondary := FMultipartType;
  285. Description := 'Multipart message';
  286. Boundary := bound;
  287. EncodePart;
  288. @Self.FLines.Assign(Lines);
  289. finally
  290. Free;
  291. end;
  292. end;
  293. end;
  294. {==============================================================================}
  295. procedure TMimeMess.FinalizeHeaders;
  296. begin
  297. FHeader.EncodeHeaders(FLines);
  298. end;
  299. {==============================================================================}
  300. procedure TMimeMess.ParseHeaders;
  301. begin
  302. FHeader.DecodeHeaders(FLines);
  303. end;
  304. {==============================================================================}
  305. procedure TMimeMess.DecodeMessage;
  306. var
  307. l: PStrList;
  308. m: PMimePart;
  309. i: Integer;
  310. bound: string;
  311. begin
  312. l := NewStrList;//TStringList.Create;
  313. m := NewMimePart;//TMimePart.Create;
  314. try
  315. l.Assign(FLines);
  316. FHeader.Clear;
  317. ParseHeaders;
  318. m.ExtractPart(l, 0);
  319. if m.PrimaryCode = MP_MULTIPART then
  320. begin
  321. bound := m.Boundary;
  322. i := 0;
  323. repeat
  324. with PMimePart(PartList[AddPart])^ do
  325. begin
  326. Boundary := bound;
  327. i := ExtractPart(l, i);
  328. DecodePart;
  329. end;
  330. until i >= l.Count - 2;
  331. end
  332. else
  333. begin
  334. with PMimePart(PartList[AddPart])^ do
  335. begin
  336. ExtractPart(l, 0);
  337. DecodePart;
  338. end;
  339. end;
  340. finally
  341. m.Free;
  342. l.Free;
  343. end;
  344. end;
  345. end.