Core/POP3 (thanks Oblivion!)

git-svn-id: svn://ultimatepp.org/upp/trunk@7091 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2014-03-25 08:26:45 +00:00
parent 2798ebc2ed
commit d9c8f2a532
8 changed files with 690 additions and 0 deletions

View file

@ -0,0 +1,86 @@
#include "POP3.h"
bool InetMessage::ReadHeader(VectorMap<String, String>& hdr, StringStream& ss)
{
for(;;) {
if(ss.IsEof())
return false;
String s = ss.GetLine();
if(s.IsEmpty())
return true;
if(s[0] == ' ' || s[0] == '\t') {
if(hdr.GetCount())
hdr.Top().Cat(TrimLeft(s.Mid(1)));
}
else {
int q = s.Find(':');
if(q >= 0)
hdr.Add(ToLower(s.Mid(0, q)), TrimLeft(s.Mid(q + 1)));
}
}
}
bool InetMessage::ReadHeader(const String& s)
{
part.Clear();
header.Clear();
StringStream ss(s);
return ReadHeader(header, ss);
}
bool InetMessage::Read(const String& s)
{
part.Clear();
header.Clear();
StringStream ss(s);
if(!ReadHeader(header, ss))
return false;
String type = header.Get("content-type");
if(!type.StartsWith("multipart")) {
part.Add().body = LoadStream(ss);
return true;
}
String boundary;
int q = type.Find("boundary=");
if(q < 0)
return false;
q += strlen("boundary=");
int qq = type.Find(";", q);
if(qq >= 0)
boundary = type.Mid(q, qq);
else
boundary = type.Mid(q);
if(*boundary == '\"')
boundary = boundary.Mid(1);
if(*boundary.Last() == '\"')
boundary.Trim(boundary.GetCount() - 1);
boundary = "--" + boundary;
String end_boundary = boundary + "--";
for(;;) {
String ln = ss.GetLine();
if(ln == boundary)
break;
if(ss.IsEof())
return false;
}
for(;;) {
Part& p = part.Add();
if(!ReadHeader(p.header, ss))
return false;
for(;;) {
if(ss.IsEof())
return false;
String ln = ss.GetLine();
if(ln == boundary)
break;
if(ln == end_boundary)
return true;
p.body << ln << "\r\n";
}
}
}

238
uppsrc/Core/POP3/POP3.cpp Normal file
View file

@ -0,0 +1,238 @@
#include "POP3.h"
static bool sPop3Trace;
#define LLOG(x) do { if(sPop3Trace) RLOG(x); } while(0)
void Pop3::Trace(bool b)
{
sPop3Trace = b;
}
String Pop3::GetTimeStamp()
{
int begin = data.Find('<');
if(begin >= 0) {
int end = data.Find('>', begin);
if(end > begin) {
end++;
return data.Mid(begin, end - begin);
}
}
return Null;
}
bool Pop3::GetListItems(ValueMap& list, dword type1, dword type2)
{
StringStream s(data);
for(;;) {
String line = s.GetLine();
if(s.IsError())
return false;
if(s.IsEof())
break;
Vector<String> s = Split(line, ' ');
if(s.GetCount() < 2)
return false;
list.Add(Scan(type1, s[0]), Scan(type2, s[1]));
}
return true;
}
int Pop3::GetMessageCount()
{
if(!PutGet("STAT\r\n"))
return Null;
String ok, cnt, tsz;
if(!SplitTo(data, ' ', ok, cnt, tsz))
return Null;
return StrInt(cnt);
}
String Pop3::GetMessage(int index)
{
if(!PutGet(Format("RETR %d\r\n", index), true))
return Null;
return data;
}
String Pop3::GetMessageHeader(int index)
{
if(!PutGet(Format("TOP %d %d\r\n", index, 0), true))
return Null;
return data;
}
bool Pop3::GetMessageList(ValueMap& list)
{
VectorMap<int, unsigned int> v;
if(!PutGet("LIST\r\n", true))
return false;
return GetListItems(list, INT_V, INT_V);
}
String Pop3::GetMessageUniqueId(int index)
{
if(!PutGet(Format("UIDL %d\r\n", index)))
return Null;
String ok, id, tsz;
if(!SplitTo(data, ' ', ok, id, tsz))
return Null;
return id;
}
bool Pop3::GetMessageUniqueIds(ValueMap& uids)
{
if(!PutGet("UIDL\r\n", true))
return false;
return GetListItems(uids, INT_V, STRING_V);
}
bool Pop3::RemoveMessage(int index)
{
return PutGet(Format("DELE %d\r\n", index));
}
bool Pop3::Undo()
{
return PutGet("RSET\r\n");
}
bool Pop3::Noop()
{
return PutGet("NOOP\r\n");
}
String Pop3::GetDataLine()
{
// We can't use TcpSocket::GetLine(), since it omits carriage returns we need.
String line;
for(;;) {
int c = Get();
if(c < 0) {
if(!IsError())
continue;
return String::GetVoid();
}
line.Cat(c);
if(line.EndsWith("\r\n"))
return line;
}
}
bool Pop3::PutGet(const String& s, bool multiline, bool nolog)
{
// Put() request.
if(!s.IsEmpty()) {
if(!nolog)
LLOG(">> " << TrimRight(s));
if(!PutAll(s)) {
LLOG("-- " << GetLastError());
return false;
}
}
// Get() respone.
data.Clear();
String line = GetDataLine();
if(!line.IsEmpty()) {
LLOG("<< " << TrimRight(line));
if(line.StartsWith("+OK")) {
if(!multiline) {
data << line;
return true;
}
else
for(;;) {
line = GetDataLine();
if(line.IsEmpty())
break;
if(line.StartsWith(".."))
line.Remove(0);
data << line;
if(!data.EndsWith("\r\n.\r\n"))
continue;
LLOG("<< ...");
return true;
}
}
else
if(line.StartsWith("-ERR"))
error = line;
}
LLOG("-- " << GetLastError());
return false;
}
bool Pop3::Authenticate()
{
// Try using APOP authentication.
String timestamp = GetTimeStamp();
if(!timestamp.IsEmpty()) {
if(PutGet("APOP " + user + " " + MD5String(timestamp << pass) + "\r\n"))
return true;
}
else
if(PutGet("USER " + user + "\r\n")) {
LLOG(">>PASS ******");
if(PutGet("PASS " + pass + "\r\n", false, true))
return true;
}
return false;
}
bool Pop3::Login()
{
try {
if(host.IsEmpty())
throw Exc(t_("Hostname is not specified."));
if(user.IsEmpty())
throw Exc(t_("Username is not specified."));
if(pass.IsEmpty())
throw Exc(t_("Password is nor specified."));
if(!Connect(host, Nvl(port, ssl ? 995 : 110)))
throw Exc(GetErrorDesc());
LLOG(Format(t_("Opening connection to %s:%d."), host, port));
if(ssl) {
if(!StartSSL())
throw Exc(t_("Couldn't start SSL session."));
LLOG(t_("SSL session successfully started."));
}
// Receive server greetings.
if(!PutGet(Null))
throw Exc(GetLastError());
if(!Authenticate())
throw Exc(GetLastError());
}
catch (Exc e) {
error = e;
LLOG("-- " + e);
Logout();
return false;
}
return online = true;
}
bool Pop3::Logout()
{
if(IsOnline())
PutGet("QUIT\r\n");
LLOG(Format(t_("Closing connection to %s:%d."), host, port));
Close();
online = false;
return true;
}
Pop3::Pop3()
{
ssl = false;
online = false;
Timeout(60000);
}
Pop3::~Pop3()
{
if(IsOpen())
Close();
}

75
uppsrc/Core/POP3/POP3.h Normal file
View file

@ -0,0 +1,75 @@
#ifndef _POP3_POP3_h
#define _POP3_POP3_h
#include <Core/Core.h>
using namespace Upp;
class Pop3 : public TcpSocket
{
String host;
String user;
String pass;
String error;
String data;
int port;
bool ssl;
bool online;
bool GetListItems(ValueMap& list, dword type1, dword type2);
String GetTimeStamp();
bool Authenticate();
String GetDataLine();
bool PutGet(const String& s, bool multiline = false, bool nolog = false);
public:
Pop3& Host(const String& h) { host = h; return *this; }
Pop3& Port(int p) { port = p; return *this; }
Pop3& User(const String& u, const String& p) { user = u; pass = p; return *this; }
Pop3& SSL(bool b = true) { ssl = b; return *this; }
int GetMessageCount();
String GetMessage(int index);
String GetMessageHeader(int index);
bool RemoveMessage(int index);
bool GetMessageList(ValueMap& list);
String GetMessageUniqueId(int index);
bool GetMessageUniqueIds(ValueMap& uids);
bool Undo();
bool Noop();
bool Login();
bool Logout();
bool IsOnline() const { return online; }
String GetLastError() { return IsError() ? GetErrorDesc() : error; }
static void Trace(bool b = true);
Pop3();
~Pop3();
};
struct InetMessage {
struct Part : Moveable<Part> {
VectorMap<String, String> header;
String body;
};
VectorMap<String, String> header;
Vector<Part> part;
bool Read(const String& msg);
bool ReadHeader(const String& msg);
String operator[](const char *id) const { return header.Get(id, Null); }
int GetPartCount() const { return part.GetCount(); }
String GetPartBody(int i) const { return part[i].body; }
String GetPartHeader(int i, const char *id) { return part[i].header.Get(id, Null); }
private:
bool ReadHeader(VectorMap<String, String>& hdr, StringStream& ss);
};
#endif

15
uppsrc/Core/POP3/POP3.upp Normal file
View file

@ -0,0 +1,15 @@
description "Post Office Protocol, version 3 encapsulation. Author: İsmail Yılmaz\377";
uses
Core,
Core/SSL;
file
POP3.h,
POP3.cpp,
InetMessage.cpp,
src.tpp;
mainconfig
"" = "";

5
uppsrc/Core/POP3/init Normal file
View file

@ -0,0 +1,5 @@
#ifndef _Core_POP3_icpp_init_stub
#define _Core_POP3_icpp_init_stub
#include "Core/init"
#include "Core/SSL/init"
#endif

View file

@ -0,0 +1,68 @@
topic "struct InetMessage";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,2#27521748481378242620020725143825:desc]
[0 $$3,0#96390100711032703541132217272105:end]
[H6;0 $$4,0#05600065144404261032431302351956:begin]
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item]
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement]
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[{_}
[ {{10000@(113.42.0) [s0;%% [*@7;4 InetMessage]]}}&]
[s0;i448;a25;kKO9;@(0.0.255) &]
[s0;i448;a25;kKO9; [@(0.0.255)3 struct][3 _][*3 InetMessage]&]
[s2; This is helper class intended for parsing Pop3 (or generally,
RFC822) messages. It parses messages to header map and one or
multiple (for multipart content) parts. Header names are converted
to lower`-case before being stored to map.&]
[s0;i448;a25;kKO9;:noref:@(0.0.255) &]
[ {{10000F(128)G(128)@1 [s0;%% [* Public Members List]]}}&]
[s3; &]
[s5;:InetMessage`:`:header: [_^VectorMap^ VectorMap]<[_^String^ String],
[_^String^ String]>_[* header]&]
[s2;%% Map of header fields.&]
[s3; &]
[s4; &]
[s5;:InetMessage`:`:part: [_^Vector^ Vector]<[_^InetMessage`:`:Part^ Part]>_[* part]&]
[s2;%% Message parts. Part is defined as&]
[s2;%% [C1 -|struct Part : Moveable<Part> `{]&]
[s2;%% [C1 -|-|VectorMap<String, String> header;]&]
[s2;%% [C1 -|-|String body;]&]
[s2;%% [C1 -|`};]&]
[s3; &]
[s4; &]
[s5;:InetMessage`:`:Read`(const String`&`): [@(0.0.255) bool]_[* Read]([@(0.0.255) const]_[_^String^ S
tring][@(0.0.255) `&]_[*@3 msg])&]
[s2;%% Attempts to parse the whole message. Returns true on success.&]
[s3;%% &]
[s4;%% &]
[s5;:InetMessage`:`:ReadHeader`(const String`&`): [@(0.0.255) bool]_[* ReadHeader]([@(0.0.255) c
onst]_[_^String^ String][@(0.0.255) `&]_[*@3 msg])&]
[s2;%% Attempts to parse only the message header (part is left empty).
Returns true on success.&]
[s3;%% &]
[s4;%% &]
[s5;:InetMessage`:`:operator`[`]`(const char`*`)const: [_^String^ String]_[* operator`[`]
]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&]
[s2;%% Returns the value of header field or empty String if header
field is not present. [%-*@3 id] should be lower`-case (as all
header names are converted to lower`-case by Read).&]
[s3;%% &]
[s4;%% &]
[s5;:InetMessage`:`:GetPartCount`(`)const: [@(0.0.255) int]_[* GetPartCount]()_[@(0.0.255) c
onst]&]
[s2;%% Returns the number of message parts. This is 1 for non`-multipart
message.&]
[s3;%% &]
[s4;%% &]
[s5;:InetMessage`:`:GetPartBody`(int`)const: [_^String^ String]_[* GetPartBody]([@(0.0.255) i
nt]_[*@3 i])_[@(0.0.255) const]&]
[s2;%% Returns the body of part [%-*@3 i].&]
[s3;%% &]
[s4;%% &]
[s5;:InetMessage`:`:GetPartHeader`(int`,const char`*`): [_^String^ String]_[* GetPartHead
er]([@(0.0.255) int]_[*@3 i], [@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])&]
[s2;%% Returns header [%-*@3 id] for part [%-*@3 i].&]
[s3;%% ]]

View file

@ -0,0 +1,141 @@
topic "POP3";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,2#27521748481378242620020725143825:desc]
[0 $$3,0#96390100711032703541132217272105:end]
[H6;0 $$4,0#05600065144404261032431302351956:begin]
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item]
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement]
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[{_}
[ {{10000@(113.42.0) [s0;%% [*@7;4 Pop3]]}}&]
[s1;@(0.0.255)3 &]
[s1;:Pop3`:`:class: [@(0.0.255)3 class][3 _][*3 Pop3][3 _:_][@(0.0.255)3 public][3 _][*@3;3 TcpSocke
t]&]
[s2;%% Encapsulates the Post Office Protocol, Version 3 (POP3) as
specified in the [^http`:`/`/tools`.ietf`.org`/html`/rfc1939^ RFC
1939]. This class provides a simplified interface to a single
POP3 mailbox.&]
[s2;%% Important: Pop3 indicies are 1 based! Thus the correct loop
to obtain all messages is for(int i `= 1; i <`= pop3.GetMessageCount();
i`+`+).&]
[s2;%% &]
[s6;%% Requires OpenSSL library.&]
[s3; &]
[ {{10000F(128)G(128)@1 [s0;%% [* Public Method List]]}}&]
[s0; &]
[s5;:Pop3`:`:Host`(const String`&`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Host]([@(0.0.255) const
]_[_^String^ String][@(0.0.255) `&]_[*@3 h])&]
[s2;%% Sets hostname. Returns `*this for method chaining.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:Port`(int`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* Port]([@(0.0.255) int]_[*@3 p])&]
[s2;%% Sets port number. Returns `*this for method chaining.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:User`(const String`&`,const String`&`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* User](
[@(0.0.255) const]_[_^String^ String][@(0.0.255) `&]_[*@3 u], [@(0.0.255) const]_[_^String^ S
tring][@(0.0.255) `&]_[*@3 p])&]
[s2;%% Sets username and password. Returns `*this for method chaining.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:SSL`(bool`): [_^Pop3^ Pop3][@(0.0.255) `&]_[* SSL]([@(0.0.255) bool]_[*@3 b]_`=_[@(0.0.255) t
rue])&]
[s2;%% Activates POP3S mode (using SSL). Requires Core/SSL package.
Returns `*this for method chaining.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:GetMessageCount`(`): [@(0.0.255) int]_[* GetMessageCount]()&]
[s2;%% Returns the number of currently available messages in the
POP3 mailbox. Returns `-1 on failure.&]
[s3; &]
[s4; &]
[s5;:Pop3`:`:GetMessage`(int`): [_^String^ String]_[* GetMessage]([@(0.0.255) int]_[*@3 index
])&]
[s2;%% Retreives a message with the given [%-*@3 index] from the POP3
mailbox. Returns Null on failure. First message has index 1,
last GetMessageCount().&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:GetMessageHeader`(int`): [_^String^ String]_[* GetMessageHeader]([@(0.0.255) i
nt]_[*@3 index])&]
[s2;%% Retreives the header section of a message with the given [%-*@3 index]
from the POP3 mailbox. Returns Null on failure. First message
has index 1, last GetMessageCount().&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:GetMessageList`(ValueMap`&`): [@(0.0.255) bool]_[* GetMessageList]([_^ValueMap^ V
alueMap][@(0.0.255) `&]_[*@3 list])&]
[s2;%% Retrieves the list of currently available messages in the
POP3 mailbox. [%-*@3 list] is a ValueMap containing messages indices
and sizes as integer key and integer value pairs. Returns true
on success.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:GetMessageUniqueId`(int`): [_^String^ String]_[* GetMessageUniqueId]([@(0.0.255) i
nt]_[*@3 index])&]
[s2;%% Retreives the unique identifier string of a message with the
given [%-*@3 index] from the POP3 mailbox. Returns Null on failure.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:GetMessageUniqueIds`(ValueMap`&`): [@(0.0.255) bool]_[* GetMessageUniqueIds](
[_^topic`:`/`/Core`/src`/ValueMap`$en`-us`#ValueMap`:`:class^ ValueMap][@(0.0.255) `&
]_[*@3 uids])&]
[s2;%% Retrieves the unique identifier strings of currently available
messages in the POP3 mailbox. [%-*@3 uids] is a ValueMap containing
messages indices and unique identifiers as integer key and String
value pairs. Returns true on success.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:RemoveMessage`(int`): [@(0.0.255) bool]_[* RemoveMessage]([@(0.0.255) int]_[*@3 i
ndex])&]
[s2;%% Marks a message with the given [%-*@3 index] to be deleted from
the POP3 mailbox. Messages marked for deletion are only deleted
by the POP3 server after a successful [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Logout`(`)^ L
ogout()]. If you want to unmark messages, you must invoke [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Undo`(`)^ U
ndo()] method before logging out. Returns true on success. &]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:Undo`(`): [@(0.0.255) bool]_[* Undo]()&]
[s2;%% Resets POP3 session. Useful for unmarking the messages marked
to be deleted. This method must be invoked before any [^topic`:`/`/POP3`/src`/Pop3`$en`-us`#Pop3`:`:Logout`(`)^ L
ogout()]. Returns true on success.&]
[s3;%% &]
[s4; &]
[s5;:Pop3`:`:Noop`(`): [@(0.0.255) bool]_[* Noop]()&]
[s2;%% Sends a NOOP command to the POP3 server. Useful for keeping
connections alive.&]
[s3; &]
[s4; &]
[s5;:Pop3`:`:Login`(`): [@(0.0.255) bool]_[* Login]()&]
[s2;%% Connect and login to the POP3 server. User name and password
must be set. Uses APOP authentication mechanism, if available.
Returns true on success.&]
[s3; &]
[s4; &]
[s5;:Pop3`:`:Logout`(`): [@(0.0.255) bool]_[* Logout]()&]
[s2;%% Logout of and disconnect from the POP3 server. Messages marked
for deletion will be permanently deleted from the server after
a successful logout. Returns true on success.&]
[s3; &]
[s4; &]
[s5;:Pop3`:`:IsOnline`(`)const: [@(0.0.255) bool]_[* IsOnline]()_[@(0.0.255) const]&]
[s2;%% Returns true if the POP3 mailbox is online. &]
[s3; &]
[s4; &]
[s5;:Pop3`:`:GetLastError`(`): [_^String^ String]_[* GetLastError]()&]
[s2;%% Returns the description of last error.&]
[s3; &]
[s4; &]
[s5;:Pop3`:`:Trace`(bool`): [@(0.0.255) static] [@(0.0.255) void]_[* Trace]([@(0.0.255) bool]_
[*@3 b]_`=_[@(0.0.255) true])&]
[s2;%% Activates logging of POP3.&]
[s3;%% &]
[ {{10000F(128)G(128)@1 [s0;%% [* Constructor detail]]}}&]
[s0; &]
[s5;:Pop3`:`:Pop3`(`): [* Pop3]()&]
[s2;%% Default constructor.&]
[s3; &]
[s0;%% ]]

View file

@ -0,0 +1,62 @@
topic "";
[2 $$0,0#00000000000000000000000000000000:Default]
[i448;a25;kKO9;2 $$1,0#37138531426314131252341829483380:class]
[l288;2 $$2,2#27521748481378242620020725143825:desc]
[0 $$3,0#96390100711032703541132217272105:end]
[H6;0 $$4,0#05600065144404261032431302351956:begin]
[i448;a25;kKO9;2 $$5,0#37138531426314131252341829483370:item]
[l288;a4;*@5;1 $$6,6#70004532496200323422659154056402:requirement]
[l288;i1121;b17;O9;~~~.1408;2 $$7,0#10431211400427159095818037425705:param]
[i448;b42;O9;2 $$8,8#61672508125594000341940100500538:tparam]
[b42;2 $$9,9#13035079074754324216151401829390:normal]
[{_}
[ {{10000@(113.42.0) [s0;%% [*@7;4 InetHeader]]}}&]
[s3; &]
[s1;:InetHeader`:`:struct: [@(0.0.255)3 struct][3 _][*3 InetHeader]&]
[s2;%% InetHeader is a simple helper class for parsing internet header
texts (RFC822). In addition, InetHeader also detects `"set`-cookie`"
headers and parses the content according to cookie syntax (this
can be ignored if header is not HTTP related).&]
[s3; &]
[ {{10000F(128)G(128)@1 [s0;%% [* Public Member List]]}}&]
[s3; &]
[s5;:InetHeader`:`:fields: [_^VectorMap^ VectorMap]<[_^String^ String],
[_^String^ String]>_[* fields]&]
[s2;%% Http fields as key`-value pairs. Keys are converted to lower`-case.
Note that the same key can be present multiple times.&]
[s3; &]
[s4; &]
[s5;:InetHeader`:`:cookies: [_^VectorMap^ VectorMap]<[_^String^ String],
[_^HttpCookie^ HttpCookie]>_[* cookies]&]
[s2;%% Set of http response http cookies (filled based on Set`-Cookie
headers during parsing).&]
[s3; &]
[s4; &]
[s5;:InetHeader`:`:Clear`(`): [@(0.0.255) void]_[* Clear]()&]
[s2;%% Clears data.&]
[s3; &]
[s4; &]
[s5;:InetHeader`:`:ParseAdd`(const String`&`): [@(0.0.255) bool]_[* ParseAdd]([@(0.0.255) c
onst]_[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&]
[s2;%% Parses the header (all lines of header) into [* first`_line
]and [* fields].&]
[s3;%% &]
[s4; &]
[s5;:InetHeader`:`:Parse`(const String`&`): [@(0.0.255) bool]_[* Parse]([@(0.0.255) const]_
[_^String^ String][@(0.0.255) `&]_[*@3 hdrs])&]
[s2;%% Calls Clear and parses the header (all lines of header) into
[* first`_line ]and [* fields].&]
[s3;%% &]
[s4; &]
[s5;:InetHeader`:`:GetCookie`(const char`*`)const: [_^String^ String]_[* GetCookie]([@(0.0.255) c
onst]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&]
[s2;%% Returns the value of first cookie of response (set by Set`-Cookie)
with name [%-*@3 id].&]
[s3;%% &]
[s4;%% &]
[s5;:InetHeader`:`:operator`[`]`(const char`*`)const: [_^String^ String]_[* operator`[`]](
[@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 id])_[@(0.0.255) const]&]
[s2;%% Returns the first http header field with key [%-*@3 id] (must
be lower`-case) or empty string if such field is not present.&]
[s3;%% &]
[s0;%% ]]