2 * Copyright (C) 2015 Apple, Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 static Vector<uint16_t> portVectorFromList(NSArray<NSNumber *> *portList)
33 Vector<uint16_t> ports;
34 ports.reserveInitialCapacity(portList.count);
36 for (NSNumber *port : portList)
37 ports.uncheckedAppend(port.unsignedShortValue);
42 static NSString *portStringFromVector(const Vector<uint16_t>& ports)
47 auto *string = [NSMutableString stringWithCapacity:ports.size() * 5];
49 for (size_t i = 0; i < ports.size() - 1; ++i)
50 [string appendFormat:@"%" PRIu16 ", ", ports[i]];
52 [string appendFormat:@"%" PRIu16, ports.last()];
57 static double cookieCreated(NSHTTPCookie *cookie)
59 id value = cookie.properties[@"Created"];
61 auto toCanonicalFormat = [](double referenceFormat) {
62 return 1000.0 * (referenceFormat + NSTimeIntervalSince1970);
65 if ([value isKindOfClass:[NSNumber class]])
66 return toCanonicalFormat(((NSNumber *)value).doubleValue);
68 if ([value isKindOfClass:[NSString class]])
69 return toCanonicalFormat(((NSString *)value).doubleValue);
74 Cookie::Cookie(NSHTTPCookie *cookie)
75 : Cookie(cookie.name, cookie.value, cookie.domain, cookie.path, cookieCreated(cookie), [cookie.expiresDate timeIntervalSince1970] * 1000.0,
76 cookie.HTTPOnly, cookie.secure, cookie.sessionOnly, cookie.comment, cookie.commentURL, portVectorFromList(cookie.portList))
80 Cookie::operator NSHTTPCookie *() const
85 // FIXME: existing APIs do not provide a way to set httpOnly without parsing headers from scratch.
87 NSMutableDictionary *properties = [NSMutableDictionary dictionaryWithCapacity:11];
89 if (!comment.isNull())
90 [properties setObject:(NSString *)comment forKey:NSHTTPCookieComment];
92 if (!commentURL.isNull())
93 [properties setObject:(NSURL *)commentURL forKey:NSHTTPCookieCommentURL];
96 [properties setObject:(NSString *)domain forKey:NSHTTPCookieDomain];
99 [properties setObject:(NSString *)name forKey:NSHTTPCookieName];
102 [properties setObject:(NSString *)path forKey:NSHTTPCookiePath];
105 [properties setObject:(NSString *)value forKey:NSHTTPCookieValue];
107 NSDate *expirationDate = [NSDate dateWithTimeIntervalSince1970:expires / 1000.0];
108 auto maxAge = [expirationDate timeIntervalSinceNow];
110 [properties setObject:[NSString stringWithFormat:@"%f", maxAge] forKey:NSHTTPCookieMaximumAge];
112 auto* portString = portStringFromVector(ports);
114 [properties setObject:portString forKey:NSHTTPCookiePort];
117 [properties setObject:@YES forKey:NSHTTPCookieSecure];
120 [properties setObject:@YES forKey:NSHTTPCookieDiscard];
122 [properties setObject:@"1" forKey:NSHTTPCookieVersion];
124 return [NSHTTPCookie cookieWithProperties:properties];
127 bool Cookie::operator==(const Cookie& other) const
129 ASSERT(!name.isHashTableDeletedValue());
130 bool thisNull = isNull();
131 bool otherNull = other.isNull();
132 if (thisNull || otherNull)
133 return thisNull == otherNull;
135 NSHTTPCookie *nsCookie(*this);
136 return [nsCookie isEqual:other];
139 unsigned Cookie::hash() const
141 ASSERT(!name.isHashTableDeletedValue());
143 NSHTTPCookie *nsCookie(*this);
144 return nsCookie.hash;
147 } // namespace WebCore