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 */ 020package org.sonar.wsclient.internal; 021 022import com.github.kevinsawicki.http.HttpRequest; 023import org.sonar.wsclient.base.HttpException; 024 025import javax.annotation.Nullable; 026 027import java.util.Arrays; 028import java.util.Map; 029 030import static java.net.HttpURLConnection.*; 031 032/** 033 * Not an API. Please do not use this class, except maybe for unit tests. 034 */ 035public class HttpRequestFactory { 036 037 private static final int[] RESPONSE_SUCCESS = {HTTP_OK, HTTP_CREATED, HTTP_NO_CONTENT}; 038 039 private final String baseUrl; 040 private String login, password, proxyHost, proxyLogin, proxyPassword; 041 private int proxyPort; 042 private int connectTimeoutInMilliseconds; 043 private int readTimeoutInMilliseconds; 044 045 public HttpRequestFactory(String baseUrl) { 046 this.baseUrl = baseUrl; 047 } 048 049 public HttpRequestFactory setLogin(@Nullable String login) { 050 this.login = login; 051 return this; 052 } 053 054 public HttpRequestFactory setPassword(@Nullable String password) { 055 this.password = password; 056 return this; 057 } 058 059 public HttpRequestFactory setProxyHost(@Nullable String proxyHost) { 060 this.proxyHost = proxyHost; 061 return this; 062 } 063 064 public HttpRequestFactory setProxyLogin(@Nullable String proxyLogin) { 065 this.proxyLogin = proxyLogin; 066 return this; 067 } 068 069 public HttpRequestFactory setProxyPassword(@Nullable String proxyPassword) { 070 this.proxyPassword = proxyPassword; 071 return this; 072 } 073 074 public HttpRequestFactory setProxyPort(int proxyPort) { 075 this.proxyPort = proxyPort; 076 return this; 077 } 078 079 public HttpRequestFactory setConnectTimeoutInMilliseconds(int connectTimeoutInMilliseconds) { 080 this.connectTimeoutInMilliseconds = connectTimeoutInMilliseconds; 081 return this; 082 } 083 084 public HttpRequestFactory setReadTimeoutInMilliseconds(int readTimeoutInMilliseconds) { 085 this.readTimeoutInMilliseconds = readTimeoutInMilliseconds; 086 return this; 087 } 088 089 public String getBaseUrl() { 090 return baseUrl; 091 } 092 093 public String getLogin() { 094 return login; 095 } 096 097 public String getPassword() { 098 return password; 099 } 100 101 public String getProxyHost() { 102 return proxyHost; 103 } 104 105 public String getProxyLogin() { 106 return proxyLogin; 107 } 108 109 public String getProxyPassword() { 110 return proxyPassword; 111 } 112 113 public int getProxyPort() { 114 return proxyPort; 115 } 116 117 public int getConnectTimeoutInMilliseconds() { 118 return connectTimeoutInMilliseconds; 119 } 120 121 public int getReadTimeoutInMilliseconds() { 122 return readTimeoutInMilliseconds; 123 } 124 125 public String get(String wsUrl, Map<String, Object> queryParams) { 126 HttpRequest request = prepare(HttpRequest.get(buildUrl(wsUrl), queryParams, true)); 127 return execute(request); 128 } 129 130 public String post(String wsUrl, Map<String, Object> queryParams) { 131 HttpRequest request = prepare(HttpRequest.post(buildUrl(wsUrl), true)).form(queryParams, HttpRequest.CHARSET_UTF8); 132 return execute(request); 133 } 134 135 private String buildUrl(String part) { 136 StringBuilder url = new StringBuilder(); 137 url.append(baseUrl); 138 if (!part.startsWith("/")) { 139 url.append('/'); 140 } 141 url.append(part); 142 return url.toString(); 143 } 144 145 private String execute(HttpRequest request) { 146 try { 147 if (isSuccess(request)) { 148 return request.body(HttpRequest.CHARSET_UTF8); 149 } 150 // TODO better handle error messages 151 throw new HttpException(request.url().toString(), request.code(), request.body()); 152 153 } catch (HttpRequest.HttpRequestException e) { 154 throw new IllegalStateException("Fail to request " + request.url(), e.getCause()); 155 } 156 } 157 158 private boolean isSuccess(HttpRequest request) { 159 return Arrays.binarySearch(RESPONSE_SUCCESS, request.code()) >= 0; 160 } 161 162 private HttpRequest prepare(HttpRequest request) { 163 if (proxyHost != null) { 164 request.useProxy(proxyHost, proxyPort); 165 if (proxyLogin != null) { 166 request.proxyBasic(proxyLogin, proxyPassword); 167 } 168 } 169 request 170 .acceptGzipEncoding() 171 .uncompress(true) 172 .acceptJson() 173 .acceptCharset(HttpRequest.CHARSET_UTF8) 174 .connectTimeout(connectTimeoutInMilliseconds) 175 .readTimeout(readTimeoutInMilliseconds) 176 .trustAllCerts() 177 .trustAllHosts(); 178 if (login != null) { 179 request.basic(login, password); 180 } 181 return request; 182 } 183}