cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From a.@apache.org
Subject [1/2] cxf git commit: [CXF-6232] Refacor CXF's Atmosphere based WebSocket transport part 1
Date Thu, 05 Feb 2015 17:06:24 GMT
Repository: cxf
Updated Branches:
  refs/heads/master 42eba2f94 -> 28e185b27


http://git-wip-us.apache.org/repos/asf/cxf/blob/28e185b2/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletRequest.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletRequest.java
b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletRequest.java
new file mode 100644
index 0000000..870c3c9
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletRequest.java
@@ -0,0 +1,527 @@
+/**
+ * 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.apache.cxf.transport.websocket.jetty;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.AsyncContext;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.Part;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.transport.websocket.InvalidPathException;
+import org.apache.cxf.transport.websocket.WebSocketUtils;
+
+/**
+ * 
+ */
+public class WebSocketVirtualServletRequest implements HttpServletRequest {
+    private static final Logger LOG = LogUtils.getL7dLogger(WebSocketVirtualServletRequest.class);
+
+    private WebSocketServletHolder webSocketHolder;
+    private InputStream in;
+    private Map<String, String> requestHeaders;
+    private Map<String, Object> attributes;
+    
+    public WebSocketVirtualServletRequest(WebSocketServletHolder websocket, InputStream in)

+        throws IOException {
+        this.webSocketHolder = websocket;
+        this.in = in;
+
+        this.requestHeaders = WebSocketUtils.readHeaders(in);
+        String path = requestHeaders.get(WebSocketUtils.URI_KEY);
+        String origin = websocket.getRequestURI();
+        if (!path.startsWith(origin)) {
+            LOG.log(Level.WARNING, "invalid path: {0} not within {1}", new Object[]{path,
origin});
+            throw new InvalidPathException();
+        }
+        this.attributes = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
+        Object v = websocket.getAttribute("org.apache.cxf.transport.endpoint.address");
+        if (v != null) {
+            attributes.put("org.apache.cxf.transport.endpoint.address", v);
+        }
+    }
+
+    @Override
+    public AsyncContext getAsyncContext() {
+        return null;
+    }
+
+    @Override
+    public Object getAttribute(String name) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getAttribute({0}) -> {1}", new Object[] {name , attributes.get(name)});
+        }
+        return attributes.get(name);
+    }
+
+    @Override
+    public Enumeration<String> getAttributeNames() {
+        LOG.log(Level.FINE, "getAttributeNames()");
+        return Collections.enumeration(attributes.keySet());
+    }
+
+    @Override
+    public String getCharacterEncoding() {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "getCharacterEncoding()");
+        return null;
+    }
+
+    @Override
+    public int getContentLength() {
+        LOG.log(Level.FINE, "getContentLength()");
+        return 0;
+    }
+
+    @Override
+    public String getContentType() {
+        LOG.log(Level.FINE, "getContentType()");
+        return requestHeaders.get("Content-Type");
+    }
+
+    @Override
+    public DispatcherType getDispatcherType() {
+        LOG.log(Level.FINE, "getDispatcherType()");
+        return webSocketHolder.getDispatcherType();
+    }
+
+    @Override
+    public ServletInputStream getInputStream() throws IOException {
+        return new ServletInputStream() {
+            @Override
+            public int read() throws IOException {
+                return in.read();
+            }
+
+            @Override
+            public int read(byte[] b, int off, int len) throws IOException {
+                return in.read(b, off, len);
+            }
+        };
+    }
+
+    @Override
+    public String getLocalAddr() {
+        LOG.log(Level.FINE, "getLocalAddr()");
+        return webSocketHolder.getLocalAddr();
+    }
+
+    @Override
+    public String getLocalName() {
+        LOG.log(Level.FINE, "getLocalName()");
+        return webSocketHolder.getLocalName();
+    }
+
+    @Override
+    public int getLocalPort() {
+        LOG.log(Level.FINE, "getLocalPort()");
+        return webSocketHolder.getLocalPort();
+    }
+
+    @Override
+    public Locale getLocale() {
+        LOG.log(Level.FINE, "getLocale()");
+        return webSocketHolder.getLocale();
+    }
+
+    @Override
+    public Enumeration<Locale> getLocales() {
+        LOG.log(Level.FINE, "getLocales()");
+        return webSocketHolder.getLocales();
+    }
+
+    @Override
+    public String getParameter(String name) {
+        // TODO Auto-generated method stub
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getParameter({0})", name);
+        }
+        return null;
+    }
+
+    @Override
+    public Map<String, String[]> getParameterMap() {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "getParameterMap()");
+        return null;
+    }
+
+    @Override
+    public Enumeration<String> getParameterNames() {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "getParameterNames()");
+        return null;
+    }
+
+    @Override
+    public String[] getParameterValues(String name) {
+        // TODO Auto-generated method stub
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getParameterValues({0})", name);
+        }
+        return null;
+    }
+
+    @Override
+    public String getProtocol() {
+        LOG.log(Level.FINE, "getProtocol");
+        return webSocketHolder.getProtocol();
+    }
+
+    @Override
+    public BufferedReader getReader() throws IOException {
+        LOG.log(Level.FINE, "getReader");
+        return new BufferedReader(new InputStreamReader(in, "utf-8"));
+    }
+
+    @Override
+    public String getRealPath(String path) {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "getRealPath");
+        return null;
+    }
+
+    @Override
+    public String getRemoteAddr() {
+        LOG.log(Level.FINE, "getRemoteAddr");
+        return webSocketHolder.getRemoteAddr();
+    }
+
+    @Override
+    public String getRemoteHost() {
+        LOG.log(Level.FINE, "getRemoteHost");
+        return webSocketHolder.getRemoteHost();
+    }
+
+    @Override
+    public int getRemotePort() {
+        LOG.log(Level.FINE, "getRemotePort");
+        return webSocketHolder.getRemotePort();
+    }
+
+    @Override
+    public RequestDispatcher getRequestDispatcher(String path) {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "getRequestDispatcher");
+        return null;
+    }
+
+    @Override
+    public String getScheme() {
+        LOG.log(Level.FINE, "getScheme");
+        return webSocketHolder.getScheme();
+    }
+
+    @Override
+    public String getServerName() {
+        return webSocketHolder.getServerName();
+    }
+
+    @Override
+    public int getServerPort() {
+        LOG.log(Level.FINE, "getServerPort");
+        return webSocketHolder.getServerPort();
+    }
+
+    @Override
+    public ServletContext getServletContext() {
+        LOG.log(Level.FINE, "getServletContext");
+        return webSocketHolder.getServletContext();
+    }
+
+    @Override
+    public boolean isAsyncStarted() {
+        LOG.log(Level.FINE, "isAsyncStarted");
+        return false;
+    }
+
+    @Override
+    public boolean isAsyncSupported() {
+        LOG.log(Level.FINE, "isAsyncSupported");
+        return false;
+    }
+
+    @Override
+    public boolean isSecure() {
+        LOG.log(Level.FINE, "isSecure");
+        return webSocketHolder.isSecure();
+    }
+
+    @Override
+    public void removeAttribute(String name) {
+        LOG.log(Level.FINE, "removeAttribute");
+        attributes.remove(name);
+    }
+
+    @Override
+    public void setAttribute(String name, Object o) {
+        LOG.log(Level.FINE, "setAttribute");
+        attributes.put(name,  o);
+    }
+
+    @Override
+    public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
+        LOG.log(Level.FINE, "setCharacterEncoding");
+        // ignore as we stick to utf-8.
+    }
+
+    @Override
+    public AsyncContext startAsync() {
+        LOG.log(Level.FINE, "startAsync");
+        return null;
+    }
+
+    @Override
+    public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
{
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "startAsync");
+        return null;
+    }
+
+    @Override
+    public boolean authenticate(HttpServletResponse servletResponse) throws IOException,
ServletException {
+        // TODO Auto-generated method stub
+        LOG.log(Level.FINE, "authenticate");
+        return false;
+    }
+
+    @Override
+    public String getAuthType() {
+        LOG.log(Level.FINE, "getAuthType");
+        return webSocketHolder.getAuthType();
+    }
+
+    @Override
+    public String getContextPath() {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getContextPath -> " + webSocketHolder.getContextPath());
+        }
+        return webSocketHolder.getContextPath();
+    }
+
+    @Override
+    public Cookie[] getCookies() {
+        LOG.log(Level.FINE, "getCookies");
+        return null;
+    }
+
+    @Override
+    public long getDateHeader(String name) {
+        LOG.log(Level.FINE, "getDateHeader");
+        return 0;
+    }
+
+    @Override
+    public String getHeader(String name) {
+        LOG.log(Level.FINE, "getHeader");
+        return requestHeaders.get(name);
+    }
+
+    @Override
+    public Enumeration<String> getHeaderNames() {
+        LOG.log(Level.FINE, "getHeaderNames");
+        return Collections.enumeration(requestHeaders.keySet());
+    }
+
+    @Override
+    public Enumeration<String> getHeaders(String name) {
+        LOG.log(Level.FINE, "getHeaders");
+        // our protocol assumes no multiple headers
+        return Collections.enumeration(Arrays.asList(requestHeaders.get(name)));
+    }
+
+    @Override
+    public int getIntHeader(String name) {
+        LOG.log(Level.FINE, "getIntHeader");
+        String v = requestHeaders.get(name);
+        return v == null ? -1 : Integer.parseInt(v);
+    }
+
+    @Override
+    public String getMethod() {
+        LOG.log(Level.FINE, "getMethod");
+        return requestHeaders.get(WebSocketUtils.METHOD_KEY);
+    }
+
+    @Override
+    public Part getPart(String name) throws IOException, ServletException {
+        LOG.log(Level.FINE, "getPart");
+        return null;
+    }
+
+    @Override
+    public Collection<Part> getParts() throws IOException, ServletException {
+        LOG.log(Level.FINE, "getParts");
+        return null;
+    }
+
+    @Override
+    public String getPathInfo() {
+        String uri = requestHeaders.get(WebSocketUtils.URI_KEY);
+        String servletpath = webSocketHolder.getServletPath(); 
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getPathInfo " + servletpath + " " + uri);
+        }
+        //TODO remove the query string part
+        //REVISIT may cache this value in requstHeaders?
+        return uri.substring(servletpath.length());
+    }
+
+    @Override
+    public String getPathTranslated() {
+        String path = getPathInfo();
+        String opathtrans = webSocketHolder.getPathTranslated();
+        // some container may choose not to return this value
+        if (opathtrans == null) {
+            return null;
+        }
+        String opathinfo = webSocketHolder.getPathInfo();
+        LOG.log(Level.FINE, "getPathTranslated " + path + " " + opathinfo);
+        int pos = opathtrans.indexOf(opathinfo);
+        //REVISIT may cache this value in requstHeaders?
+        return new StringBuilder().append(opathtrans.substring(0, pos)).append(path).toString();
+    }
+
+    @Override
+    public String getQueryString() {
+        LOG.log(Level.FINE, "getQueryString");
+        return null;
+    }
+
+    @Override
+    public String getRemoteUser() {
+        LOG.log(Level.FINE, "getRemoteUser");
+        return null;
+    }
+
+    @Override
+    public String getRequestURI() {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getRequestURI " + requestHeaders.get(WebSocketUtils.URI_KEY));
+        }
+        return requestHeaders.get(WebSocketUtils.URI_KEY);
+    }
+
+    @Override
+    public StringBuffer getRequestURL() {
+        StringBuffer sb = webSocketHolder.getRequestURL();
+        String ouri = webSocketHolder.getRequestURI();
+        String uri = getRequestURI();
+        sb.append(uri.substring(ouri.length()));
+        LOG.log(Level.FINE, "getRequestURL " + uri);
+        return sb;
+    }
+
+    @Override
+    public String getRequestedSessionId() {
+        LOG.log(Level.FINE, "getRequestedSessionId");
+        return null;
+    }
+
+    @Override
+    public String getServletPath() {
+        LOG.log(Level.FINE, "getServletPath " + webSocketHolder.getServletPath());
+        return webSocketHolder.getServletPath();
+    }
+
+    @Override
+    public HttpSession getSession() {
+        LOG.log(Level.FINE, "getSession");
+        return null;
+    }
+
+    @Override
+    public HttpSession getSession(boolean create) {
+        LOG.log(Level.FINE, "getSession");
+        return null;
+    }
+
+    @Override
+    public Principal getUserPrincipal() {
+        LOG.log(Level.FINE, "getUserPrincipal");
+        return webSocketHolder.getUserPrincipal();
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromCookie() {
+        LOG.log(Level.FINE, "isRequestedSessionIdFromCookie");
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromURL() {
+        LOG.log(Level.FINE, "isRequestedSessionIdFromURL");
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdFromUrl() {
+        LOG.log(Level.FINE, "isRequestedSessionIdFromUrl");
+        return false;
+    }
+
+    @Override
+    public boolean isRequestedSessionIdValid() {
+        LOG.log(Level.FINE, "isRequestedSessionIdValid");
+        return false;
+    }
+
+    @Override
+    public boolean isUserInRole(String role) {
+        LOG.log(Level.FINE, "isUserInRole");
+        return false;
+    }
+
+    @Override
+    public void login(String username, String password) throws ServletException {
+        LOG.log(Level.FINE, "login");
+        
+    }
+
+    @Override
+    public void logout() throws ServletException {
+        LOG.log(Level.FINE, "logout");
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/28e185b2/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletResponse.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletResponse.java
b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletResponse.java
new file mode 100644
index 0000000..b9908b1
--- /dev/null
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty/WebSocketVirtualServletResponse.java
@@ -0,0 +1,369 @@
+/**
+ * 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.apache.cxf.transport.websocket.jetty;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.transport.websocket.WebSocketConstants;
+import org.apache.cxf.transport.websocket.WebSocketUtils;
+
+/**
+ * 
+ */
+public class WebSocketVirtualServletResponse implements HttpServletResponse {
+    private static final Logger LOG = LogUtils.getL7dLogger(WebSocketVirtualServletResponse.class);
+    private WebSocketServletHolder webSocketHolder;
+    private Map<String, String> responseHeaders;
+    private ServletOutputStream outputStream;
+
+    public WebSocketVirtualServletResponse(WebSocketServletHolder websocket) {
+        this.webSocketHolder = websocket;
+        this.responseHeaders = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
+        this.outputStream = createOutputStream();
+    }
+
+    @Override
+    public void flushBuffer() throws IOException {
+        LOG.log(Level.FINE, "flushBuffer()");
+        outputStream.flush();
+    }
+
+    @Override
+    public int getBufferSize() {
+        LOG.log(Level.FINE, "getBufferSize()");
+        return 0;
+    }
+
+    @Override
+    public String getCharacterEncoding() {
+        LOG.log(Level.FINE, "getCharacterEncoding()");
+        return null;
+    }
+
+    @Override
+    public String getContentType() {
+        LOG.log(Level.FINE, "getContentType()");
+        return responseHeaders.get("Content-Type");
+    }
+
+    @Override
+    public Locale getLocale() {
+        LOG.log(Level.FINE, "getLocale");
+        return null;
+    }
+
+    @Override
+    public ServletOutputStream getOutputStream() throws IOException {
+        return outputStream;
+    }
+
+    @Override
+    public PrintWriter getWriter() throws IOException {
+        LOG.log(Level.FINE, "getWriter()");
+        return new PrintWriter(getOutputStream());
+    }
+
+    @Override
+    public boolean isCommitted() {
+        return false;
+    }
+
+    @Override
+    public void reset() {
+    }
+
+    @Override
+    public void resetBuffer() {
+        LOG.log(Level.FINE, "resetBuffer()");
+    }
+
+    @Override
+    public void setBufferSize(int size) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setBufferSize({0})", size);
+        }
+    }
+
+    @Override
+    public void setCharacterEncoding(String charset) {
+        // TODO 
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setCharacterEncoding({0})", charset);
+        }
+    }
+
+    @Override
+    public void setContentLength(int len) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setContentLength({0})", len);
+        }
+        responseHeaders.put("Content-Length", Integer.toString(len));
+    }
+
+    @Override
+    public void setContentType(String type) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setContentType({0})", type);
+        }
+        responseHeaders.put("Content-Type", type);
+    }
+
+    @Override
+    public void setLocale(Locale loc) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setLocale({0})", loc);
+        }
+    }
+
+    @Override
+    public void addCookie(Cookie cookie) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "addCookie({0})", cookie);
+        }
+    }
+
+    @Override
+    public void addDateHeader(String name, long date) {
+        // TODO
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "addDateHeader({0}, {1})", new Object[]{name, date});
+        }
+    }
+
+    @Override
+    public void addHeader(String name, String value) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "addHeader({0}, {1})", new Object[]{name, value});
+        }
+        responseHeaders.put(name, value);
+    }
+
+    @Override
+    public void addIntHeader(String name, int value) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "addIntHeader({0}, {1})", new Object[]{name, value});
+        }
+        responseHeaders.put(name, Integer.toString(value));
+    }
+
+    @Override
+    public boolean containsHeader(String name) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "containsHeader({0})", name);
+        }
+        return responseHeaders.containsKey(name);
+    }
+
+    @Override
+    public String encodeRedirectURL(String url) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "encodeRedirectURL({0})", url);
+        }
+        return null;
+    }
+
+    @Override
+    public String encodeRedirectUrl(String url) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "encodeRedirectUrl({0})", url);
+        }
+        return null;
+    }
+
+    @Override
+    public String encodeURL(String url) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "encodeURL({0})", url);
+        }
+        return null;
+    }
+
+    @Override
+    public String encodeUrl(String url) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "encodeUrl({0})", url);
+        }
+        return null;
+    }
+
+    @Override
+    public String getHeader(String name) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getHeader({0})", name);
+        }
+        return null;
+    }
+
+    @Override
+    public Collection<String> getHeaderNames() {
+        LOG.log(Level.FINE, "getHeaderNames()");
+        return null;
+    }
+
+    @Override
+    public Collection<String> getHeaders(String name) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "getHeaders({0})", name);
+        }
+        return null;
+    }
+
+    @Override
+    public int getStatus() {
+        LOG.log(Level.FINE, "getStatus()");
+        String v = responseHeaders.get(WebSocketUtils.SC_KEY);
+        return v == null ? 200 : Integer.parseInt(v);
+    }
+
+    @Override
+    public void sendError(int sc) throws IOException {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "sendError{0}", sc);
+        }
+        responseHeaders.put(WebSocketUtils.SC_KEY, Integer.toString(sc));
+        byte[] data = WebSocketUtils.buildResponse(responseHeaders, null, 0, 0);
+        webSocketHolder.write(data, 0, data.length);
+    }
+
+    @Override
+    public void sendError(int sc, String msg) throws IOException {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "sendError({0}, {1})", new Object[]{sc, msg});
+        }
+        responseHeaders.put(WebSocketUtils.SC_KEY, Integer.toString(sc));
+        byte[] data = WebSocketUtils.buildResponse(responseHeaders, null, 0, 0);
+        webSocketHolder.write(data, 0, data.length);
+    }
+
+    @Override
+    public void sendRedirect(String location) throws IOException {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "sendRedirect({0})", location);
+        }
+    }
+
+    @Override
+    public void setDateHeader(String name, long date) {
+        // ignore
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setDateHeader({0}, {1})", new Object[]{name, date});
+        }
+    }
+
+    @Override
+    public void setHeader(String name, String value) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setHeader({0}, {1})", new Object[]{name, value});
+        }
+        responseHeaders.put(name, value);
+    }
+
+    @Override
+    public void setIntHeader(String name, int value) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setIntHeader({0}, {1})", new Object[]{name, value});
+        }
+    }
+
+    @Override
+    public void setStatus(int sc) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setStatus({0})", sc);
+        }
+        responseHeaders.put(WebSocketUtils.SC_KEY, Integer.toString(sc));
+    }
+
+    @Override
+    public void setStatus(int sc, String sm) {
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.log(Level.FINE, "setStatus({0}, {1})", new Object[]{sc, sm});
+        }
+        responseHeaders.put(WebSocketUtils.SC_KEY, Integer.toString(sc));
+    }
+
+    private ServletOutputStream createOutputStream() {
+        //REVISIT
+        // This output buffering is needed as the server side websocket does
+        // not support the fragment transmission mode when sending back a large data.
+        // And this buffering is only used for the response for the initial service innovation.
+        // For the subsequently pushed data to the socket are sent back
+        // unbuffered as individual websocket messages.
+        // the things to consider :
+        // - provide a size limit if we are use this buffering
+        // - add a chunking mode in the cxf websocket's binding.
+        return new ServletOutputStream() {
+            private InternalByteArrayOutputStream buffer = new InternalByteArrayOutputStream();
+
+            @Override
+            public void write(int b) throws IOException {
+                byte[] data = new byte[1];
+                data[0] = (byte)b;
+                write(data, 0, 1);
+            }
+
+            @Override
+            public void write(byte[] data) throws IOException {
+                write(data, 0, data.length);
+            }
+
+            @Override
+            public void write(byte[] data, int offset, int length) throws IOException {
+                if (responseHeaders.get(WebSocketUtils.FLUSHED_KEY) == null) {
+                    // buffer the data until it gets flushed
+                    buffer.write(data, offset, length);
+                } else {
+                    // unbuffered write to the socket
+                    String respid = responseHeaders.get(WebSocketConstants.DEFAULT_RESPONSE_ID_KEY);
+                    byte[] headers = respid != null 
+                        ? WebSocketUtils.buildHeaderLine(WebSocketConstants.DEFAULT_RESPONSE_ID_KEY,
respid) : null;
+                    data = WebSocketUtils.buildResponse(headers, data, offset, length);
+                    webSocketHolder.write(data, 0, data.length);
+                }
+            }
+            public void close() throws IOException {
+                if (responseHeaders.get(WebSocketUtils.FLUSHED_KEY) == null) {
+                    byte[] data = WebSocketUtils.buildResponse(responseHeaders, buffer.getBytes(),
0, buffer.size());
+                    webSocketHolder.write(data, 0, data.length);
+                    responseHeaders.put(WebSocketUtils.FLUSHED_KEY, "true");
+                }
+                super.close();
+            }
+        };
+    }
+
+    private static class InternalByteArrayOutputStream extends ByteArrayOutputStream {
+        public byte[] getBytes() {
+            return buf;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/28e185b2/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty9/Jetty9WebSocketDestination.java
----------------------------------------------------------------------
diff --git a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty9/Jetty9WebSocketDestination.java
b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty9/Jetty9WebSocketDestination.java
index 32e681e..af16b9f 100644
--- a/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty9/Jetty9WebSocketDestination.java
+++ b/rt/transports/websocket/src/main/java/org/apache/cxf/transport/websocket/jetty9/Jetty9WebSocketDestination.java
@@ -48,9 +48,9 @@ import org.apache.cxf.transport.http_jetty.JettyHTTPServerEngineFactory;
 import org.apache.cxf.transport.websocket.InvalidPathException;
 import org.apache.cxf.transport.websocket.WebSocketConstants;
 import org.apache.cxf.transport.websocket.WebSocketDestinationService;
-import org.apache.cxf.transport.websocket.WebSocketServletHolder;
-import org.apache.cxf.transport.websocket.WebSocketVirtualServletRequest;
-import org.apache.cxf.transport.websocket.WebSocketVirtualServletResponse;
+import org.apache.cxf.transport.websocket.jetty.WebSocketServletHolder;
+import org.apache.cxf.transport.websocket.jetty.WebSocketVirtualServletRequest;
+import org.apache.cxf.transport.websocket.jetty.WebSocketVirtualServletResponse;
 import org.apache.cxf.workqueue.WorkQueueManager;
 import org.eclipse.jetty.server.Request;
 import org.eclipse.jetty.websocket.api.Session;

http://git-wip-us.apache.org/repos/asf/cxf/blob/28e185b2/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/websocket/WebSocketTestClient.java
----------------------------------------------------------------------
diff --git a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/websocket/WebSocketTestClient.java
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/websocket/WebSocketTestClient.java
index 69ad06c..6f3f8ad 100644
--- a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/websocket/WebSocketTestClient.java
+++ b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/websocket/WebSocketTestClient.java
@@ -307,7 +307,15 @@ class WebSocketTestClient {
         }
 
         private int length(Object o) {
-            return o instanceof char[] ? ((String)o).length() : (o instanceof byte[] ? ((byte[])o).length
: 0);
+            if (o instanceof String) {
+                return ((String)o).length();
+            } else if (o instanceof char[]) {
+                return ((char[])o).length;
+            } else if (o instanceof byte[]) {
+                return ((byte[])o).length;
+            } else {
+                return 0;
+            }
         }
 
         private int getchar(Object o, int p) {


Mime
View raw message