001/*
002 * SonarQube, open source software quality management tool.
003 * Copyright (C) 2008-2013 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 */
020package org.sonar.wsclient.internal;
021
022import com.github.kevinsawicki.http.HttpRequest;
023import org.sonar.wsclient.base.HttpException;
024
025import javax.annotation.Nullable;
026import java.util.Arrays;
027import java.util.Map;
028
029import static java.net.HttpURLConnection.*;
030
031/**
032 * Not an API. Please do not use this class, except maybe for unit tests.
033 */
034public 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}