com.addc.commons.slp.ServiceURL Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of addc-slp Show documentation
Show all versions of addc-slp Show documentation
The addc-slp library supplies client classes for registering objects with a Service Location Protocol Daemon and
for looking theses objects up later.
package com.addc.commons.slp;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import com.addc.commons.ObjectEquals;
import com.addc.commons.slp.configuration.SLPConfig;
/**
* Implementation of the SLP ServiceURL class defined in RFC 2614.
*/
public class ServiceURL {
private final List authBlocks= new ArrayList<>();
private final SLPConfig config;
private String url;
private int lifetime;
private ServiceType type;
private String host;
private String transport;
private int port;
private String path;
/**
* Create a new ServiceURL
*
* @param config
* The configuration to use
* @param url
* The service URL
* @param lifetime
* The lifetime in seconds
* @throws ServiceLocationException
* If fails.
*/
public ServiceURL(SLPConfig config, String url, int lifetime) throws ServiceLocationException {
this.url= url;
this.lifetime= lifetime;
this.config= config;
try {
parse();
} catch (Exception ex) {
throw new ServiceLocationException("Malformed service url [" + url + "]. ", ex, SLPConstants.PARSE_ERROR);
}
}
/**
* Create a new ServiceURL for reading from data input stream
*
* @param config
* The configuration to use
*/
public ServiceURL(SLPConfig config) {
this.config= config;
}
/**
* Sign the URL
*
* @throws ServiceLocationException
* If signing fails.
*/
public void sign() throws ServiceLocationException {
if (config.isSecurityEnabled()) {
try {
String[] spis= StringUtils.split(config.getSPI(), ",");
authBlocks.clear();
for (String spIndex : spis) {
int timestamp= ServiceLocationManager.getTimestamp();
timestamp+= lifetime;
byte[] data= getAuthData(spIndex, timestamp);
authBlocks.add(new AuthenticationBlock(config, 2, spIndex, timestamp, data));
}
} catch (IOException e) {
throw new ServiceLocationException("Could not sign URL", e, SLPConstants.AUTHENTICATION_FAILED);
}
}
}
/**
* Verify the URL.
*
* @return true if valid
*/
public boolean verify() {
if (config.isSecurityEnabled()) {
for (AuthenticationBlock authBlock : authBlocks) {
try {
byte[] data= getAuthData(authBlock.getSPI(), authBlock.getTimestamp());
if (!authBlock.verify(data)) {
return false;
}
} catch (@SuppressWarnings("unused") IOException | ServiceLocationException e) {
return false;
}
}
}
return true;
}
/**
* Get the Service Type.
*
* @return the Service Type.
*/
public ServiceType getServiceType() {
return type;
}
/**
* Get the transport.
*
* @return the transport.
*/
public String getTransport() {
return transport;
}
/**
* Get the host.
*
* @return the host.
*/
public String getHost() {
return host;
}
/**
* Get the port.
*
* @return the port.
*/
public int getPort() {
return port;
}
/**
* Get the URL path.
*
* @return the URL path.
*/
public String getURLPath() {
return path;
}
/**
* Get the lifetime.
*
* @return the lifetime.
*/
public int getLifetime() {
return lifetime;
}
/**
* Get the URL.
*
* @return the URL.
*/
public String getURL() {
return url;
}
/**
* Read the Service URL from a Data input stream
*
* @param dataIn
* The DataInputStream to read from
* @throws IOException
* If there is an IO error
*/
public void readExternal(DataInputStream dataIn) throws IOException {
dataIn.readByte();
lifetime= dataIn.readShort();
url= dataIn.readUTF();
int numBlks= dataIn.readByte();
for (int i= 0; i < numBlks; i++) {
authBlocks.add(AuthenticationBlock.readBlock(config, dataIn));
}
parse();
}
/**
* Write the Service URL to a data output stream
*
* @param out
* The DataOutStream to write to
* @throws IOException
* If there is an IO error
*/
public void writeExternal(DataOutputStream out) throws IOException {
out.writeByte(0);
out.writeShort(lifetime);
out.writeUTF(this.toString());
out.writeByte(authBlocks.size());
for (AuthenticationBlock authBlock : authBlocks) {
authBlock.writeBlock(out);
}
}
/**
* calculate the size
*
* @return the size
*/
public int calcSize() {
int size= 6 + this.toString().length();
for (AuthenticationBlock authBlock : authBlocks) {
size+= authBlock.calcSize();
}
return size;
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime= 31;
int result= 1;
result= prime * result + ((host == null) ? 0 : host.hashCode());
result= prime * result + ((path == null) ? 0 : path.hashCode());
result= prime * result + port;
result= prime * result + ((transport == null) ? 0 : transport.hashCode());
result= prime * result + ((type == null) ? 0 : type.hashCode());
return result;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof ServiceURL)) {
return false;
}
ServiceURL other= (ServiceURL) obj;
return (ObjectEquals.areFieldsEqual(host, other.host) && ObjectEquals.areFieldsEqual(path, other.path)
&& (port == other.port) && ObjectEquals.areFieldsEqual(transport, other.transport)
&& ObjectEquals.areFieldsEqual(type, other.type));
}
@Override
public String toString() {
StringBuilder sb= new StringBuilder();
sb.append(type).append(":/").append(transport).append('/').append(host);
if (port != SLPConstants.NO_PORT) {
sb.append(':').append(port);
}
sb.append(path);
return sb.toString();
}
private void parse() {
int transportSlash1= url.indexOf(":/");
type= new ServiceType(url.substring(0, transportSlash1++));
int transportSlash2= url.indexOf("/", transportSlash1 + 1);
transport= url.substring(transportSlash1, transportSlash2 - 1);
int hostEnd= -1;
if ("".equals(transport)) {
hostEnd= url.indexOf(':', transportSlash2 + 1);
}
int pathStart;
if (hostEnd == -1) {
port= SLPConstants.NO_PORT;
pathStart= url.indexOf('/', transportSlash2 + 1);
hostEnd= pathStart;
} else {
pathStart= url.indexOf('/', hostEnd + 1);
if (pathStart == -1) {
port= Integer.parseInt(url.substring(hostEnd + 1));
} else {
port= Integer.parseInt(url.substring(hostEnd + 1, pathStart));
}
}
if (hostEnd == -1) {
host= url.substring(transportSlash2 + 1);
} else {
host= url.substring(transportSlash2 + 1, hostEnd);
}
if (pathStart == -1) {
path= "";
} else {
path= url.substring(pathStart);
}
}
private byte[] getAuthData(String spi, int timestamp) throws IOException {
ByteArrayOutputStream bos= new ByteArrayOutputStream();
DataOutputStream dos= new DataOutputStream(bos);
dos.writeUTF(spi);
dos.writeUTF(this.toString());
dos.writeInt(timestamp);
return bos.toByteArray();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy