s_chunksaver_test.go 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. package chunk
  2. import (
  3. "bytes"
  4. "fmt"
  5. "github.com/flashmob/go-guerrilla/backends"
  6. "github.com/flashmob/go-guerrilla/mail"
  7. "io"
  8. "os"
  9. "testing"
  10. )
  11. func TestChunkedBytesBuffer(t *testing.T) {
  12. var in string
  13. var buf chunkedBytesBuffer
  14. buf.CapTo(64)
  15. // the data to write is over-aligned
  16. in = `123456789012345678901234567890123456789012345678901234567890abcde12345678901234567890123456789012345678901234567890123456789abcdef` // len == 130
  17. i, _ := buf.Write([]byte(in[:]))
  18. if i != len(in) {
  19. t.Error("did not write", len(in), "bytes")
  20. }
  21. // the data to write is aligned
  22. var buf2 chunkedBytesBuffer
  23. buf2.CapTo(64)
  24. in = `123456789012345678901234567890123456789012345678901234567890abcde12345678901234567890123456789012345678901234567890123456789abcd` // len == 128
  25. i, _ = buf2.Write([]byte(in[:]))
  26. if i != len(in) {
  27. t.Error("did not write", len(in), "bytes")
  28. }
  29. // the data to write is under-aligned
  30. var buf3 chunkedBytesBuffer
  31. buf3.CapTo(64)
  32. in = `123456789012345678901234567890123456789012345678901234567890abcde12345678901234567890123456789012345678901234567890123456789ab` // len == 126
  33. i, _ = buf3.Write([]byte(in[:]))
  34. if i != len(in) {
  35. t.Error("did not write", len(in), "bytes")
  36. }
  37. // the data to write is smaller than the buffer
  38. var buf4 chunkedBytesBuffer
  39. buf4.CapTo(64)
  40. in = `1234567890` // len == 10
  41. i, _ = buf4.Write([]byte(in[:]))
  42. if i != len(in) {
  43. t.Error("did not write", len(in), "bytes")
  44. }
  45. // what if the buffer already contains stuff before Write is called
  46. // and the buffer len is smaller than the len of the slice of bytes we pass it?
  47. var buf5 chunkedBytesBuffer
  48. buf5.CapTo(5)
  49. buf5.buf = append(buf5.buf, []byte{'a', 'b', 'c'}...)
  50. in = `1234567890` // len == 10
  51. i, _ = buf5.Write([]byte(in[:]))
  52. if i != len(in) {
  53. t.Error("did not write", len(in), "bytes")
  54. }
  55. }
  56. var email = `From: Al Gore <[email protected]>
  57. To: White House Transportation Coordinator <[email protected]>
  58. Subject: [Fwd: Map of Argentina with Description]
  59. MIME-Version: 1.0
  60. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed; s=ncr424; d=reliancegeneral.co.in;
  61. h=List-Unsubscribe:MIME-Version:From:To:Reply-To:Date:Subject:Content-Type:Content-Transfer-Encoding:Message-ID; [email protected];
  62. bh=F4UQPGEkpmh54C7v3DL8mm2db1QhZU4gRHR1jDqffG8=;
  63. b=MVltcq6/I9b218a370fuNFLNinR9zQcdBSmzttFkZ7TvV2mOsGrzrwORT8PKYq4KNJNOLBahswXf
  64. GwaMjDKT/5TXzegdX/L3f/X4bMAEO1einn+nUkVGLK4zVQus+KGqm4oP7uVXjqp70PWXScyWWkbT
  65. 1PGUwRfPd/HTJG5IUqs=
  66. Content-Type: multipart/mixed;
  67. boundary="D7F------------D7FD5A0B8AB9C65CCDBFA872"
  68. This is a multi-part message in MIME format.
  69. --D7F------------D7FD5A0B8AB9C65CCDBFA872
  70. Content-Type: text/plain; charset=us-ascii
  71. Content-Transfer-Encoding: 7bit
  72. Fred,
  73. Fire up Air Force One! We're going South!
  74. Thanks,
  75. Al
  76. --D7F------------D7FD5A0B8AB9C65CCDBFA872
  77. Content-Type: message/rfc822
  78. Content-Transfer-Encoding: 7bit
  79. Content-Disposition: inline
  80. Return-Path: <[email protected]>
  81. Received: from mailhost.whitehouse.gov ([192.168.51.200])
  82. by heartbeat.whitehouse.gov (8.8.8/8.8.8) with ESMTP id SAA22453
  83. for <[email protected]>;
  84. Mon, 13 Aug 1998 l8:14:23 +1000
  85. Received: from the_big_box.whitehouse.gov ([192.168.51.50])
  86. by mailhost.whitehouse.gov (8.8.8/8.8.7) with ESMTP id RAA20366
  87. for [email protected]; Mon, 13 Aug 1998 17:42:41 +1000
  88. Date: Mon, 13 Aug 1998 17:42:41 +1000
  89. Message-Id: <[email protected]>
  90. From: Bill Clinton <[email protected]>
  91. To: A1 (The Enforcer) Gore <[email protected]>
  92. Subject: Map of Argentina with Description
  93. MIME-Version: 1.0
  94. Content-Type: multipart/mixed;
  95. boundary="DC8------------DC8638F443D87A7F0726DEF7"
  96. This is a multi-part message in MIME format.
  97. --DC8------------DC8638F443D87A7F0726DEF7
  98. Content-Type: text/plain; charset=us-ascii
  99. Content-Transfer-Encoding: 7bit
  100. Hi A1,
  101. I finally figured out this MIME thing. Pretty cool. I'll send you
  102. some sax music in .au files next week!
  103. Anyway, the attached image is really too small to get a good look at
  104. Argentina. Try this for a much better map:
  105. http://www.1one1yp1anet.com/dest/sam/graphics/map-arg.htm
  106. Then again, shouldn't the CIA have something like that?
  107. Bill
  108. --DC8------------DC8638F443D87A7F0726DEF7
  109. Content-Type: image/gif; name="map_of_Argentina.gif"
  110. Content-Transfer-Encoding: base64
  111. Content-Disposition: attachment; filename="map_of_Argentina.gif"
  112. R01GOD1hJQA1AKIAAP/////78P/omn19fQAAAAAAAAAAAAAAACwAAAAAJQA1AAAD7Qi63P5w
  113. wEmjBCLrnQnhYCgM1wh+pkgqqeC9XrutmBm7hAK3tP31gFcAiFKVQrGFR6kscnonTe7FAAad
  114. GugmRu3CmiBt57fsVq3Y0VFKnpYdxPC6M7Ze4crnnHum4oN6LFJ1bn5NXTN7OF5fQkN5WYow
  115. BEN2dkGQGWJtSzqGTICJgnQuTJN/WJsojad9qXMuhIWdjXKjY4tenjo6tjVssk2gaWq3uGNX
  116. U6ZGxseyk8SasGw3J9GRzdTQky1iHNvcPNNI4TLeKdfMvy0vMqLrItvuxfDW8ubjueDtJufz
  117. 7itICBxISKDBgwgTKjyYAAA7
  118. --DC8------------DC8638F443D87A7F0726DEF7--
  119. --D7F------------D7FD5A0B8AB9C65CCDBFA872--
  120. `
  121. var email2 = `Delivered-To: [email protected]
  122. Received: from aaa.cn (aaa.cn [220.178.145.250])
  123. by 163.com with SMTP id [email protected];
  124. Tue, 17 Sep 2019 01:16:43 +0000
  125. From: "=?utf-8?Q?=E6=B1=9F=E5=8D=97=E6=A2=A6=E6=96=AD=E6=A8=AA=E6=B1=9F=E6=B8=9A?=" <[email protected]>
  126. To: <[email protected]>
  127. Subject: =?utf-8?Q?=E5=BA=94=E5=8A=9B=E6=AF=94b?=
  128. Date: Tue, 17 Sep 2019 09:16:29 +0800
  129. Message-ID: <[email protected]>
  130. MIME-Version: 1.0
  131. Content-Type: text/html;
  132. charset="utf-8"
  133. Content-Transfer-Encoding: 8bit
  134. X-Priority: 3 (Normal)
  135. X-MSMail-Priority: Normal
  136. X-Mailer: Microsoft Outlook IMO, Build 9.0.2416 (9.0.2911.0)
  137. Importance: Normal
  138. X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180
  139. <P><SPAN style='FONT-SIZE: large; FONT-FAMILY: "lucida Grande", Verdana, "Microsoft YaHei"; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; FLOAT: none; FONT-WEIGHT: normal; COLOR: rgb(0,0,0); FONT-STYLE: normal; ORPHANS: 2; WIDOWS: 2; DISPLAY: inline !important; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial'><FONT size=2><FONT color=black><FONT color=#008040><FONT color=#000000><FONT color=silver>Date:2019-09-17<BR>Account:[email protected]</FONT><FONT size=3> </FONT></FONT>
  140. <HR>
  141. <P></P>
  142. <P></FONT></FONT></FONT></SPAN><SPAN style='FONT-SIZE: large; FONT-FAMILY: "lucida Grande", Verdana, "Microsoft YaHei"; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; FLOAT: none; FONT-WEIGHT: normal; COLOR: rgb(0,0,0); FONT-STYLE: normal; ORPHANS: 2; WIDOWS: 2; DISPLAY: inline !important; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial'><FONT color=black size=2>丅<span style="position:absolute; bottom:-3000px"><交通指挥灯></span>載<span style="position:absolute; bottom:-3000px"><硝化作用></span>а<span style="position:absolute; bottom:-3000px"><柿子></span>ρ<span style="position:absolute; bottom:-3000px"><竞争性领域></span>ρ<span style="position:absolute; bottom:-3000px"><毛虫></span>签<span style="position:absolute; bottom:-3000px"><非持久性病毒></span>到<span style="position:absolute; bottom:-3000px"><街灯></span>領<span style="position:absolute; bottom:-3000px"><麦蜘蛛></span>1<span style="position:absolute; bottom:-3000px"><求索></span>6<span style="position:absolute; bottom:-3000px"><企业标准></span>╇<span style="position:absolute; bottom:-3000px"><气候条件></span>,<span style="position:absolute; bottom:-3000px"><农村劳动力转移></span>登<span style="position:absolute; bottom:-3000px"><穴深></span>杁<span style="position:absolute; bottom:-3000px"><预备队></span>2<span style="position:absolute; bottom:-3000px"><农机具></span>Ч<span style="position:absolute; bottom:-3000px"><营养袋育苗></span>棋<span style="position:absolute; bottom:-3000px"><生物肥料></span>牌<span style="position:absolute; bottom:-3000px"><光照强度></span>2<span style="position:absolute; bottom:-3000px"><改良系谱法></span>4<span style="position:absolute; bottom:-3000px"><加大投入></span>9<span style="position:absolute; bottom:-3000px"><茶叶产业办公室></span>8<span style="position:absolute; bottom:-3000px"><省局></span>8<span style="position:absolute; bottom:-3000px"><辐照></span>4<span style="position:absolute; bottom:-3000px"><百亩></span>.<span style="position:absolute; bottom:-3000px"><上行列车></span>c<span style="position:absolute; bottom:-3000px"><竹节></span>δ<span style="position:absolute; bottom:-3000px"><山嘴></span>м<span style="position:absolute; bottom:-3000px"><股所></span>,<span style="position:absolute; bottom:-3000px"><科学谋划></span>吋<span style="position:absolute; bottom:-3000px"><领海></span>款<span style="position:absolute; bottom:-3000px"><异常型种子></span>1<span style="position:absolute; bottom:-3000px"><董家村></span> <span style="position:absolute; bottom:-3000px"><平面球形图></span>0<span style="position:absolute; bottom:-3000px"><先来></span> <span style="position:absolute; bottom:-3000px"><藜叶斑病></span>0<span style="position:absolute; bottom:-3000px"><竞职></span>宋<span style="position:absolute; bottom:-3000px"><二棱大麦></span>2<span style="position:absolute; bottom:-3000px"><茎枯病></span> <span style="position:absolute; bottom:-3000px"><宁洱县></span>0<span style="position:absolute; bottom:-3000px"><共枕></span>鎵<span style="position:absolute; bottom:-3000px"><钙镁磷肥></span>專<span style="position:absolute; bottom:-3000px"><校正></span>員<span style="position:absolute; bottom:-3000px"><砍青></span>4<span style="position:absolute; bottom:-3000px"><独具特色></span>8<span style="position:absolute; bottom:-3000px"><装草机></span>6<span style="position:absolute; bottom:-3000px"><斑螟></span>1<span style="position:absolute; bottom:-3000px"><补偿机制></span>3<span style="position:absolute; bottom:-3000px"><创意策划></span>8<span style="position:absolute; bottom:-3000px"><投稿家></span>3<span style="position:absolute; bottom:-3000px"><茶点></span>2<span style="position:absolute; bottom:-3000px"><量天尺枯萎腐烂病></span>0<span style="position:absolute; bottom:-3000px"><河尾></span>翎<span style="position:absolute; bottom:-3000px"><台湾稻螟></span>。<span style="position:absolute; bottom:-3000px"><春城晚报></span></FONT></SPAN></P>
  143. <P><SPAN style='FONT-SIZE: large; FONT-FAMILY: "lucida Grande", Verdana, "Microsoft YaHei"; WHITE-SPACE: normal; WORD-SPACING: 0px; TEXT-TRANSFORM: none; FLOAT: none; FONT-WEIGHT: normal; COLOR: rgb(0,0,0); FONT-STYLE: normal; ORPHANS: 2; WIDOWS: 2; DISPLAY: inline !important; LETTER-SPACING: normal; BACKGROUND-COLOR: rgb(255,255,255); TEXT-INDENT: 0px; font-variant-ligatures: normal; font-variant-caps: normal; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial'></SPAN><FONT color=silver size=2>Your words appear idle to me; give them proof, and I will listen.</FONT></P>`
  144. var email3 = `Delivered-To: [email protected]
  145. Received: from bb_dyn_pb-146-88-38-36.violin.co.th (bb_dyn_pb-146-88-38-36.violin.co.th [146.88.38.36])
  146. by sharklasers.com with SMTP id [email protected];
  147. Tue, 17 Sep 2019 01:13:00 +0000
  148. Received: from mx03.listsystemsf.net [100.20.38.85] by mxs.perenter.com with SMTP; Tue, 17 Sep 2019 04:57:59 +0500
  149. Received: from mts.locks.grgtween.net ([Tue, 17 Sep 2019 04:52:27 +0500])
  150. by webmail.halftomorrow.com with LOCAL; Tue, 17 Sep 2019 04:52:27 +0500
  151. Received: from mail.naihautsui.co.kr ([61.220.30.1]) by mtu67.syds.piswix.net with ASMTP; Tue, 17 Sep 2019 04:47:25 +0500
  152. Received: from unknown (HELO mx03.listsystemsf.net) (Tue, 17 Sep 2019 04:41:45 +0500)
  153. by smtp-server1.cfdenselr.com with LOCAL; Tue, 17 Sep 2019 04:41:45 +0500
  154. Message-ID: <[email protected]>
  155. Date: Tue, 17 Sep 2019 04:14:56 +0500
  156. Reply-To: "Nevaeh" <[email protected]>
  157. From: "Nevaeh" <[email protected]>
  158. User-Agent: Mozilla 4.73 [de]C-CCK-MCD DT (Win98; U)
  159. X-Accept-Language: en-us
  160. MIME-Version: 1.0
  161. To: "Nevaeh" <[email protected]>
  162. Subject: czy m�glbys spotkac sie ze mna w weekend?
  163. Content-Type: text/html;
  164. charset="iso-8859-1"
  165. Content-Transfer-Encoding: base64
  166. PCFkb2N0eXBlIGh0bWw+DQo8aHRtbD4NCjxoZWFkPg0KPG1ldGEgY2hhcnNldD0idXRmLTgiPg0K
  167. PC9oZWFkPg0KPGJvZHk+DQo8dGFibGUgd2lkdGg9IjYwMCIgYm9yZGVyPSIwIiBhbGlnbj0iY2Vu
  168. dGVyIiBzdHlsZT0iZm9udC1mYW1pbHk6IEFyaWFsOyBmb250LXNpemU6IDE4cHgiPg0KPHRib2R5
  169. Pg0KPHRyPg0KPHRoIGhlaWdodD0iNjAiIHNjb3BlPSJjb2wiPk5hamdvcmV0c3plIGR6aWV3Y3p5
  170. bnkgaSBzYW1vdG5lIGtvYmlldHksIGt083JlIGNoY2Egc2Vrc3UuPG9sPjwvb2w+PC90aD4NCjwv
  171. dHI+DQo8dGQgaGVpZ2h0PSIyMjMiIGFsaWduPSJjZW50ZXIiPjxwPk5hIG5hc3plaiBzdHJvbmll
  172. IGdyb21hZHpvbmUgc2EgbWlsaW9ueSBwcm9maWxpIGtvYmlldC4gV3N6eXNjeSBjaGNhIHRlcmF6
  173. IHBpZXByenljLjwvcD4NCjxoZWFkZXI+PC9oZWFkZXI+DQo8cD5OYSBwcnp5a2xhZCBzYSBXIFRX
  174. T0lNIE1JRVNDSUUuIENoY2VzeiBpbm55Y2g/IFpuYWpkeiBuYSBuYXN6ZWogc3Ryb25pZSE8L3A+
  175. DQo8dGFibGUgY2xhc3M9Im1jbkJ1dHRvbkNvbnRlbnRDb250YWluZXIiIHN0eWxlPSJib3JkZXIt
  176. Y29sbGFwc2U6IHNlcGFyYXRlICEgaW1wb3J0YW50O2JvcmRlci1yYWRpdXM6IDNweDtiYWNrZ3Jv
  177. dW5kLWNvbG9yOiAjRTc0MTQxOyIgYm9yZGVyPSIwIiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRp
  178. bmc9IjAiPg0KIDx0Ym9keT4NCiA8dHI+DQogPHRkIGNsYXNzPSJtY25CdXR0b25Db250ZW50IiBz
  179. dHlsZT0iZm9udC1mYW1pbHk6IEFyaWFsOyBmb250LXNpemU6IDIycHg7IHBhZGRpbmc6IDE1cHgg
  180. MjVweDsiIHZhbGlnbj0ibWlkZGxlIiBhbGlnbj0iY2VudGVyIj4NCiA8YSBjbGFzcz0ibWNuQnV0
  181. dG9uICIgaHJlZj0iaHR0cDovL2JldGhhbnkuc3UiIHRhcmdldD0iX2JsYW5rIiBzdHlsZT0iZm9u
  182. dC13ZWlnaHQ6IG5vcm1hbDtsZXR0ZXItc3BhY2luZzogbm9ybWFsO2xpbmUtaGVpZ2h0OiAxMDAl
  183. O3RleHQtYWxpZ246IGNlbnRlcjt0ZXh0LWRlY29yYXRpb246IG5vbmU7Y29sb3I6ICNGRkZGRkY7
  184. Ij5odHRwOi8vYmV0aGFueS5zdTwvYT4NCiA8L3RkPg0KIDwvdHI+DQogPC90Ym9keT4NCiA8L3Rh
  185. YmxlPjx0YWJsZSB3aWR0aD0iMjglIiBib3JkZXI9IjAiPjx0Ym9keT48dHI+PHRkPjwvdGQ+PHRk
  186. PjwvdGQ+PHRkPjwvdGQ+PC90cj48L3Rib2R5PjwvdGFibGU+DQo8dGFibGUgc3R5bGU9Im1pbi13
  187. aWR0aDoxMDAlOyIgY2xhc3M9Im1jblRleHRDb250ZW50Q29udGFpbmVyIiBhbGlnbj0ibGVmdCIg
  188. Ym9yZGVyPSIwIiBjZWxscGFkZGluZz0iMCIgY2VsbHNwYWNpbmc9IjAiIHdpZHRoPSIxMDAlIj4N
  189. Cjx0Ym9keT4NCiA8dHI+DQo8dGQgYWxpZ249ImNlbnRlciIgdmFsaWduPSJ0b3AiIGNsYXNzPSJt
  190. Y25UZXh0Q29udGVudCIgc3R5bGU9InBhZGRpbmc6IDlweCAxOHB4O2NvbG9yOiAjNkI2QjZCO2Zv
  191. bnQtZmFtaWx5OiBWZXJkYW5hLEdlbmV2YSxzYW5zLXNlcmlmO2ZvbnQtc2l6ZTogMTFweDsiPg0K
  192. VXp5aiB0ZWdvIGxpbmt1LCBqZXNsaSBwcnp5Y2lzayBuaWUgZHppYWxhPGJyPg0KPGEgaHJlZj0i
  193. aHR0cDovL2JldGhhbnkuc3UiIHRhcmdldD0iX2JsYW5rIj5odHRwOi8vYmV0aGFueS5zdTwvYT48
  194. YnI+DQpTa29waXVqIGkgd2tsZWogbGluayBkbyBwcnplZ2xhZGFya2k8L3RkPg0KPC90cj4NCjwv
  195. dGJvZHk+PC90YWJsZT48L3RkPg0KPC90cj4gDQo8L3Rib2R5Pg0KPC90YWJsZT4NCjxvbD48cD48
  196. L3A+PC9vbD4NCjx0YWJsZSB3aWR0aD0iNjAwIiBib3JkZXI9IjAiIGFsaWduPSJjZW50ZXIiPg0K
  197. IDx0Ym9keT4NCiA8dHI+DQogPHRkPjxhIGhyZWY9Imh0dHA6Ly9iZXRoYW55LnN1Ij48cCBzdHls
  198. ZT0idGV4dC1hbGlnbjogY2VudGVyIj5DYW1pbGE8L3A+DQogPG5hdj48L25hdj4NCiA8dGFibGU+
  199. DQogPHRyPg0KIDx0ZCB2YWxpZ249InRvcCIgc3R5bGU9ImJhY2tncm91bmQ6IHVybChodHRwczov
  200. L3RoZWNoaXZlLmZpbGVzLndvcmRwcmVzcy5jb20vMjAxOS8wOS9iODE0NmEyOTI3ODY4ODkxNzk4
  201. ODY1NDhlN2QzOWEzZV93aWR0aC02MDAuanBlZz9xdWFsaXR5PTEwMCZzdHJpcD1pbmZvJnc9NjQx
  202. Jnpvb209Mikgbm8tcmVwZWF0IGNlbnRlcjtiYWNrZ3JvdW5kLXBvc2l0aW9uOiB0b3A7YmFja2dy
  203. b3VuZC1zaXplOiBjb3ZlcjsiPjwhLS1baWYgZ3RlIG1zbyA5XT4gPHY6cmVjdCB4bWxuczp2PSJ1
  204. cm46c2NoZW1hcy1taWNyb3NvZnQtY29tOnZtbCIgZmlsbD0idHJ1ZSIgc3Ryb2tlPSJmYWxzZSIg
  205. c3R5bGU9Im1zby13aWR0aC1wZXJjZW50OjEwMDA7aGVpZ2h0OjQwMHB4OyI+IDx2OmZpbGwgdHlw
  206. ZT0idGlsZSIgc3JjPSJodHRwczovL3RoZWNoaXZlLmZpbGVzLndvcmRwcmVzcy5jb20vMjAxOS8w
  207. OC82YWU4NzFiNTlmYjUxMDc1ZGMwMzE3ZDBiOTkzZjJhOV93aWR0aC02MDAuanBnP3F1YWxpdHk9
  208. MTAwJnN0cmlwPWluZm8mdz02NDEmem9vbT0yIiAvPiA8djp0ZXh0Ym94IGluc2V0PSIwLDAsMCww
  209. Ij4gPCFbZW5kaWZdLS0+DQogPGRpdj4NCiA8Y2VudGVyPg0KIDx0YWJsZSBjZWxsc3BhY2luZz0i
  210. MCIgY2VsbHBhZGRpbmc9IjAiIHdpZHRoPSIyODAiIGhlaWdodD0iNDAwIj4NCiA8dHI+DQogPHRk
  211. IHZhbGlnbj0ibWlkZGxlIiBzdHlsZT0idmVydGljYWwtYWxpZ246bWlkZGxlO3RleHQtYWxpZ246
  212. bGVmdDsiIGNsYXNzPSJtb2JpbGUtY2VudGVyIiBoZWlnaHQ9IjQwMCI+PGFydGljbGU+PC9hcnRp
  213. Y2xlPiA8L3RkPg0KIDwvdHI+DQogPC90YWJsZT4NCiA8L2NlbnRlcj4NCiA8L2Rpdj4NCiA8IS0t
  214. W2lmIGd0ZSBtc28gOV0+IDwvdjp0ZXh0Ym94PiA8L3Y6cmVjdD4gPCFbZW5kaWZdLS0+PC90ZD4N
  215. CiA8L3RyPg0KIDwvdGFibGU+DQogPC9hPjwvdGQ+DQogPHRkPjxhIGhyZWY9Imh0dHA6Ly9iZXRo
  216. YW55LnN1Ij48cCBzdHlsZT0idGV4dC1hbGlnbjogY2VudGVyIj5NaWxhPC9wPg0KIDxkaXY+PC9k
  217. aXY+DQogPHRhYmxlPg0KIDx0cj4NCiA8dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJiYWNrZ3JvdW5k
  218. OiB1cmwoaHR0cHM6Ly90aGVjaGl2ZS5maWxlcy53b3JkcHJlc3MuY29tLzIwMTkvMDgvODg1ZGFi
  219. OTM2MGZiYzY2NGMzYTNhNDQwOGI1NTE2ZDUtMS5qcGc/cXVhbGl0eT0xMDAmc3RyaXA9aW5mbyZ3
  220. PTY0MSZ6b29tPTIpIG5vLXJlcGVhdCBjZW50ZXI7YmFja2dyb3VuZC1wb3NpdGlvbjogdG9wO2Jh
  221. Y2tncm91bmQtc2l6ZTogY292ZXI7Ij48IS0tW2lmIGd0ZSBtc28gOV0+IDx2OnJlY3QgeG1sbnM6
  222. dj0idXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTp2bWwiIGZpbGw9InRydWUiIHN0cm9rZT0iZmFs
  223. c2UiIHN0eWxlPSJtc28td2lkdGgtcGVyY2VudDoxMDAwO2hlaWdodDo0MDBweDsiPiA8djpmaWxs
  224. IHR5cGU9InRpbGUiIHNyYz0iaHR0cHM6Ly90aGVjaGl2ZS5maWxlcy53b3JkcHJlc3MuY29tLzIw
  225. MTkvMDgvMGE2Mzc2MDVkYzhkOTcyNzRhZWFkODVhOGY0YTJmYjkuanBnP3F1YWxpdHk9MTAwJnN0
  226. cmlwPWluZm8mdz02MDAiIC8+IDx2OnRleHRib3ggaW5zZXQ9IjAsMCwwLDAiPiA8IVtlbmRpZl0t
  227. LT4NCg0KIDxkaXY+DQogPGNlbnRlcj4NCiA8dGFibGUgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRk
  228. aW5nPSIwIiB3aWR0aD0iMjgwIiBoZWlnaHQ9IjQwMCI+DQogPHRyPg0KIDx0ZCB2YWxpZ249Im1p
  229. ZGRsZSIgc3R5bGU9InZlcnRpY2FsLWFsaWduOm1pZGRsZTt0ZXh0LWFsaWduOmxlZnQ7IiBjbGFz
  230. cz0ibW9iaWxlLWNlbnRlciIgaGVpZ2h0PSI0MDAiPjxocj4gPC90ZD4NCiA8L3RyPg0KIDwvdGFi
  231. bGU+DQogPC9jZW50ZXI+DQogPC9kaXY+DQogPCEtLVtpZiBndGUgbXNvIDldPiA8L3Y6dGV4dGJv
  232. eD4gPC92OnJlY3Q+IDwhW2VuZGlmXS0tPjwvdGQ+DQogPC90cj4NCiA8L3RhYmxlPg0KIDwvYT48
  233. L3RkPg0KIDwvdHI+DQogPHRyPg0KIDx0ZD48YSBocmVmPSJodHRwOi8vYmV0aGFueS5zdSI+PHAg
  234. c3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+THVuYTwvcD4NCiA8dGFibGUgd2lkdGg9Ijc0JSIg
  235. Ym9yZGVyPSIwIj48dGJvZHk+PHRyPjx0ZD48L3RkPjx0ZD48L3RkPjx0ZD48L3RkPjx0ZD48L3Rk
  236. Pjx0ZD48L3RkPjwvdHI+PC90Ym9keT48L3RhYmxlPg0KIDx0YWJsZT4NCiA8dHI+DQogPHRkIHZh
  237. bGlnbj0idG9wIiBzdHlsZT0iYmFja2dyb3VuZDogdXJsKGh0dHBzOi8vdGhlY2hpdmUuZmlsZXMu
  238. d29yZHByZXNzLmNvbS8yMDE5LzA4LzA2ZTU2YTU4ZjQ3ZDM0OGEyMjc3NmYyOTFlNjg2OWEwLTEu
  239. anBnP3F1YWxpdHk9MTAwJnN0cmlwPWluZm8mdz02NDEmem9vbT0yKSBuby1yZXBlYXQgY2VudGVy
  240. O2JhY2tncm91bmQtcG9zaXRpb246IHRvcDtiYWNrZ3JvdW5kLXNpemU6IGNvdmVyOyI+PCEtLVtp
  241. ZiBndGUgbXNvIDldPiA8djpyZWN0IHhtbG5zOnY9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206
  242. dm1sIiBmaWxsPSJ0cnVlIiBzdHJva2U9ImZhbHNlIiBzdHlsZT0ibXNvLXdpZHRoLXBlcmNlbnQ6
  243. MTAwMDtoZWlnaHQ6NDAwcHg7Ij4gPHY6ZmlsbCB0eXBlPSJ0aWxlIiBzcmM9Imh0dHBzOi8vdGhl
  244. Y2hpdmUuZmlsZXMud29yZHByZXNzLmNvbS8yMDE5LzA4LzhhYjRkYzcxMjFlYTVhMzdiMTc3NjNm
  245. ZjRhNDA1MTVlLmpwZz9xdWFsaXR5PTEwMCZzdHJpcD1pbmZvJnc9NjQxJnpvb209MiIgLz4gPHY6
  246. dGV4dGJveCBpbnNldD0iMCwwLDAsMCI+IDwhW2VuZGlmXS0tPg0KIDxkaXY+DQogPGNlbnRlcj4N
  247. CiA8dGFibGUgY2VsbHNwYWNpbmc9IjAiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMjgwIiBoZWln
  248. aHQ9IjQwMCI+DQogPHRyPg0KIDx0ZCB2YWxpZ249Im1pZGRsZSIgc3R5bGU9InZlcnRpY2FsLWFs
  249. aWduOm1pZGRsZTt0ZXh0LWFsaWduOmxlZnQ7IiBjbGFzcz0ibW9iaWxlLWNlbnRlciIgaGVpZ2h0
  250. PSI0MDAiPjxicj4gPC90ZD4NCiA8L3RyPg0KIDwvdGFibGU+DQogPC9jZW50ZXI+DQogPC9kaXY+
  251. DQogPCEtLVtpZiBndGUgbXNvIDldPiA8L3Y6dGV4dGJveD4gPC92OnJlY3Q+IDwhW2VuZGlmXS0t
  252. PjwvdGQ+DQogPC90cj4NCiA8L3RhYmxlPg0KIDwvYT48L3RkPg0KIDx0ZD48YSBocmVmPSJodHRw
  253. Oi8vYmV0aGFueS5zdSI+PHAgc3R5bGU9InRleHQtYWxpZ246IGNlbnRlciI+U2F2YW5uYWg8L3A+
  254. DQogPG9sPjwvb2w+DQogPHRhYmxlPg0KIDx0cj4NCiA8dGQgdmFsaWduPSJ0b3AiIHN0eWxlPSJi
  255. YWNrZ3JvdW5kOiB1cmwoaHR0cHM6Ly90aGVjaGl2ZS5maWxlcy53b3JkcHJlc3MuY29tLzIwMTkv
  256. MDgvYzA4MzYxNTE2MzUxNDFkNDhlY2ZmYTNkYmZkOGYxZDYuanBnP3F1YWxpdHk9MTAwJnN0cmlw
  257. PWluZm8mdz02NDEmem9vbT0yKSBuby1yZXBlYXQgY2VudGVyO2JhY2tncm91bmQtcG9zaXRpb246
  258. IHRvcDtiYWNrZ3JvdW5kLXNpemU6IGNvdmVyOyI+PCEtLVtpZiBndGUgbXNvIDldPiA8djpyZWN0
  259. IHhtbG5zOnY9InVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206dm1sIiBmaWxsPSJ0cnVlIiBzdHJv
  260. a2U9ImZhbHNlIiBzdHlsZT0ibXNvLXdpZHRoLXBlcmNlbnQ6MTAwMDtoZWlnaHQ6NDAwcHg7Ij4g
  261. PHY6ZmlsbCB0eXBlPSJ0aWxlIiBzcmM9Imh0dHBzOi8vdGhlY2hpdmUuZmlsZXMud29yZHByZXNz
  262. LmNvbS8yMDE5LzA4L2NhMWI4MWI5MTkyYTZkMzEyNTI1MmYwYzIwZWIxMjVjLmpwZz9xdWFsaXR5
  263. PTEwMCZzdHJpcD1pbmZvJnc9NjQxJnpvb209MiIgLz4gPHY6dGV4dGJveCBpbnNldD0iMCwwLDAs
  264. MCI+IDwhW2VuZGlmXS0tPg0KIDxkaXY+DQogPGNlbnRlcj4NCiA8dGFibGUgY2VsbHNwYWNpbmc9
  265. IjAiIGNlbGxwYWRkaW5nPSIwIiB3aWR0aD0iMjgwIiBoZWlnaHQ9IjQwMCI+DQogPHRyPg0KIDx0
  266. ZCB2YWxpZ249Im1pZGRsZSIgc3R5bGU9InZlcnRpY2FsLWFsaWduOm1pZGRsZTt0ZXh0LWFsaWdu
  267. OmxlZnQ7IiBjbGFzcz0ibW9iaWxlLWNlbnRlciIgaGVpZ2h0PSI0MDAiPjxtYWluPjwvbWFpbj4g
  268. PC90ZD4NCiA8L3RyPg0KIDwvdGFibGU+DQogPC9jZW50ZXI+DQogPC9kaXY+DQogPCEtLVtpZiBn
  269. dGUgbXNvIDldPiA8L3Y6dGV4dGJveD4gPC92OnJlY3Q+IDwhW2VuZGlmXS0tPjwvdGQ+DQogPC90
  270. cj4NCiA8L3RhYmxlPg0KIDwvYT48L3RkPg0KIDwvdHI+DQogPC90Ym9keT4NCjwvdGFibGU+DQo8
  271. dGFibGUgd2lkdGg9IjYxJSIgYm9yZGVyPSIwIj48dGJvZHk+PHRyPjx0ZD48L3RkPjx0ZD48L3Rk
  272. PjwvdHI+PC90Ym9keT48L3RhYmxlPg0KPHRhYmxlIHdpZHRoPSI2MDAiIGJvcmRlcj0iMCIgYWxp
  273. Z249ImNlbnRlciI+DQo8dGJvZHk+DQo8dHI+DQo8dGg+PHAgc3R5bGU9InRleHQtYWxpZ246IGNl
  274. bnRlciI+QnJvb2tseW48L3A+DQogPHA+PGEgaHJlZj0iaHR0cDovL2JldGhhbnkuc3UiPjxpbWcg
  275. c3JjPSJodHRwczovL3RoZWNoaXZlLmZpbGVzLndvcmRwcmVzcy5jb20vMjAxOS8wOC9kMzc0Zjcx
  276. NDI0Nzc0MjEwNzdkOWQzZTg4ZmI1OTMxMS5qcGc/cXVhbGl0eT0xMDAmc3RyaXA9aW5mbyZ3PTY0
  277. MSZ6b29tPTIiIHdpZHRoPSIyODAiIGFsdD0ib3BlbiBwcm9maWxlIi8+PC9hPjwvcD48L3RoPg0K
  278. PHRoPjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPkVtbWE8L3A+DQogPHA+PGEgaHJlZj0i
  279. aHR0cDovL2JldGhhbnkuc3UiPjxpbWcgc3JjPSJodHRwczovL3RoZWNoaXZlLmZpbGVzLndvcmRw
  280. cmVzcy5jb20vMjAxOS8wOC9kNTk4ZjdlYTYxYWZjYTNjYjg2MjVkN2NmYTE5NzRiNC5qcGc/cXVh
  281. bGl0eT0xMDAmc3RyaXA9aW5mbyZ3PTY0MSZ6b29tPTIiIHdpZHRoPSIyODAiIGFsdD0ib3BlbiBw
  282. cm9maWxlIi8+PC9hPjwvcD48L3RoPg0KPC90cj4NCjx0cj4NCjx0ZD48dGFibGUgd2lkdGg9IjUw
  283. JSIgYm9yZGVyPSIwIj48dGJvZHk+PHRyPjx0ZD48L3RkPjx0ZD48L3RkPjwvdHI+PC90Ym9keT48
  284. L3RhYmxlPjwvdGQ+DQo8dGQ+PHVsPjxwPjwvcD48L3VsPjwvdGQ+DQo8L3RyPg0KPHRyPg0KPHRo
  285. PjxwIHN0eWxlPSJ0ZXh0LWFsaWduOiBjZW50ZXIiPkVtbWE8L3A+DQogPHA+PGEgaHJlZj0iaHR0
  286. cDovL2JldGhhbnkuc3UiPjxpbWcgc3JjPSJodHRwczovL3RoZWNoaXZlLmZpbGVzLndvcmRwcmVz
  287. cy5jb20vMjAxOS8wOS85YzU1ZjA1MmMzZDZhODgyZGYxMTFhZDZhZmFjOWMwNF93aWR0aC02MDAu
  288. anBlZz9xdWFsaXR5PTEwMCZzdHJpcD1pbmZvJnc9NjQxJnpvb209MiIgd2lkdGg9IjI4MCIgYWx0
  289. PSJvcGVuIHByb2ZpbGUiLz48L2E+PC9wPjwvdGg+DQo8dGg+PHAgc3R5bGU9InRleHQtYWxpZ246
  290. IGNlbnRlciI+QXZhPC9wPg0KIDxwPjxhIGhyZWY9Imh0dHA6Ly9iZXRoYW55LnN1Ij48aW1nIHNy
  291. Yz0iaHR0cHM6Ly90aGVjaGl2ZS5maWxlcy53b3JkcHJlc3MuY29tLzIwMTkvMDkvMzdlMDM1ZGZj
  292. YTM2NjkyZTk3ZTA4OWFjN2ZiNWVjN2QuanBnP3F1YWxpdHk9MTAwJnN0cmlwPWluZm8mdz02NDEm
  293. em9vbT0yIiB3aWR0aD0iMjgwIiBhbHQ9Im9wZW4gcHJvZmlsZSIvPjwvYT48L3A+PC90aD4NCjwv
  294. dHI+DQo8L3Rib2R5Pg0KPC90YWJsZT4NCjxuYXY+PC9uYXY+DQo8dGFibGUgc3R5bGU9Im1heC13
  295. aWR0aDo2MDBweDsgIiBjbGFzcz0ibWNuVGV4dENvbnRlbnRDb250YWluZXIiIHdpZHRoPSIxMDAl
  296. IiBjZWxsc3BhY2luZz0iMCIgY2VsbHBhZGRpbmc9IjAiIGJvcmRlcj0iMCIgYWxpZ249ImNlbnRl
  297. ciI+DQo8dGJvZHk+PHRyPg0KPHRkIGNsYXNzPSJtY25UZXh0Q29udGVudCIgc3R5bGU9InBhZGRp
  298. bmctdG9wOjA7IHBhZGRpbmctcmlnaHQ6MThweDsgcGFkZGluZy1ib3R0b206OXB4OyBwYWRkaW5n
  299. LWxlZnQ6MThweDsiIHZhbGlnbj0idG9wIj4NCiAgIDxhIGhyZWY9Imh0dHA6Ly9iZXRoYW55LnN1
  300. L3Vuc3ViL3Vuc3ViLnBocCI+PHRhYmxlIHdpZHRoPSIwOCUiIGJvcmRlcj0iMCI+PHRib2R5Pjx0
  301. cj48dGQ+PC90ZD48dGQ+PC90ZD48L3RyPjwvdGJvZHk+PC90YWJsZT51bnN1YnNjcmliZSBmcm9t
  302. IHRoaXMgbGlzdDwvYT4uPGJyPg0KPC90ZD4NCjwvdHI+DQo8L3Rib2R5PjwvdGFibGU+DQo8L2Jv
  303. ZHk+DQo8L2h0bWw+DQo=`
  304. func TestHashBytes(t *testing.T) {
  305. var h HashKey
  306. h.Pack([]byte{222, 23, 3, 128, 1, 23, 3, 128, 1, 23, 3, 255, 1, 23, 3, 128})
  307. if h.String() != "3hcDgAEXA4ABFwP/ARcDgA" {
  308. t.Error("expecting 3hcDgAEXA4ABFwP/ARcDgA got", h.String())
  309. }
  310. }
  311. func TestChunkSaverWrite(t *testing.T) {
  312. // place the parse result in an envelope
  313. e := mail.NewEnvelope("127.0.0.1", 1)
  314. to, _ := mail.NewAddress("[email protected]")
  315. e.RcptTo = append(e.RcptTo, to)
  316. e.MailFrom, _ = mail.NewAddress("[email protected]")
  317. store := new(ChunkSaverMemory)
  318. chunkBuffer := NewChunkedBytesBufferMime()
  319. //chunkBuffer.setDatabase(store)
  320. // instantiate the chunk saver
  321. chunksaver := backends.Streamers["chunksaver"]()
  322. mimeanalyzer := backends.Streamers["mimeanalyzer"]()
  323. // add the default processor as the underlying processor for chunksaver
  324. // and chain it with mimeanalyzer.
  325. // Call order: mimeanalyzer -> chunksaver -> default (terminator)
  326. // This will also set our Open, Close and Initialize functions
  327. // we also inject a ChunkSaverStorage and a ChunkedBytesBufferMime
  328. stream := mimeanalyzer.Decorate(chunksaver.Decorate(backends.DefaultStreamProcessor{}, store, chunkBuffer))
  329. // configure the buffer cap
  330. bc := backends.BackendConfig{}
  331. bc["chunksaver_chunk_size"] = 8000
  332. bc["chunksaver_storage_engine"] = "memory"
  333. bc["chunksaver_compress_level"] = 0
  334. _ = backends.Svc.Initialize(bc)
  335. // give it the envelope with the parse results
  336. _ = chunksaver.Open(e)
  337. _ = mimeanalyzer.Open(e)
  338. buf := make([]byte, 128)
  339. if written, err := io.CopyBuffer(stream, bytes.NewBuffer([]byte(email3)), buf); err != nil {
  340. t.Error(err)
  341. } else {
  342. _ = mimeanalyzer.Close()
  343. _ = chunksaver.Close()
  344. fmt.Println("written:", written)
  345. total := 0
  346. for _, chunk := range store.chunks {
  347. total += len(chunk.data)
  348. }
  349. // 8A9m4qGsTU4wQB1wAgBEVw==
  350. fmt.Println("compressed", total, "saved:", written-int64(total))
  351. email, err := store.GetEmail(1)
  352. if err != nil {
  353. t.Error("email not found")
  354. return
  355. }
  356. // this should read all parts
  357. r, err := NewChunkMailReader(store, email, 0)
  358. if w, err := io.Copy(os.Stdout, r); err != nil {
  359. t.Error(err)
  360. } else if w != email.size {
  361. t.Error("email.size != number of bytes copied from reader")
  362. }
  363. // test the seek feature
  364. r, err = NewChunkMailReader(store, email, 0)
  365. if err != nil {
  366. t.Error(err)
  367. t.FailNow()
  368. }
  369. // we start from 1 because if the start from 0, all the parts will be read
  370. for i := 1; i < len(email.partsInfo.Parts); i++ {
  371. fmt.Println("seeking to", i)
  372. err = r.SeekPart(i)
  373. if err != nil {
  374. t.Error(err)
  375. }
  376. w, err := io.Copy(os.Stdout, r)
  377. if err != nil {
  378. t.Error(err)
  379. }
  380. if w != int64(email.partsInfo.Parts[i].Size) {
  381. t.Error("incorrect size, expecting", email.partsInfo.Parts[i].Size, "but read:", w)
  382. }
  383. }
  384. /*
  385. dr, err := NewChunkPartDecoder(store, email, 0)
  386. _ = dr
  387. if err != nil {
  388. t.Error(err)
  389. t.FailNow()
  390. }
  391. var decoded bytes.Buffer
  392. io.Copy(&decoded, dr)
  393. */
  394. }
  395. }