/** * Extracts the response from the method as a InputStream. * * @param method the method that was executed * @return the response either as a stream, or as a deserialized java object * @throws IOException can be thrown */ protected static Object extractResponseBody(HttpMethod method, Exchange exchange) throws IOException, ClassNotFoundException { InputStream is = method.getResponseBodyAsStream(); if (is == null) { return null; } Header header = method.getResponseHeader(Exchange.CONTENT_ENCODING); String contentEncoding = header != null ? header.getValue() : null; if (!exchange.getProperty(Exchange.SKIP_GZIP_ENCODING, Boolean.FALSE, Boolean.class)) { is = GZIPHelper.uncompressGzip(contentEncoding, is); } // Honor the character encoding String contentType = null; header = method.getResponseHeader("content-type"); if (header != null) { contentType = header.getValue(); // find the charset and set it to the Exchange HttpHelper.setCharsetFromContentType(contentType, exchange); } InputStream response = doExtractResponseBodyAsStream(is, exchange); // if content type is a serialized java object then de-serialize it back to a Java object if (contentType != null && contentType.equals(HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT)) { return HttpHelper.deserializeJavaObjectFromStream(response); } else { return response; } }
protected void populateResponse( Exchange exchange, HttpMethod method, Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException, ClassNotFoundException { // We just make the out message is not create when extractResponseBody throws exception, Object response = extractResponseBody(method, exchange); Message answer = exchange.getOut(); answer.setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode); answer.setBody(response); // propagate HTTP response headers Header[] headers = method.getResponseHeaders(); for (Header header : headers) { String name = header.getName(); String value = header.getValue(); if (name.toLowerCase().equals("content-type")) { name = Exchange.CONTENT_TYPE; exchange.setProperty(Exchange.CHARSET_NAME, IOHelper.getCharsetNameFromContentType(value)); } // use http helper to extract parameter value as it may contain multiple values Object extracted = HttpHelper.extractHttpParameterValue(value); if (strategy != null && !strategy.applyFilterToExternalHeaders(name, extracted, exchange)) { HttpHelper.appendHeader(answer.getHeaders(), name, extracted); } } // preserve headers from in by copying any non existing headers // to avoid overriding existing headers with old values MessageHelper.copyHeaders(exchange.getIn(), answer, false); }
/** * Creates the HttpMethod to use to call the remote server, either its GET or POST. * * @param exchange the exchange * @return the created method as either GET or POST * @throws CamelExchangeException is thrown if error creating RequestEntity */ @SuppressWarnings("deprecation") protected HttpMethod createMethod(Exchange exchange) throws Exception { // creating the url to use takes 2-steps String url = HttpHelper.createURL(exchange, getEndpoint()); URI uri = HttpHelper.createURI(exchange, url, getEndpoint()); // get the url and query string from the uri url = uri.toASCIIString(); String queryString = uri.getRawQuery(); // execute any custom url rewrite String rewriteUrl = HttpHelper.urlRewrite(exchange, url, getEndpoint(), this); if (rewriteUrl != null) { // update url and query string from the rewritten url url = rewriteUrl; uri = new URI(url); // use raw query to have uri decimal encoded which http client requires queryString = uri.getRawQuery(); } // remove query string as http client does not accept that if (url.indexOf('?') != -1) { url = url.substring(0, url.indexOf('?')); } // create http holder objects for the request RequestEntity requestEntity = createRequestEntity(exchange); HttpMethods methodToUse = HttpHelper.createMethod(exchange, getEndpoint(), requestEntity != null); HttpMethod method = methodToUse.createMethod(url); if (queryString != null) { // need to encode query string queryString = UnsafeUriCharactersEncoder.encode(queryString); method.setQueryString(queryString); } LOG.trace("Using URL: {} with method: {}", url, method); if (methodToUse.isEntityEnclosing()) { ((EntityEnclosingMethod) method).setRequestEntity(requestEntity); if (requestEntity != null && requestEntity.getContentType() == null) { LOG.debug("No Content-Type provided for URL: {} with exchange: {}", url, exchange); } } // there must be a host on the method if (method.getHostConfiguration().getHost() == null) { throw new IllegalArgumentException( "Invalid uri: " + url + ". If you are forwarding/bridging http endpoints, then enable the bridgeEndpoint option on the endpoint: " + getEndpoint()); } return method; }
/** * Creates a holder object for the data to send to the remote server. * * @param exchange the exchange with the IN message with data to send * @return the data holder * @throws CamelExchangeException is thrown if error creating RequestEntity */ protected RequestEntity createRequestEntity(Exchange exchange) throws CamelExchangeException { Message in = exchange.getIn(); if (in.getBody() == null) { return null; } RequestEntity answer = in.getBody(RequestEntity.class); if (answer == null) { try { Object data = in.getBody(); if (data != null) { String contentType = ExchangeHelper.getContentType(exchange); if (contentType != null && HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) { // serialized java object Serializable obj = in.getMandatoryBody(Serializable.class); // write object to output stream ByteArrayOutputStream bos = new ByteArrayOutputStream(); HttpHelper.writeObjectToStream(bos, obj); answer = new ByteArrayRequestEntity( bos.toByteArray(), HttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT); IOHelper.close(bos); } else if (data instanceof File || data instanceof GenericFile) { // file based (could potentially also be a FTP file etc) File file = in.getBody(File.class); if (file != null) { answer = new FileRequestEntity(file, contentType); } } else if (data instanceof String) { // be a bit careful with String as any type can most likely be converted to String // so we only do an instanceof check and accept String if the body is really a String // do not fallback to use the default charset as it can influence the request // (for example application/x-www-form-urlencoded forms being sent) String charset = IOHelper.getCharsetName(exchange, false); answer = new StringRequestEntity((String) data, contentType, charset); } // fallback as input stream if (answer == null) { // force the body as an input stream since this is the fallback InputStream is = in.getMandatoryBody(InputStream.class); answer = new InputStreamRequestEntity(is, contentType); } } } catch (UnsupportedEncodingException e) { throw new CamelExchangeException( "Error creating RequestEntity from message body", exchange, e); } catch (IOException e) { throw new CamelExchangeException("Error serializing message body", exchange, e); } } return answer; }