001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.component.jetty;
018
019 import java.io.IOException;
020 import java.util.Map;
021
022 import org.apache.camel.Exchange;
023 import org.apache.camel.Message;
024 import org.apache.camel.component.http.HttpHeaderFilterStrategy;
025 import org.apache.camel.component.http.HttpOperationFailedException;
026 import org.apache.camel.spi.HeaderFilterStrategy;
027 import org.apache.commons.logging.Log;
028 import org.apache.commons.logging.LogFactory;
029
030 /**
031 * @version $Revision: 999444 $
032 */
033 public class DefaultJettyHttpBinding implements JettyHttpBinding {
034
035 private static final transient Log LOG = LogFactory.getLog(DefaultJettyHttpBinding.class);
036 private HeaderFilterStrategy headerFilterStrategy = new HttpHeaderFilterStrategy();
037 private boolean throwExceptionOnFailure;
038
039 public void populateResponse(Exchange exchange, JettyContentExchange httpExchange) throws Exception {
040 int responseCode = httpExchange.getResponseStatus();
041
042 if (LOG.isDebugEnabled()) {
043 LOG.debug("HTTP responseCode: " + responseCode);
044 }
045
046 Message in = exchange.getIn();
047 if (!isThrowExceptionOnFailure()) {
048 // if we do not use failed exception then populate response for all response codes
049 populateResponse(exchange, httpExchange, in, getHeaderFilterStrategy(), responseCode);
050 } else {
051 if (responseCode >= 100 && responseCode < 300) {
052 // only populate response for OK response
053 populateResponse(exchange, httpExchange, in, getHeaderFilterStrategy(), responseCode);
054 } else {
055 // operation failed so populate exception to throw
056 throw populateHttpOperationFailedException(exchange, httpExchange, responseCode);
057 }
058 }
059 }
060
061 public HeaderFilterStrategy getHeaderFilterStrategy() {
062 return headerFilterStrategy;
063 }
064
065 public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
066 this.headerFilterStrategy = headerFilterStrategy;
067 }
068
069 public boolean isThrowExceptionOnFailure() {
070 return throwExceptionOnFailure;
071 }
072
073 public void setThrowExceptionOnFailure(boolean throwExceptionOnFailure) {
074 this.throwExceptionOnFailure = throwExceptionOnFailure;
075 }
076
077 protected void populateResponse(Exchange exchange, JettyContentExchange httpExchange,
078 Message in, HeaderFilterStrategy strategy, int responseCode) throws IOException {
079 Message answer = exchange.getOut();
080
081 answer.setHeaders(in.getHeaders());
082 answer.setHeader(Exchange.HTTP_RESPONSE_CODE, responseCode);
083 answer.setBody(extractResponseBody(exchange, httpExchange));
084
085 // propagate HTTP response headers
086 // must use entrySet to ensure case of keys is preserved
087 for (Map.Entry<String, String> entry : httpExchange.getHeaders().entrySet()) {
088 String name = entry.getKey();
089 String value = entry.getValue();
090 if (name.toLowerCase().equals("content-type")) {
091 name = Exchange.CONTENT_TYPE;
092 }
093 if (strategy != null && !strategy.applyFilterToExternalHeaders(name, value, exchange)) {
094 answer.setHeader(name, value);
095 }
096 }
097 }
098
099 protected HttpOperationFailedException populateHttpOperationFailedException(Exchange exchange, JettyContentExchange httpExchange,
100 int responseCode) throws IOException {
101 HttpOperationFailedException exception;
102 String uri = httpExchange.getUrl();
103 Map<String, String> headers = httpExchange.getHeaders();
104 String body = extractResponseBody(exchange, httpExchange);
105
106 if (responseCode >= 300 && responseCode < 400) {
107 String locationHeader = httpExchange.getResponseFields().getStringField("location");
108 if (locationHeader != null) {
109 exception = new HttpOperationFailedException(uri, responseCode, null, locationHeader, headers, body);
110 } else {
111 // no redirect location
112 exception = new HttpOperationFailedException(uri, responseCode, null, null, headers, body);
113 }
114 } else {
115 // internal server error (error code 500)
116 exception = new HttpOperationFailedException(uri, responseCode, null, null, headers, body);
117 }
118
119 return exception;
120 }
121
122 protected String extractResponseBody(Exchange exchange, JettyContentExchange httpExchange) throws IOException {
123 return httpExchange.getBody();
124 }
125
126 }