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