1/*
2 * Copyright 2010-2015 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Christophe Huriaux, c.huriaux@gmail.com
7 *		Adrien Destugues, pulkomandy@pulkomandy.tk
8 */
9
10
11#include <UrlContext.h>
12
13#include <stdio.h>
14
15#include <HashMap.h>
16#include <HashString.h>
17
18
19class BUrlContext::BHttpAuthenticationMap : public
20	SynchronizedHashMap<BPrivate::HashString, BHttpAuthentication*> {};
21
22
23BUrlContext::BUrlContext()
24	:
25	fCookieJar(),
26	fAuthenticationMap(NULL),
27	fCertificates(20, true),
28	fProxyHost(),
29	fProxyPort(0)
30{
31	fAuthenticationMap = new(std::nothrow) BHttpAuthenticationMap();
32
33	// This is the default authentication, used when nothing else is found.
34	// The empty string used as a key will match all the domain strings, once
35	// we have removed all components.
36	fAuthenticationMap->Put(HashString("", 0), new BHttpAuthentication());
37}
38
39
40BUrlContext::~BUrlContext()
41{
42	BHttpAuthenticationMap::Iterator iterator
43		= fAuthenticationMap->GetIterator();
44	while (iterator.HasNext())
45		delete iterator.Next().value;
46
47	delete fAuthenticationMap;
48}
49
50
51// #pragma mark Context modifiers
52
53
54void
55BUrlContext::SetCookieJar(const BNetworkCookieJar& cookieJar)
56{
57	fCookieJar = cookieJar;
58}
59
60
61void
62BUrlContext::AddAuthentication(const BUrl& url,
63	const BHttpAuthentication& authentication)
64{
65	BString domain = url.Host();
66	domain += url.Path();
67	BPrivate::HashString hostHash(domain.String(), domain.Length());
68
69	fAuthenticationMap->Lock();
70
71	BHttpAuthentication* previous = fAuthenticationMap->Get(hostHash);
72
73	if (previous)
74		*previous = authentication;
75	else {
76		BHttpAuthentication* copy
77			= new(std::nothrow) BHttpAuthentication(authentication);
78		fAuthenticationMap->Put(hostHash, copy);
79	}
80
81	fAuthenticationMap->Unlock();
82}
83
84
85void
86BUrlContext::SetProxy(BString host, uint16 port)
87{
88	fProxyHost = host;
89	fProxyPort = port;
90}
91
92
93void
94BUrlContext::AddCertificateException(const BCertificate& certificate)
95{
96	BCertificate* copy = new(std::nothrow) BCertificate(certificate);
97	if (copy != NULL) {
98		fCertificates.AddItem(copy);
99	}
100}
101
102
103// #pragma mark Context accessors
104
105
106BNetworkCookieJar&
107BUrlContext::GetCookieJar()
108{
109	return fCookieJar;
110}
111
112
113BHttpAuthentication&
114BUrlContext::GetAuthentication(const BUrl& url)
115{
116	BString domain = url.Host();
117	domain += url.Path();
118
119	BHttpAuthentication* authentication = NULL;
120
121	do {
122		authentication = fAuthenticationMap->Get( HashString(domain.String(),
123			domain.Length()));
124
125		domain.Truncate(domain.FindLast('/'));
126
127	} while (authentication == NULL);
128
129	return *authentication;
130}
131
132
133bool
134BUrlContext::UseProxy()
135{
136	return !fProxyHost.IsEmpty();
137}
138
139
140BString
141BUrlContext::GetProxyHost()
142{
143	return fProxyHost;
144}
145
146
147uint16
148BUrlContext::GetProxyPort()
149{
150	return fProxyPort;
151}
152
153
154bool
155BUrlContext::HasCertificateException(const BCertificate& certificate)
156{
157	struct Equals: public UnaryPredicate<const BCertificate> {
158		Equals(const BCertificate& itemToMatch)
159			:
160			fItemToMatch(itemToMatch)
161		{
162		}
163
164		int operator()(const BCertificate* item) const
165		{
166			/* Must return 0 if there is a match! */
167			return !(*item == fItemToMatch);
168		}
169
170		const BCertificate& fItemToMatch;
171	} comparator(certificate);
172
173	return fCertificates.FindIf(comparator) != NULL;
174}
175