Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2010-2025 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
*/
package com.marklogic.client;

import java.util.concurrent.TimeUnit;

/**
* ClientCookie is a wrapper around the Cookie implementation so that the
* underlying implementation can be changed.
*
*/
public class ClientCookie {

private final String name;
private final String value;
private final long expiresAt;
private final String domain;
private final String path;
private final boolean secure;

public ClientCookie(String name, String value, long expiresAt, String domain, String path, boolean secure) {
this.name = name;
this.value = value;
this.expiresAt = expiresAt;
this.domain = domain;
this.path = path;
this.secure = secure;
}

public boolean isSecure() {
return secure;
}

public String getPath() {
return path;
}

public String getDomain() {
return domain;
}

public long expiresAt() {
return expiresAt;
}

public String getName() {
return name;
}

public int getMaxAge() {
return (int) TimeUnit.MILLISECONDS.toSeconds(expiresAt - System.currentTimeMillis());
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
*/
package com.marklogic.client;

import com.marklogic.client.impl.ClientCookie;
import com.marklogic.client.io.marker.StructureReadHandle;

import java.util.List;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@ public OkHttpServices(ConnectionConfig connectionConfig) {
this.okHttpClient = connect(connectionConfig);
}

private static ClientCookie parseClientCookie(HttpUrl url, String setCookieHeaderValue) {
Cookie cookie = Cookie.parse(url, setCookieHeaderValue);
if(cookie == null) throw new IllegalStateException(setCookieHeaderValue + " is not a well-formed cookie");
return new ClientCookie(cookie.name(), cookie.value(), cookie.expiresAt(), cookie.domain(), cookie.path(),
cookie.secure());
}

private FailedRequest extractErrorFields(Response response) {
if (response == null) return null;
try {
Expand Down Expand Up @@ -1501,7 +1508,7 @@ public Response apply(Request.Builder funcBuilder) {
String location = response.headers().get("Location");
List<ClientCookie> cookies = new ArrayList<>();
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
ClientCookie cookie = ClientCookie.parse(requestBldr.build().url(), setCookie);
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
cookies.add(cookie);
}
closeResponse(response);
Expand Down Expand Up @@ -5599,7 +5606,7 @@ private void executeRequest(CallResponseImpl responseImpl) {
if (session != null) {
List<ClientCookie> cookies = new ArrayList<>();
for (String setCookie : response.headers(HEADER_SET_COOKIE)) {
ClientCookie cookie = ClientCookie.parse(requestBldr.build().url(), setCookie);
ClientCookie cookie = parseClientCookie(requestBldr.build().url(), setCookie);
cookies.add(cookie);
}
((SessionStateImpl) session).setCookies(cookies);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*/
package com.marklogic.client.impl;

import com.marklogic.client.ClientCookie;
import com.marklogic.client.SessionState;

import java.util.ArrayList;
Expand All @@ -12,43 +13,42 @@
import java.util.concurrent.atomic.AtomicBoolean;

public class SessionStateImpl implements SessionState {
private List<ClientCookie> cookies;
private String sessionId;
private AtomicBoolean setCreatedTimestamp;
private Calendar created;

public SessionStateImpl() {
sessionId = Long.toUnsignedString(ThreadLocalRandom.current().nextLong(), 16);
cookies = new ArrayList<>();
setCreatedTimestamp = new AtomicBoolean(false);
}

@Override
public String getSessionId() {
return sessionId;
}

List<ClientCookie> getCookies() {
return cookies;
}

void setCookies(List<ClientCookie> cookies) {
if ( cookies != null ) {
if(setCreatedTimestamp.compareAndSet(false, true)) {
for (ClientCookie cookie : cookies) {
// Drop the SessionId cookie received from the server. We add it every
// time we make a request with a SessionState object passed
if(cookie.getName().equalsIgnoreCase("SessionId")) continue;
// make a clone to ensure we're not holding on to any resources
// related to an HTTP connection that need to be released
this.cookies.add(new ClientCookie(cookie));
}
created = Calendar.getInstance();
}
}
}

Calendar getCreatedTimestamp() {
return created;
}

private List<ClientCookie> cookies;
private String sessionId;
private AtomicBoolean setCreatedTimestamp;
private Calendar created;

public SessionStateImpl() {
sessionId = Long.toUnsignedString(ThreadLocalRandom.current().nextLong(), 16);
cookies = new ArrayList<>();
setCreatedTimestamp = new AtomicBoolean(false);
}

@Override
public String getSessionId() {
return sessionId;
}

List<ClientCookie> getCookies() {
return cookies;
}

void setCookies(List<ClientCookie> cookies) {
if (cookies != null) {
if (setCreatedTimestamp.compareAndSet(false, true)) {
for (ClientCookie cookie : cookies) {
// Drop the SessionId cookie received from the server. We add it every
// time we make a request with a SessionState object passed
if (cookie.getName().equalsIgnoreCase("SessionId")) continue;
this.cookies.add(cookie);
}
created = Calendar.getInstance();
}
}
}

Calendar getCreatedTimestamp() {
return created;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
package com.marklogic.client.impl;

import com.marklogic.client.impl.ClientCookie;
import com.marklogic.client.ClientCookie;
import com.marklogic.client.FailedRequestException;
import com.marklogic.client.ForbiddenUserException;
import com.marklogic.client.Transaction;
Expand All @@ -19,7 +19,7 @@ class TransactionImpl implements Transaction {
private RESTServices services;
private String transactionId;
private String hostId;
// we keep cookies scoped with each tranasaction to work with load balancers
// we keep cookies scoped with each transaction to work with load balancers
// that need to keep requests for one transaction on a specific MarkLogic Server host
private List<ClientCookie> cookies = new ArrayList<>();
private Calendar created;
Expand All @@ -29,9 +29,7 @@ class TransactionImpl implements Transaction {
this.transactionId = transactionId;
if ( cookies != null ) {
for (ClientCookie cookie : cookies) {
// make a clone to ensure we're not holding on to any resources
// related to an HTTP connection that need to be released
this.cookies.add(new ClientCookie(cookie));
this.cookies.add(cookie);
if ( "HostId".equalsIgnoreCase(cookie.getName()) ) {
hostId = cookie.getValue();
}
Expand All @@ -44,9 +42,6 @@ class TransactionImpl implements Transaction {
public String getTransactionId() {
return transactionId;
}
public void setTransactionId(String transactionId) {
this.transactionId = transactionId;
}

@Override
public List<ClientCookie> getCookies() {
Expand All @@ -57,9 +52,6 @@ public List<ClientCookie> getCookies() {
public String getHostId() {
return hostId;
}
protected void setHostId(String hostId) {
this.hostId = hostId;
}

public Calendar getCreatedTimestamp() {
return created;
Expand Down