001: package org.objectweb.celtix.bus.transports.http;
002:
003: import java.io.IOException;
004: import java.net.URL;
005: import java.util.Arrays;
006: import java.util.HashMap;
007: import java.util.List;
008: import java.util.Map;
009: import java.util.logging.Logger;
010:
011: import javax.wsdl.Port;
012: import javax.wsdl.WSDLException;
013: import javax.xml.namespace.QName;
014: import javax.xml.ws.BindingProvider;
015: import javax.xml.ws.handler.MessageContext;
016:
017: import org.objectweb.celtix.Bus;
018: import org.objectweb.celtix.bus.configuration.wsdl.WsdlHttpConfigurationProvider;
019: import org.objectweb.celtix.common.logging.LogUtils;
020: import org.objectweb.celtix.common.util.Base64Exception;
021: import org.objectweb.celtix.common.util.Base64Utility;
022: import org.objectweb.celtix.configuration.Configuration;
023: import org.objectweb.celtix.configuration.ConfigurationBuilder;
024: import org.objectweb.celtix.configuration.ConfigurationBuilderFactory;
025: import org.objectweb.celtix.context.GenericMessageContext;
026: import org.objectweb.celtix.context.ObjectMessageContext;
027: import org.objectweb.celtix.context.OutputStreamMessageContext;
028: import org.objectweb.celtix.transports.ServerTransport;
029: import org.objectweb.celtix.transports.ServerTransportCallback;
030: import org.objectweb.celtix.transports.http.configuration.HTTPServerPolicy;
031: import org.objectweb.celtix.ws.addressing.EndpointReferenceType;
032: import org.objectweb.celtix.wsdl.EndpointReferenceUtils;
033:
034: public abstract class AbstractHTTPServerTransport implements
035: ServerTransport {
036: static final Logger LOG = LogUtils
037: .getL7dLogger(AbstractHTTPServerTransport.class);
038:
039: private static final long serialVersionUID = 1L;
040: private static final String ENDPOINT_CONFIGURATION_URI = "http://celtix.objectweb.org/bus/jaxws/endpoint-config";
041: private static final String HTTP_SERVER_CONFIGURATION_URI = "http://celtix.objectweb.org/bus/transports/http/http-server-config";
042: private static final String HTTP_SERVER_CONFIGURATION_ID = "http-server";
043:
044: protected EndpointReferenceType reference;
045: protected String url;
046: protected String name;
047: protected URL nurl;
048: protected ServerTransportCallback callback;
049: protected Configuration configuration;
050: protected HTTPServerPolicy policy;
051: protected final Bus bus;
052:
053: public AbstractHTTPServerTransport(Bus b, EndpointReferenceType ref)
054: throws WSDLException, IOException {
055: if (b == null) {
056: Thread.dumpStack();
057: }
058: reference = ref;
059: bus = b;
060: // get url (publish address) from endpoint reference
061: url = EndpointReferenceUtils.getAddress(ref);
062: configuration = createConfiguration(ref);
063:
064: nurl = new URL(url);
065: name = nurl.getPath();
066: policy = getServerPolicy(configuration);
067:
068: }
069:
070: private HTTPServerPolicy getServerPolicy(Configuration conf) {
071: HTTPServerPolicy pol = conf.getObject(HTTPServerPolicy.class,
072: "httpServer");
073: if (pol == null) {
074: pol = new HTTPServerPolicy();
075: }
076: return pol;
077: }
078:
079: public OutputStreamMessageContext rebase(MessageContext context,
080: EndpointReferenceType decoupledResponseEndpoint)
081: throws IOException {
082: return null;
083: }
084:
085: public void postDispatch(MessageContext bindingContext,
086: OutputStreamMessageContext context) {
087: // Do not need to do anything here.
088: }
089:
090: public void shutdown() {
091: }
092:
093: private Configuration createConfiguration(EndpointReferenceType ref) {
094: Configuration busConfiguration = bus.getConfiguration();
095: QName serviceName = EndpointReferenceUtils.getServiceName(ref);
096: Configuration endpointConfiguration = busConfiguration
097: .getChild(ENDPOINT_CONFIGURATION_URI, serviceName
098: .toString());
099: Port port = null;
100: try {
101: port = EndpointReferenceUtils.getPort(bus.getWSDLManager(),
102: ref);
103: } catch (WSDLException ex) {
104: // ignore
105: }
106: ConfigurationBuilder cb = ConfigurationBuilderFactory
107: .getBuilder(null);
108:
109: Configuration cfg = cb.getConfiguration(
110: HTTP_SERVER_CONFIGURATION_URI,
111: HTTP_SERVER_CONFIGURATION_ID, endpointConfiguration);
112: if (null == cfg) {
113: cfg = cb
114: .buildConfiguration(HTTP_SERVER_CONFIGURATION_URI,
115: HTTP_SERVER_CONFIGURATION_ID,
116: endpointConfiguration);
117: }
118: // register the additional provider
119: if (null != port) {
120: cfg.getProviders().add(
121: new WsdlHttpConfigurationProvider(port, true));
122: }
123: return cfg;
124: }
125:
126: protected void setHeaders(MessageContext ctx) {
127: ctx.put(ObjectMessageContext.MESSAGE_INPUT, true);
128: Map<String, List<String>> headers = new HashMap<String, List<String>>();
129: copyRequestHeaders(ctx, headers);
130: ctx.put(GenericMessageContext.HTTP_REQUEST_HEADERS, headers);
131:
132: if (headers.containsKey("Authorization")) {
133: List<String> authorizationLines = headers
134: .get("Authorization");
135: String credentials = authorizationLines.get(0);
136: String authType = credentials.split(" ")[0];
137: if ("Basic".equals(authType)) {
138: String authEncoded = credentials.split(" ")[1];
139: try {
140: String authDecoded = new String(Base64Utility
141: .decode(authEncoded));
142: String authInfo[] = authDecoded.split(":");
143: String username = authInfo[0];
144: String password = authInfo[1];
145: ctx
146: .put(BindingProvider.USERNAME_PROPERTY,
147: username);
148: ctx
149: .put(BindingProvider.PASSWORD_PROPERTY,
150: password);
151: } catch (Base64Exception ex) {
152: //ignore, we'll leave things alone. They can try decoding it themselves
153: }
154: }
155: }
156:
157: headers = new HashMap<String, List<String>>();
158: setPolicies(ctx, headers);
159: ctx.put(GenericMessageContext.HTTP_RESPONSE_HEADERS, headers);
160: }
161:
162: protected void setPolicies(MessageContext ctx,
163: Map<String, List<String>> headers) {
164: if (policy.isSetCacheControl()) {
165: headers.put("Cache-Control", Arrays
166: .asList(new String[] { policy.getCacheControl()
167: .value() }));
168: }
169: if (policy.isSetContentLocation()) {
170: headers.put("Content-Location",
171: Arrays.asList(new String[] { policy
172: .getContentLocation() }));
173: }
174: if (policy.isSetContentEncoding()) {
175: headers.put("Content-Encoding",
176: Arrays.asList(new String[] { policy
177: .getContentEncoding() }));
178: }
179: if (policy.isSetContentType()) {
180: headers.put("Content-Type", Arrays
181: .asList(new String[] { policy.getContentType() }));
182: }
183: if (policy.isSetServerType()) {
184: headers.put("Server", Arrays.asList(new String[] { policy
185: .getServerType() }));
186: }
187: if (policy.isSetHonorKeepAlive() && !policy.isHonorKeepAlive()) {
188: headers.put("Connection", Arrays
189: .asList(new String[] { "close" }));
190: }
191:
192: /*
193: * TODO - hook up these policies
194: <xs:attribute name="SuppressClientSendErrors" type="xs:boolean" use="optional" default="false">
195: <xs:attribute name="SuppressClientReceiveErrors" type="xs:boolean" use="optional" default="false">
196: */
197:
198: }
199:
200: /**
201: * @param context The <code>OutputStreamMessageContext</code> to prepare.
202: */
203: public void finalPrepareOutputStreamContext(
204: OutputStreamMessageContext context) throws IOException {
205: if (context instanceof AbstractHTTPServerOutputStreamContext) {
206: ((AbstractHTTPServerOutputStreamContext) context)
207: .flushHeaders();
208: } else if (context instanceof AbstractHTTPRequestorOutputStreamContext) {
209: ((AbstractHTTPRequestorOutputStreamContext) context)
210: .flushHeaders();
211: }
212: }
213:
214: protected abstract void copyRequestHeaders(MessageContext ctx,
215: Map<String, List<String>> headers);
216:
217: }
|