use of com.zimbra.common.httpclient.InputStreamRequestHttpRetryHandler in project zm-mailbox by Zimbra.
the class UserServlet method doHttpOp.
private static Pair<Header[], HttpResponse> doHttpOp(ZAuthToken authToken, HttpRequestBase method) throws ServiceException {
// create an HTTP client with the same cookies
String url = "";
String hostname = "";
url = method.getURI().toString();
hostname = method.getURI().getHost();
HttpClientBuilder clientBuilder = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
Map<String, String> cookieMap = authToken.cookieMap(false);
if (cookieMap != null) {
BasicCookieStore cookieStore = new BasicCookieStore();
for (Map.Entry<String, String> ck : cookieMap.entrySet()) {
BasicClientCookie cookie = new BasicClientCookie(ck.getKey(), ck.getValue());
cookie.setDomain(hostname);
cookie.setPath("/");
cookie.setSecure(false);
cookieStore.addCookie(cookie);
}
clientBuilder.setDefaultCookieStore(cookieStore);
RequestConfig reqConfig = RequestConfig.copy(ZimbraHttpConnectionManager.getInternalHttpConnMgr().getZimbraConnMgrParams().getReqConfig()).setCookieSpec(CookieSpecs.BROWSER_COMPATIBILITY).build();
clientBuilder.setDefaultRequestConfig(reqConfig);
if (method.getMethod().equalsIgnoreCase("PUT")) {
clientBuilder.setRetryHandler(new InputStreamRequestHttpRetryHandler());
}
}
if (method instanceof HttpPut) {
long contentLength = ((HttpPut) method).getEntity().getContentLength();
if (contentLength > 0) {
// 100kbps in millis
int timeEstimate = Math.max(10000, (int) (contentLength / 100));
// cannot set connection time using our ZimbrahttpConnectionManager,
// see comments in ZimbrahttpConnectionManager.
// actually, length of the content to Put should not be a factor for
// establishing a connection, only read time out matter, which we set
// client.getHttpConnectionManager().getParams().setConnectionTimeout(timeEstimate);
SocketConfig config = SocketConfig.custom().setSoTimeout(timeEstimate).build();
clientBuilder.setDefaultSocketConfig(config);
}
}
HttpClient client = clientBuilder.build();
try {
HttpResponse response = HttpClientUtil.executeMethod(client, method);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_NOT_FOUND || statusCode == HttpStatus.SC_FORBIDDEN)
throw MailServiceException.NO_SUCH_ITEM(-1);
else if (statusCode != HttpStatus.SC_OK && statusCode != HttpStatus.SC_CREATED && statusCode != HttpStatus.SC_NO_CONTENT)
throw ServiceException.RESOURCE_UNREACHABLE(response.getStatusLine().getReasonPhrase(), null, new ServiceException.InternalArgument(HTTP_URL, url, ServiceException.Argument.Type.STR), new ServiceException.InternalArgument(HTTP_STATUS_CODE, statusCode, ServiceException.Argument.Type.NUM));
List<Header> headers = new ArrayList<Header>(Arrays.asList(response.getAllHeaders()));
headers.add(new BasicHeader("X-Zimbra-Http-Status", "" + statusCode));
return new Pair<Header[], HttpResponse>(headers.toArray(new Header[0]), response);
} catch (HttpException e) {
throw ServiceException.RESOURCE_UNREACHABLE("HttpException while fetching " + url, e);
} catch (IOException e) {
throw ServiceException.RESOURCE_UNREACHABLE("IOException while fetching " + url, e);
}
}
use of com.zimbra.common.httpclient.InputStreamRequestHttpRetryHandler in project zm-mailbox by Zimbra.
the class TritonIncomingOutputStream method sendHttpData.
private void sendHttpData() throws IOException {
HttpClientBuilder clientBuilder = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
clientBuilder.setRetryHandler(new InputStreamRequestHttpRetryHandler());
HttpClient client = clientBuilder.build();
HttpPost post;
boolean started = false;
if (uploadUrl.isInitialized()) {
started = true;
post = new HttpPost(baseUrl + uploadUrl);
} else {
post = new HttpPost(baseUrl + "/blob");
}
try {
ZimbraLog.store.info("posting to %s", post.getURI());
InputStreamEntity entity = new InputStreamEntity(new ByteArrayInputStream(baos.toByteArray()), baos.size(), ContentType.APPLICATION_OCTET_STREAM);
post.setEntity(entity);
post.addHeader(TritonHeaders.CONTENT_LENGTH, baos.size() + "");
post.addHeader(TritonHeaders.HASH_TYPE, hashType.toString());
post.addHeader("Content-Range", "bytes " + written.longValue() + "-" + (written.longValue() + baos.size() - 1) + "/*");
if (serverToken.getToken() != null) {
post.addHeader(TritonHeaders.SERVER_TOKEN, serverToken.getToken());
}
HttpResponse httpResp = HttpClientUtil.executeMethod(client, post);
int statusCode = httpResp.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
handleResponse(httpResp);
} else if (!started && statusCode == HttpStatus.SC_SEE_OTHER) {
started = true;
uploadUrl.setUploadUrl(httpResp.getFirstHeader(TritonHeaders.LOCATION).getValue());
handleResponse(httpResp);
} else {
throw new IOException("Unable to append, bad response code " + statusCode);
}
} catch (HttpException e) {
throw new IOException("unexpected error during sendHttpData() operation: " + e.getMessage());
} finally {
post.releaseConnection();
}
baos = new ByteArrayOutputStream(LC.triton_upload_buffer_size.intValue());
}
use of com.zimbra.common.httpclient.InputStreamRequestHttpRetryHandler in project zm-mailbox by Zimbra.
the class ZMailbox method uploadContentAsStream.
public String uploadContentAsStream(String name, InputStream in, String contentType, long contentLength, int msTimeout, boolean limitByFileUploadMaxSize) throws ServiceException {
String aid = null;
if (name != null) {
contentType += "; name=" + name;
}
URI uri = getUploadURI(limitByFileUploadMaxSize);
// make the post
HttpPost post = new HttpPost(uri.toString());
HttpClientBuilder clientBuilder = getHttpClientBuilder(uri);
SocketConfig config = SocketConfig.custom().setSoTimeout(msTimeout).build();
clientBuilder.setDefaultSocketConfig(config);
clientBuilder.setRetryHandler(new InputStreamRequestHttpRetryHandler());
HttpClient client = clientBuilder.build();
int statusCode;
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("upfile", in, ContentType.DEFAULT_BINARY, name);
HttpEntity httpEntity = builder.build();
post.setEntity(httpEntity);
if (mCsrfToken != null) {
post.addHeader(Constants.CSRF_TOKEN, mCsrfToken);
}
HttpResponse response = HttpClientUtil.executeMethod(client, post);
statusCode = response.getStatusLine().getStatusCode();
// parse the response
if (statusCode == HttpServletResponse.SC_OK) {
String content = EntityUtils.toString(response.getEntity());
aid = getAttachmentId(content);
} else if (statusCode == HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE) {
throw ZClientException.UPLOAD_SIZE_LIMIT_EXCEEDED("upload size limit exceeded", null);
} else {
throw ZClientException.UPLOAD_FAILED("Attachment post failed, status=" + statusCode, null);
}
} catch (IOException | HttpException e) {
throw ZClientException.IO_ERROR(e.getMessage(), e);
} finally {
post.releaseConnection();
}
return aid;
}
use of com.zimbra.common.httpclient.InputStreamRequestHttpRetryHandler in project zm-mailbox by Zimbra.
the class ZMailbox method postRESTResource.
/**
* @param relativePath a relative path (i.e., "/Calendar", "Inbox?fmt=rss", etc).
* @param is the input stream to post
* @param closeIs whether to close the input stream when done
* @param length length of inputstream, or 0/-1 if length is unknown.
* @param contentType optional content-type header value (defaults to "binary")
* @param ignoreAndContinueOnError if true, set optional ignore=1 query string parameter
* @param preserveAlarms if true, set optional preserveAlarms=1 query string parameter
* @param msecTimeout connection timeout in milliseconds, or <tt>-1</tt> for no timeout
* @param url alternate url to connect to
* @throws ServiceException on error
*/
public void postRESTResource(String relativePath, InputStream is, boolean closeIs, long length, String contentType, boolean ignoreAndContinueOnError, boolean preserveAlarms, int msecTimeout, String alternateUrl) throws ServiceException {
HttpPost post = null;
try {
if (ignoreAndContinueOnError) {
if (!relativePath.contains("?")) {
relativePath = relativePath + "?ignore=1";
} else {
relativePath = relativePath + "&ignore=1";
}
}
if (preserveAlarms) {
if (!relativePath.contains("?")) {
relativePath = relativePath + "?preserveAlarms=1";
} else {
relativePath = relativePath + "&preserveAlarms=1";
}
}
URI uri = getRestURI(relativePath, alternateUrl);
post = new HttpPost(uri.toString());
HttpClientBuilder clientBuilder = getHttpClientBuilder(uri);
if (msecTimeout > -1) {
SocketConfig config = SocketConfig.custom().setSoTimeout(msecTimeout).build();
clientBuilder.setDefaultSocketConfig(config);
}
clientBuilder.setRetryHandler(new InputStreamRequestHttpRetryHandler());
HttpClient client = clientBuilder.build();
int statusCode;
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addBinaryBody("upfile", is, ContentType.DEFAULT_BINARY, "file");
HttpEntity httpEntity = builder.build();
post.setEntity(httpEntity);
HttpResponse response = HttpClientUtil.executeMethod(client, post);
statusCode = response.getStatusLine().getStatusCode();
// parse the response
if (statusCode != HttpServletResponse.SC_OK) {
throw ServiceException.FAILURE("POST failed, status=" + statusCode + " " + response.getStatusLine().getStatusCode(), null);
}
} catch (IOException | HttpException e) {
throw ZClientException.IO_ERROR(e.getMessage(), e);
} finally {
if (closeIs) {
ByteUtil.closeStream(is);
}
if (post != null) {
post.releaseConnection();
}
}
}
use of com.zimbra.common.httpclient.InputStreamRequestHttpRetryHandler in project zm-mailbox by Zimbra.
the class TritonBlobStoreManager method writeStreamToStore.
@Override
protected void writeStreamToStore(InputStream in, long actualSize, Mailbox mbox, String locator) throws IOException, ServiceException {
HttpClientBuilder clientBuilder = ZimbraHttpConnectionManager.getInternalHttpConnMgr().newHttpClient();
clientBuilder.setRetryHandler(new InputStreamRequestHttpRetryHandler());
HttpClient client = clientBuilder.build();
if (actualSize < 0) {
throw ServiceException.FAILURE("Must use resumable upload (i.e. StoreManager.newIncomingBlob()) if size is unknown", null);
} else if (actualSize == 0) {
ZimbraLog.store.info("storing empty blob");
// don't bother writing empty file to remote
return;
}
HttpPost post = new HttpPost(blobApiUrl);
ZimbraLog.store.info("posting to %s with locator %s", post.getURI(), locator);
try {
InputStreamEntity entity = new InputStreamEntity(in, actualSize, ContentType.APPLICATION_OCTET_STREAM);
post.setEntity(entity);
post.addHeader(TritonHeaders.CONTENT_LENGTH, actualSize + "");
post.addHeader(TritonHeaders.OBJECTID, locator);
post.addHeader(TritonHeaders.HASH_TYPE, hashType.toString());
HttpResponse httpResp = HttpClientUtil.executeMethod(client, post);
int statusCode = httpResp.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_CREATED) {
return;
} else {
ZimbraLog.store.error("failed with code %d response: %s", statusCode, EntityUtils.toString(httpResp.getEntity()));
throw ServiceException.FAILURE("unable to store blob " + statusCode + ":" + httpResp.getStatusLine().getReasonPhrase(), null);
}
} catch (HttpException e) {
throw new IOException("unexpected error during write stream to store operation: " + e.getMessage());
} finally {
post.releaseConnection();
}
}
Aggregations