001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.server.ldap; 021 022 023import org.apache.commons.lang3.StringUtils; 024import org.apache.directory.api.ldap.model.csn.Csn; 025import org.apache.directory.api.ldap.model.message.Request; 026import org.apache.directory.api.ldap.model.message.Response; 027import org.apache.directory.api.util.Strings; 028import org.apache.directory.server.core.api.interceptor.context.OperationContext; 029import org.slf4j.Logger; 030import org.slf4j.LoggerFactory; 031 032 033/** 034 * Utility methods used by the LDAP protocol service. 035 * 036 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 037 */ 038public final class LdapProtocolUtils 039{ 040 /** A delimiter for the replicaId */ 041 public static final String COOKIE_DELIM = ","; 042 043 /** the prefix for replicaId value */ 044 public static final String REPLICA_ID_PREFIX = "rid="; 045 046 public static final int REPLICA_ID_PREFIX_LEN = REPLICA_ID_PREFIX.length(); 047 048 /** the prefix for Csn value */ 049 public static final String CSN_PREFIX = "csn="; 050 051 private static final int CSN_PREFIX_LEN = CSN_PREFIX.length(); 052 053 private static final Logger LOG = LoggerFactory.getLogger( LdapProtocolUtils.class ); 054 055 056 private LdapProtocolUtils() 057 { 058 } 059 060 061 /** 062 * Extracts request controls from a request to populate into an 063 * OperationContext. 064 * 065 * @param opContext the context to populate with request controls 066 * @param request the request to extract controls from 067 */ 068 public static void setRequestControls( OperationContext opContext, Request request ) 069 { 070 if ( request.getControls() != null ) 071 { 072 opContext 073 .addRequestControls( request.getControls().values().toArray( LdapProtocolConstants.EMPTY_CONTROLS ) ); 074 } 075 } 076 077 078 /** 079 * Extracts response controls from a an OperationContext to populate into 080 * a Response object. 081 * 082 * @param opContext the context to extract controls from 083 * @param response the response to populate with response controls 084 */ 085 public static void setResponseControls( OperationContext opContext, Response response ) 086 { 087 response.addAllControls( opContext.getResponseControls() ); 088 } 089 090 091 public static byte[] createCookie( int replicaId, String csn ) 092 { 093 // the syncrepl cookie format (compatible with OpenLDAP) 094 // rid=nn,csn=xxxz 095 String replicaIdStr = StringUtils.leftPad( Integer.toString( replicaId ), 3, '0' ); 096 return Strings.getBytesUtf8( REPLICA_ID_PREFIX + replicaIdStr + COOKIE_DELIM + CSN_PREFIX + csn ); 097 } 098 099 100 /** 101 * Check the cookie syntax. A cookie must have the following syntax : 102 * { rid={replicaId},csn={CSN} } 103 * 104 * @param cookieString The cookie 105 * @return <tt>true</tt> if the cookie is valid 106 */ 107 public static boolean isValidCookie( String cookieString ) 108 { 109 if ( ( cookieString == null ) || ( cookieString.trim().length() == 0 ) ) 110 { 111 return false; 112 } 113 114 int pos = cookieString.indexOf( COOKIE_DELIM ); 115 116 // position should start from REPLICA_ID_PREFIX_LEN or higher cause a cookie can be 117 // like "rid=0,csn={csn}" or "rid=11,csn={csn}" 118 if ( pos <= REPLICA_ID_PREFIX_LEN ) 119 { 120 return false; 121 } 122 123 String replicaId = cookieString.substring( REPLICA_ID_PREFIX_LEN, pos ); 124 125 try 126 { 127 Integer.parseInt( replicaId ); 128 } 129 catch ( NumberFormatException e ) 130 { 131 LOG.debug( "Failed to parse the replica id {}", replicaId ); 132 return false; 133 } 134 135 if ( pos == cookieString.length() ) 136 { 137 return false; 138 } 139 140 String csnString = cookieString.substring( pos + 1 + CSN_PREFIX_LEN ); 141 142 return Csn.isValid( csnString ); 143 } 144 145 146 /** 147 * returns the CSN present in cookie 148 * 149 * @param cookieString the cookie 150 * @return The CSN 151 */ 152 public static String getCsn( String cookieString ) 153 { 154 int pos = cookieString.indexOf( COOKIE_DELIM ); 155 return cookieString.substring( pos + 1 + CSN_PREFIX_LEN ); 156 } 157 158 159 /** 160 * returns the replica id present in cookie 161 * 162 * @param cookieString the cookie 163 * @return The replica Id 164 */ 165 public static int getReplicaId( String cookieString ) 166 { 167 String replicaId = cookieString.substring( REPLICA_ID_PREFIX_LEN, cookieString.indexOf( COOKIE_DELIM ) ); 168 169 return Integer.parseInt( replicaId ); 170 } 171}