001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.http;
016    
017    import com.liferay.portal.kernel.servlet.HttpHeaders;
018    import com.liferay.portal.kernel.util.Base64;
019    import com.liferay.portal.kernel.util.ContentTypes;
020    import com.liferay.portal.kernel.util.GetterUtil;
021    import com.liferay.portal.kernel.util.MethodHandler;
022    import com.liferay.portal.kernel.util.ObjectValuePair;
023    import com.liferay.portal.kernel.util.PropsUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.Validator;
026    import com.liferay.portal.security.auth.HttpPrincipal;
027    import com.liferay.portal.security.auth.PrincipalException;
028    
029    import java.io.EOFException;
030    import java.io.IOException;
031    import java.io.ObjectInputStream;
032    import java.io.ObjectOutputStream;
033    
034    import java.net.HttpURLConnection;
035    import java.net.URL;
036    
037    import javax.net.ssl.HostnameVerifier;
038    import javax.net.ssl.HttpsURLConnection;
039    import javax.net.ssl.SSLSession;
040    
041    import javax.servlet.http.HttpServletRequest;
042    
043    /**
044     * @author Brian Wing Shun Chan
045     */
046    public class TunnelUtil {
047    
048            public static Object invoke(
049                            HttpPrincipal httpPrincipal, MethodHandler methodHandler)
050                    throws Exception {
051    
052                    HttpURLConnection urlc = _getConnection(httpPrincipal);
053    
054                    ObjectOutputStream oos = new ObjectOutputStream(urlc.getOutputStream());
055    
056                    oos.writeObject(
057                            new ObjectValuePair<HttpPrincipal, MethodHandler>(
058                                    httpPrincipal, methodHandler));
059    
060                    oos.flush();
061                    oos.close();
062    
063                    Object returnObj = null;
064    
065                    try {
066                            ObjectInputStream ois = new ObjectInputStream(
067                                    urlc.getInputStream());
068    
069                            returnObj = ois.readObject();
070    
071                            ois.close();
072                    }
073                    catch (EOFException eofe) {
074                    }
075                    catch (IOException ioe) {
076                            String ioeMessage = ioe.getMessage();
077    
078                            if ((ioeMessage != null) &&
079                                    ioeMessage.contains("HTTP response code: 401")) {
080    
081                                    throw new PrincipalException(ioeMessage);
082                            }
083                            else {
084                                    throw ioe;
085                            }
086                    }
087    
088                    if ((returnObj != null) && returnObj instanceof Exception) {
089                            throw (Exception)returnObj;
090                    }
091    
092                    return returnObj;
093            }
094    
095            private static HttpURLConnection _getConnection(HttpPrincipal httpPrincipal)
096                    throws IOException {
097    
098                    if ((httpPrincipal == null) || (httpPrincipal.getUrl() == null)) {
099                            return null;
100                    }
101    
102                    URL url = new URL(httpPrincipal.getUrl() + "/api/liferay/do");
103    
104                    HttpURLConnection httpURLConnection =
105                            (HttpURLConnection)url.openConnection();
106    
107                    httpURLConnection.setDoInput(true);
108                    httpURLConnection.setDoOutput(true);
109    
110                    if (!_VERIFY_SSL_HOSTNAME &&
111                            (httpURLConnection instanceof HttpsURLConnection)) {
112    
113                            HttpsURLConnection httpsURLConnection =
114                                    (HttpsURLConnection)httpURLConnection;
115    
116                            httpsURLConnection.setHostnameVerifier(
117                                    new HostnameVerifier() {
118    
119                                            public boolean verify(String hostname, SSLSession session) {
120                                                    return true;
121                                            }
122    
123                                    }
124                            );
125                    }
126    
127                    httpURLConnection.setRequestProperty(
128                            HttpHeaders.CONTENT_TYPE,
129                            ContentTypes.APPLICATION_X_JAVA_SERIALIZED_OBJECT);
130                    httpURLConnection.setUseCaches(false);
131    
132                    httpURLConnection.setRequestMethod("POST");
133    
134                    if (Validator.isNotNull(httpPrincipal.getLogin()) &&
135                            Validator.isNotNull(httpPrincipal.getPassword())) {
136    
137                            String userNameAndPassword =
138                                    httpPrincipal.getLogin() + StringPool.COLON +
139                                            httpPrincipal.getPassword();
140    
141                            httpURLConnection.setRequestProperty(
142                                    HttpHeaders.AUTHORIZATION,
143                                    HttpServletRequest.BASIC_AUTH + StringPool.SPACE +
144                                            Base64.encode(userNameAndPassword.getBytes()));
145                    }
146    
147                    return httpURLConnection;
148            }
149    
150            private static final boolean _VERIFY_SSL_HOSTNAME = GetterUtil.getBoolean(
151                    PropsUtil.get(TunnelUtil.class.getName() + ".verify.ssl.hostname"));
152    
153    }