001    /*
002     * SonarQube, open source software quality management tool.
003     * Copyright (C) 2008-2014 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * SonarQube is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * SonarQube is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public License
017     * along with this program; if not, write to the Free Software Foundation,
018     * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
019     */
020    package org.sonar.wsclient.internal;
021    
022    import com.github.kevinsawicki.http.HttpRequest;
023    import org.sonar.wsclient.base.HttpException;
024    
025    import javax.annotation.Nullable;
026    import java.util.Arrays;
027    import java.util.Map;
028    
029    import static java.net.HttpURLConnection.*;
030    
031    /**
032     * Not an API. Please do not use this class, except maybe for unit tests.
033     */
034    public class HttpRequestFactory {
035    
036      private static final int[] RESPONSE_SUCCESS = {HTTP_OK, HTTP_CREATED, HTTP_NO_CONTENT};
037    
038      private final String baseUrl;
039      private String login, password, proxyHost, proxyLogin, proxyPassword;
040      private int proxyPort;
041      private int connectTimeoutInMilliseconds;
042      private int readTimeoutInMilliseconds;
043    
044      public HttpRequestFactory(String baseUrl) {
045        this.baseUrl = baseUrl;
046      }
047    
048      public HttpRequestFactory setLogin(@Nullable String login) {
049        this.login = login;
050        return this;
051      }
052    
053      public HttpRequestFactory setPassword(@Nullable String password) {
054        this.password = password;
055        return this;
056      }
057    
058      public HttpRequestFactory setProxyHost(@Nullable String proxyHost) {
059        this.proxyHost = proxyHost;
060        return this;
061      }
062    
063      public HttpRequestFactory setProxyLogin(@Nullable String proxyLogin) {
064        this.proxyLogin = proxyLogin;
065        return this;
066      }
067    
068      public HttpRequestFactory setProxyPassword(@Nullable String proxyPassword) {
069        this.proxyPassword = proxyPassword;
070        return this;
071      }
072    
073      public HttpRequestFactory setProxyPort(int proxyPort) {
074        this.proxyPort = proxyPort;
075        return this;
076      }
077    
078      public HttpRequestFactory setConnectTimeoutInMilliseconds(int connectTimeoutInMilliseconds) {
079        this.connectTimeoutInMilliseconds = connectTimeoutInMilliseconds;
080        return this;
081      }
082    
083      public HttpRequestFactory setReadTimeoutInMilliseconds(int readTimeoutInMilliseconds) {
084        this.readTimeoutInMilliseconds = readTimeoutInMilliseconds;
085        return this;
086      }
087    
088      public String getBaseUrl() {
089        return baseUrl;
090      }
091    
092      public String getLogin() {
093        return login;
094      }
095    
096      public String getPassword() {
097        return password;
098      }
099    
100      public String getProxyHost() {
101        return proxyHost;
102      }
103    
104      public String getProxyLogin() {
105        return proxyLogin;
106      }
107    
108      public String getProxyPassword() {
109        return proxyPassword;
110      }
111    
112      public int getProxyPort() {
113        return proxyPort;
114      }
115    
116      public int getConnectTimeoutInMilliseconds() {
117        return connectTimeoutInMilliseconds;
118      }
119    
120      public int getReadTimeoutInMilliseconds() {
121        return readTimeoutInMilliseconds;
122      }
123    
124      public String get(String wsUrl, Map<String, Object> queryParams) {
125        HttpRequest request = prepare(HttpRequest.get(baseUrl + wsUrl, queryParams, true));
126        return execute(request);
127      }
128    
129      public String post(String wsUrl, Map<String, Object> queryParams) {
130        HttpRequest request = prepare(HttpRequest.post(baseUrl + wsUrl, true)).form(queryParams, HttpRequest.CHARSET_UTF8);
131        return execute(request);
132      }
133    
134      private String execute(HttpRequest request) {
135        try {
136          if (isSuccess(request)) {
137            return request.body(HttpRequest.CHARSET_UTF8);
138          }
139          // TODO handle error messages
140          throw new HttpException(request.url().toString(), request.code());
141    
142        } catch (HttpRequest.HttpRequestException e) {
143          throw new IllegalStateException("Fail to request " + request.url(), e.getCause());
144        }
145      }
146    
147      private boolean isSuccess(HttpRequest request) {
148        return Arrays.binarySearch(RESPONSE_SUCCESS, request.code()) >= 0;
149      }
150    
151      private HttpRequest prepare(HttpRequest request) {
152        if (proxyHost != null) {
153          request.useProxy(proxyHost, proxyPort);
154          if (proxyLogin != null) {
155            request.proxyBasic(proxyLogin, proxyPassword);
156          }
157        }
158        request
159          .acceptGzipEncoding()
160          .uncompress(true)
161          .acceptJson()
162          .acceptCharset(HttpRequest.CHARSET_UTF8)
163          .connectTimeout(connectTimeoutInMilliseconds)
164          .readTimeout(readTimeoutInMilliseconds)
165          .trustAllCerts()
166          .trustAllHosts();
167        if (login != null) {
168          request.basic(login, password);
169        }
170        return request;
171      }
172    }