Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source.
   * Copyright 2012, Red Hat, Inc., and individual contributors
   * as indicated by the @author tags. See the copyright.txt file in the
   * distribution for a full listing of individual contributors.
   *
   * This is free software; you can redistribute it and/or modify it
   * under the terms of the GNU Lesser General Public License as
   * published by the Free Software Foundation; either version 2.1 of
  * the License, or (at your option) any later version.
  *
  * This software is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this software; if not, write to the Free
  * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */
 
 package io.undertow.client.http;
 
 import org.xnio.Pool;
 
 
 import static io.undertow.client.UndertowClientMessages.MESSAGES;
 import static io.undertow.util.Headers.CLOSE;
 import static io.undertow.util.Headers.CONNECTION;
 import static io.undertow.util.Headers.CONTENT_LENGTH;
 import static io.undertow.util.Headers.TRANSFER_ENCODING;
 import static io.undertow.util.Headers.UPGRADE;
 import static org.xnio.Bits.allAreClear;
 import static org.xnio.Bits.allAreSet;
 import static org.xnio.Bits.anyAreSet;
 import static org.xnio.IoUtils.safeClose;

Author(s):
David M. Lloyd
 
 
         @Override
         public void handleEvent(StreamSinkConduit channel) {
             .terminateRequest();
         }
     };
         @Override
         public void handleEvent(StreamSourceConduit channel) {
             .terminateResponse();
         }
     };
 
     private final Deque<HttpClientExchangependingQueue = new ArrayDeque<HttpClientExchange>();
 
    private final OptionMap options;
    private final StreamConnection connection;
    private final ClientReadListener clientReadListener = new ClientReadListener();
    private final Pool<ByteBufferbufferPool;
    private final StreamSinkConduit originalSinkConduit;
    private static final int UPGRADED = 1 << 28;
    private static final int UPGRADE_REQUESTED = 1 << 29;
    private static final int CLOSE_REQ = 1 << 30;
    private static final int CLOSED = 1 << 31;
    private int count = 0;
    private int state;
    HttpClientConnection(final StreamConnection connectionfinal OptionMap optionsfinal Pool<ByteBufferbufferPool) {
        this. = options;
        this. = connection;
        this. = bufferPool;
        this. = connection.getSinkChannel().getConduit();
        connection.getCloseSetter().set(new ChannelListener<StreamConnection>() {
            public void handleEvent(StreamConnection channel) {
                HttpClientConnection.this. |= ;
                ChannelListeners.invokeChannelListener(HttpClientConnection.this.get());
            }
        });
    }
    @Override
    public Pool<ByteBuffergetBufferPool() {
        return ;
    }
    @Override
    public SocketAddress getPeerAddress() {
        return .getPeerAddress();
    }
        return ;
    }
    @Override
    public <A extends SocketAddress> A getPeerAddress(Class<A> type) {
        return .getPeerAddress(type);
    }
    @Override
        return ;
    }
    @Override
    public SocketAddress getLocalAddress() {
        return .getLocalAddress();
    }
    @Override
    public <A extends SocketAddress> A getLocalAddress(Class<A> type) {
        return .getLocalAddress(type);
    }
    @Override
    public XnioWorker getWorker() {
        return .getWorker();
    }
    @Override
    public XnioIoThread getIoThread() {
        return .getIoThread();
    }
    @Override
    public boolean isOpen() {
        return .isOpen() && allAreClear( | );
    }
    @Override
    public boolean supportsOption(Option<?> option) {
        return .supportsOption(option);
    }
    @Override
    public <T> T getOption(Option<T> optionthrows IOException {
        return .getOption(option);
    }
    @Override
    public <T> T setOption(Option<T> option, T valuethrows IllegalArgumentExceptionIOException {
        return .setOption(optionvalue);
    }
    @Override
    public boolean isUpgraded() {
        return anyAreSet( | );
    }
    @Override
    public void sendRequest(final ClientRequest requestfinal ClientCallback<ClientExchangeclientCallback) {
        ++;
        if (anyAreSet( |  |  | )) {
            clientCallback.failed(..invalidConnectionState());
            return;
        }
        final HttpClientExchange httpClientExchange = new HttpClientExchange(clientCallbackrequestthis);
        if ( == null) {
            initiateRequest(httpClientExchange);
        } else {
            .add(httpClientExchange);
        }
    }
    private void initiateRequest(HttpClientExchange httpClientExchange) {
         = httpClientExchange;
         = new HttpResponseBuilder();
        ClientRequest request = httpClientExchange.getRequest();
        String connectionString = request.getRequestHeaders().getFirst();
        if (connectionString != null) {
            HttpString connectionHttpString = new HttpString(connectionString);
            if (connectionHttpString.equals()) {
                 |= ;
            } else if(connectionHttpString.equals()) {
                 |= ;
            }
        } else if (request.getProtocol() != .) {
             |= ;
        }
        if (request.getRequestHeaders().contains()) {
             |= ;
        }
        //setup the client request conduits
        final ConduitStreamSourceChannel sourceChannel = .getSourceChannel();
        sourceChannel.setReadListener();
        sourceChannel.resumeReads();
        ConduitStreamSinkChannel sinkChannel = .getSinkChannel();
        StreamSinkConduit conduit = ;
        conduit = new HttpRequestConduit(conduitrequest);
        String fixedLengthString = request.getRequestHeaders().getFirst();
        String transferEncodingString = request.getRequestHeaders().getLast();
        boolean hasContent = true;
        if (fixedLengthString != null) {
            try {
                long length = Long.parseLong(fixedLengthString);
                conduit = new ClientFixedLengthStreamSinkConduit(conduitlengthfalsefalse);
                hasContent = length != 0;
            } catch (NumberFormatException e) {
                handleError(new IOException(e));
                return;
            }
        } else if (transferEncodingString != null) {
            if (!transferEncodingString.toLowerCase(.).contains(..toString())) {
                handleError(..unknownTransferEncoding(transferEncodingString));
                return;
            }
            conduit = new ChunkedStreamSinkConduit(conduithttpClientExchange.getConnection().getBufferPool(), falsefalsehttpClientExchange.getRequest().getRequestHeaders(), httpClientExchange);
        } else {
            conduit = new ClientFixedLengthStreamSinkConduit(conduit, 0, falsefalse);
            hasContent = false;
        }
        sinkChannel.setConduit(conduit);
        httpClientExchange.invokeReadReadyCallback(httpClientExchange);
        if (!hasContent) {
            //if there is no content we flush the response channel.
            //otherwise it is up to the user
            try {
                sinkChannel.shutdownWrites();
                if (!sinkChannel.flush()) {
                    sinkChannel.setWriteListener(ChannelListeners.flushingChannelListener(nullnew ChannelExceptionHandler<ConduitStreamSinkChannel>() {
                        @Override
                        public void handleException(ConduitStreamSinkChannel channelIOException exception) {
                            handleError(exception);
                        }
                    }));
                }
            } catch (IOException e) {
                handleError(e);
            }
        } else if (!sinkChannel.isWriteResumed()) {
            try {
                //TODO: this needs some more thought
                if (!sinkChannel.flush()) {
                    sinkChannel.setWriteListener(new ChannelListener<ConduitStreamSinkChannel>() {
                        @Override
                        public void handleEvent(ConduitStreamSinkChannel channel) {
                            try {
                                if (channel.flush()) {
                                    channel.suspendWrites();
                                }
                            } catch (IOException e) {
                                handleError(e);
                            }
                        }
                    });
                    sinkChannel.resumeWrites();
                }
            } catch (IOException e) {
                handleError(e);
            }
        }
    }
    private void handleError(IOException exception) {
        .setFailed(exception);
        ..ioException(exception);
        safeClose();
    }
    public StreamConnection performUpgrade() throws IOException {
        // Upgrade the connection
        // Set the upgraded flag already to prevent new requests after this one
        if (allAreSet( |  | )) {
            throw new IOException(..connectionClosed());
        }
         |= ;
        return ;
    }
    public void close() throws IOException {
        if (anyAreSet()) {
            return;
        }
         |=  | ;
        .close();
    }

    
Notification that the current request is finished
    public void requestDone() {
        if (anyAreSet()) {
             = null;
            this. |= ;
            IoUtils.safeClose();
        } else if (anyAreSet()) {
            .getSourceChannel().suspendReads();
             = null;
            return;
        }
         = null;
        HttpClientExchange next = .poll();
        if (next == null) {
            //we resume reads, so if the target goes away we get notified
            .getSourceChannel().resumeReads();
        } else {
            initiateRequest(next);
        }
    }
        public void handleEvent(StreamSourceChannel channel) {
            HttpResponseBuilder builder = ;
            final Pooled<ByteBufferpooled = .allocate();
            final ByteBuffer buffer = pooled.getResource();
            boolean free = true;
            try {
                if (builder == null) {
                    //read ready when no request pending
                    buffer.clear();
                    try {
                        int res = channel.read(buffer);
                         if(res == -1) {
                            ..debugf("Connection to %s was closed by the target server".getPeerAddress());
                            IoUtils.safeClose(HttpClientConnection.this);
                        } else if(res != 0) {
                             ..debugf("Target server %s sent unexpected data when no request pending, closing connection".getPeerAddress());
                             IoUtils.safeClose(HttpClientConnection.this);
                        }
                        //otherwise it is a spurious notification
                    } catch (IOException e) {
                        if (..isDebugEnabled()) {
                            ..debugf(e"Connection closed with IOException");
                        }
                        safeClose();
                    }
                    return;
                }
                final ResponseParseState state = builder.getParseState();
                int res;
                do {
                    buffer.clear();
                    try {
                        res = channel.read(buffer);
                    } catch (IOException e) {
                        if (..isDebugEnabled()) {
                            ..debugf(e"Connection closed with IOException");
                        }
                        safeClose(channel);
                        .setFailed(new IOException(.connectionClosed()));
                        return;
                    }
                    if (res == 0) {
                        if (!channel.isReadResumed()) {
                            channel.getReadSetter().set(this);
                            channel.resumeReads();
                        }
                        return;
                    } else if (res == -1) {
                        channel.suspendReads();
                        IoUtils.safeClose(HttpClientConnection.this);
                        // Cancel the current active request
                        .setFailed(new IOException(.connectionClosed()));
                        return;
                    }
                    buffer.flip();
                    ..handle(bufferstatebuilder);
                    if (buffer.hasRemaining()) {
                        free = false;
                        .pushBack(pooled);
                    }
                } while (!state.isComplete());
                final ClientResponse response = builder.build();
                String connectionString = response.getResponseHeaders().getFirst();
                //check if an upgrade worked
                if (anyAreSet(HttpClientConnection.this.)) {
                    if ((connectionString == null || !.equalToString(connectionString)) && !response.getResponseHeaders().contains()) {
                        //just unset the upgrade requested flag
                        HttpClientConnection.this. &= ~;
                    }
                }
                if(connectionString != null) {
                    if (HttpString.tryFromString(connectionString).equals(.)) {
                        HttpClientConnection.this. |= ;
                    }
                }
                if (builder.getStatusCode() == 100) {
                     = new HttpResponseBuilder();
                    .setContinueResponse(response);
                } else {
                    prepareResponseChannel(response);
                    channel.getReadSetter().set(null);
                    channel.suspendReads();
                     = null;
                    .setResponse(response);
                }
            } catch (Exception e) {
                ..exceptionProcessingRequest(e);
                IoUtils.safeClose();
                .setFailed(new IOException(e));
            } finally {
                if (freepooled.free();
            }
        }
    }
    private void prepareResponseChannel(ClientResponse responseClientExchange exchange) {
        String encoding = response.getResponseHeaders().getLast();
        boolean chunked = encoding != null && ..equals(new HttpString(encoding));
        String length = response.getResponseHeaders().getFirst();
        if (exchange.getRequest().getMethod().equals(.)) {
        } else if (chunked) {
        } else if (length != null) {
            try {
                long contentLength = Long.parseLong(length);
            } catch (NumberFormatException e) {
                handleError(new IOException(e));
                throw e;
            }
        } else if (response.getProtocol().equals(.)) {
        } else {
             |= ;
        }
    }
New to GrepCode? Check out our FAQ X