Java tutorial
/** * Copyright 2006-2010 Soyatec * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * $Id$ */ package org.soyatec.windowsazure.authenticate; import java.net.URI; import java.net.URISyntaxException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.apache.http.HttpHost; import org.soyatec.windowsazure.constants.ConstChars; import org.soyatec.windowsazure.internal.ResourceUriComponents; import org.soyatec.windowsazure.internal.util.Logger; import org.soyatec.windowsazure.internal.util.NameValueCollection; import org.soyatec.windowsazure.internal.util.Utilities; /** * * Use this class to extract various header values from HTTP requests. * */ public class HttpRequestAccessor { /** * URI scheme delimiter */ private static final String SCHEME_DELIMITER = "://"; /** * A helper function for extracting HTTP header values from a * NameValueCollection object. * * @param header * A MultiValueMap object that should contain HTTP header * name-values pairs. * @param headerName * Name of the header that we want to get values of. * @return A array list of values for the header. The values are in the same * order as they are exist in the MultiValueMap object. */ public static List<String> getHeaderValues(NameValueCollection header, String headerName) { List<String> arrayOfValues = new ArrayList<String>(); Collection collection = header.getCollection(headerName); if (collection != null) { for (Iterator iterator = collection.iterator(); iterator.hasNext();) { String object = (String) iterator.next(); arrayOfValues.add(object); } } return arrayOfValues; } /** * Constructs an URI given all its constituents * * @param endPoint * This is the service endpoint in case of path-style URIs and a * host suffix in case of host-style URIs IMPORTANT: This does * NOT include the service name or account name * @param uriComponents * Uri constituents * @param pathStyleUri * Indicates whether to construct a path-style Uri (true) or * host-style URI (false) * @return Full URI */ public static URI constructResourceUri(URI endPoint, ResourceUriComponents uriComponents, boolean pathStyleUri) { return pathStyleUri ? constructPathStyleResourceUri(endPoint, uriComponents) : constructHostStyleResourceUri(endPoint, uriComponents); } /** * Constructs a host-style resource URI given all its constituents * * @param hostSuffix * @param uriComponents * @return Full URI */ private static URI constructHostStyleResourceUri(URI hostSuffix, ResourceUriComponents uriComponents) { if (uriComponents.getAccountName() == null) { // When there is no account name, full URI is same as hostSuffix return hostSuffix; } // accountUri will be something like "http://accountname.hostSuffix/" // and then we append // container name and remaining part if they are present. URI accountUri = constructHostStyleAccountUri(hostSuffix, uriComponents.getAccountName()); StringBuilder path = new StringBuilder(); if (uriComponents.getContainerName() != null) { // fix root container if (uriComponents.getContainerName().length() > 0) { path.append(uriComponents.getContainerName()); } if (uriComponents.getRemainingPart() != null) { if (!uriComponents.getRemainingPart().startsWith(ConstChars.Slash)) path.append(ConstChars.Slash); path.append(uriComponents.getRemainingPart()); } } String str = path.toString(); // str = Utilities.fixRootContainer(str); return constructUriFromUriAndString(accountUri, str); } /** * Constructs a path-style resource URI given all its constituents * * @param endPoint * This is the service endpoint in case of path-style URIs * @param uriComponents * Uri constituents * @return Full URI */ private static URI constructPathStyleResourceUri(URI endPoint, ResourceUriComponents uriComponents) { StringBuilder path = new StringBuilder(); if (uriComponents.getAccountName() != null) { path.append(uriComponents.getAccountName()); if (uriComponents.getContainerName() != null) { // fix root container if (uriComponents.getContainerName().length() > 0) { path.append(ConstChars.Slash); path.append(uriComponents.getContainerName()); } if (uriComponents.getRemainingPart() != null) { if (!uriComponents.getRemainingPart().startsWith(ConstChars.Slash)) path.append(ConstChars.Slash); path.append(uriComponents.getRemainingPart()); } } } String str = path.toString(); // str = Utilities.fixRootContainer(str); return constructUriFromUriAndString(endPoint, str); } /** * Given the host suffix part, service name and account name, this method * constructs the account Uri * * @param hostSuffix * @param accountName * @return URI */ private static URI constructHostStyleAccountUri(URI hostSuffix, String accountName) { URI serviceUri = hostSuffix; String hostString = hostSuffix.toString(); if (!hostString.startsWith(HttpHost.DEFAULT_SCHEME_NAME)) { hostString = HttpHost.DEFAULT_SCHEME_NAME + "://" + hostString; serviceUri = URI.create(hostString); } // Example: // Input: serviceEndpoint="http://blob.windows.net/", // accountName="youraccount" // Output: accountUri="http://youraccount.blob.windows.net/" // serviceUri in our example would be "http://blob.windows.net/" String accountUriString = null; if (serviceUri.getPort() == -1) { accountUriString = MessageFormat.format("{0}{1}{2}.{3}/", Utilities.isNullOrEmpty(serviceUri.getScheme()) ? HttpHost.DEFAULT_SCHEME_NAME : serviceUri.getScheme(), SCHEME_DELIMITER, accountName, serviceUri.getHost()); } else { accountUriString = MessageFormat.format("{0}{1}{2}.{3}:{4}/", Utilities.isNullOrEmpty(serviceUri.getScheme()) ? HttpHost.DEFAULT_SCHEME_NAME : serviceUri.getScheme(), SCHEME_DELIMITER, accountName, serviceUri.getHost(), serviceUri.getPort()); } return URI.create(accountUriString); } /** * Given the service endpoint in case of path-style URIs, path contains * container name and remaining part if they are present, this method * constructs the Full Uri. * * @param endPoint * @param path * @return Full URI */ private static URI constructUriFromUriAndString(URI endPoint, String path) { // This is where we encode the url path to be valid String encodedPath = Utilities.encode(path); if (!Utilities.isNullOrEmpty(encodedPath) && encodedPath.charAt(0) != ConstChars.Slash.charAt(0)) { encodedPath = ConstChars.Slash + encodedPath; } try { // @Note : rename blob with blank spaces in name return new URI(endPoint.getScheme(), null, endPoint.getHost(), endPoint.getPort(), encodedPath.replaceAll("%20", " "), endPoint.getQuery(), endPoint.getFragment()); // return new URI(endPoint.getScheme(), endPoint.getHost(), // encodedPath, endPoint.getFragment()); } catch (URISyntaxException e) { Logger.error("Can not new URI", e); return null; } } }