Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.jclouds.http.apachehc; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.util.Map; import java.util.Set; import javax.inject.Singleton; import javax.ws.rs.HttpMethod; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.client.methods.HttpDelete; import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpHead; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.methods.HttpPut; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.FileEntity; import org.apache.http.entity.InputStreamEntity; import org.apache.http.entity.StringEntity; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; import org.jclouds.JcloudsVersion; import org.jclouds.http.HttpRequest; import org.jclouds.io.ContentMetadataCodec; import org.jclouds.io.MutableContentMetadata; import org.jclouds.io.Payload; import org.jclouds.io.payloads.BasePayload; import org.jclouds.io.payloads.ByteArrayPayload; import org.jclouds.io.payloads.DelegatingPayload; import org.jclouds.io.payloads.FilePayload; import org.jclouds.io.payloads.StringPayload; import com.google.common.base.Throwables; import com.google.common.collect.ImmutableSet; import com.google.common.net.HttpHeaders; @Singleton public class ApacheHCUtils { //TODO: look up httpclient version public static final String USER_AGENT = String.format("jclouds/%s httpclient/%s", JcloudsVersion.get(), "4.1.1"); private final ContentMetadataCodec contentMetadataCodec; public ApacheHCUtils(ContentMetadataCodec contentMetadataCodec) { this.contentMetadataCodec = contentMetadataCodec; } public HttpUriRequest convertToApacheRequest(HttpRequest request) { HttpUriRequest apacheRequest; if (request.getMethod().equals(HttpMethod.HEAD)) { apacheRequest = new HttpHead(request.getEndpoint()); } else if (request.getMethod().equals(HttpMethod.GET)) { apacheRequest = new HttpGet(request.getEndpoint()); } else if (request.getMethod().equals(HttpMethod.DELETE)) { apacheRequest = new HttpDelete(request.getEndpoint()); } else if (request.getMethod().equals(HttpMethod.PUT)) { apacheRequest = new HttpPut(request.getEndpoint()); apacheRequest.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, true); } else if (request.getMethod().equals(HttpMethod.POST)) { apacheRequest = new HttpPost(request.getEndpoint()); } else { final String method = request.getMethod(); if (request.getPayload() != null) apacheRequest = new HttpEntityEnclosingRequestBase() { @Override public String getMethod() { return method; } }; else apacheRequest = new HttpRequestBase() { @Override public String getMethod() { return method; } }; HttpRequestBase.class.cast(apacheRequest).setURI(request.getEndpoint()); } Payload payload = request.getPayload(); // Since we may remove headers, ensure they are added to the apache // request after this block if (apacheRequest instanceof HttpEntityEnclosingRequest) { if (payload != null) { addEntityForContent(HttpEntityEnclosingRequest.class.cast(apacheRequest), payload); } } else { apacheRequest.addHeader(HttpHeaders.CONTENT_LENGTH, "0"); } for (Map.Entry<String, String> entry : request.getHeaders().entries()) { String header = entry.getKey(); // apache automatically tries to add content length header if (!header.equals(HttpHeaders.CONTENT_LENGTH)) apacheRequest.addHeader(header, entry.getValue()); } apacheRequest.addHeader(HttpHeaders.USER_AGENT, USER_AGENT); return apacheRequest; } public void addEntityForContent(HttpEntityEnclosingRequest apacheRequest, Payload payload) { payload = payload instanceof DelegatingPayload ? DelegatingPayload.class.cast(payload).getDelegate() : payload; if (payload instanceof StringPayload) { StringEntity nStringEntity = null; try { nStringEntity = new StringEntity((String) payload.getRawContent()); } catch (UnsupportedEncodingException e) { throw new UnsupportedOperationException("Encoding not supported", e); } nStringEntity.setContentType(payload.getContentMetadata().getContentType()); apacheRequest.setEntity(nStringEntity); } else if (payload instanceof FilePayload) { apacheRequest.setEntity( new FileEntity((File) payload.getRawContent(), payload.getContentMetadata().getContentType())); } else if (payload instanceof ByteArrayPayload) { ByteArrayEntity Entity = new ByteArrayEntity((byte[]) payload.getRawContent()); Entity.setContentType(payload.getContentMetadata().getContentType()); apacheRequest.setEntity(Entity); } else { InputStream inputStream = payload.getInput(); if (payload.getContentMetadata().getContentLength() == null) throw new IllegalArgumentException("you must specify size when content is an InputStream"); InputStreamEntity entity = new InputStreamEntity(inputStream, payload.getContentMetadata().getContentLength()); entity.setContentType(payload.getContentMetadata().getContentType()); apacheRequest.setEntity(entity); } // TODO Reproducing old behaviour exactly; ignoring Content-Type, Content-Length and Content-MD5 Set<String> desiredHeaders = ImmutableSet.of("Content-Disposition", "Content-Encoding", "Content-Language", "Expires"); MutableContentMetadata md = payload.getContentMetadata(); for (Map.Entry<String, String> entry : contentMetadataCodec.toHeaders(md).entries()) { if (desiredHeaders.contains(entry.getKey())) { apacheRequest.addHeader(entry.getKey(), entry.getValue()); } } assert apacheRequest.getEntity() != null; } public static class HttpEntityPayload extends BasePayload<HttpEntity> { HttpEntityPayload(HttpEntity content) { super(content); getContentMetadata().setContentType(content.getContentType().getValue()); getContentMetadata().setContentLength(content.getContentLength()); } @Override public InputStream openStream() throws IOException { try { return content.getContent(); } catch (IllegalStateException e) { throw Throwables.propagate(e); } } @Override public boolean isRepeatable() { return content.isRepeatable(); } @Override public void release() { try { EntityUtils.consume(content); } catch (IOException e) { } } } }