Search in sources :

Example 1 with ClientConnection

use of com.ociweb.pronghorn.network.ClientConnection in project GreenLightning by oci-pronghorn.

the class HTTPClientRequestTrafficStage method hasOpenConnection.

// has side effect of storing the active connection as a member so it need not be looked up again later.
public boolean hasOpenConnection(Pipe<ClientHTTPRequestSchema> requestPipe, Pipe<NetPayloadSchema>[] output, ClientCoordinator ccm, int activePipe) {
    if (PipeReader.peekMsg(requestPipe, -1)) {
        return com.ociweb.pronghorn.network.http.HTTPClientRequestStage.hasRoomForEOF(output);
    }
    final int msgIdx = PipeReader.peekInt(requestPipe, 0);
    // these fields are assumed to be the same for all mesage types.
    int hostMeta = PipeReader.peekDataMeta(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_HOST_2);
    int hostLen = PipeReader.peekDataLength(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_HOST_2);
    int port = PipeReader.peekInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_PORT_1);
    int sessionId = PipeReader.peekInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_SESSION_10);
    PipeUTF8MutableCharSquence mCharSeq = mCharSequence.setToField(requestPipe, hostMeta, hostLen);
    long connectionId;
    if (ClientHTTPRequestSchema.MSG_FASTHTTPGET_200 == msgIdx) {
        connectionId = PipeReader.peekLong(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_CONNECTIONID_20);
    // assert(connectionId == ccm.lookup(mCharSeq, port, sessionId));
    } else {
        connectionId = ccm.lookup(ClientCoordinator.lookupHostId((CharSequence) mCharSeq, READER), port, sessionId);
    }
    ClientConnection activeConnection = ClientCoordinator.openConnection(ccm, mCharSeq, port, sessionId, output, connectionId, reader, ccf);
    if (null != activeConnection) {
        if (ccm.isTLS) {
            // If this connection needs to complete a handshake first then do that and do not send the request content yet.
            HandshakeStatus handshakeStatus = activeConnection.getEngine().getHandshakeStatus();
            if (HandshakeStatus.FINISHED != handshakeStatus && HandshakeStatus.NOT_HANDSHAKING != handshakeStatus) {
                activeConnection = null;
                return false;
            }
        }
        if (activeConnection.isDisconnecting()) {
            if (ccm.isTLS) {
                logger.info("Double check the client side certificates");
            } else {
                logger.info("Double check the server port to ensure it is open");
            }
            if (PipeReader.tryReadFragment(requestPipe)) {
                // special case for connection which was closed, must abandon old data
                // and allow trafic cop get back ack and not hang the system.
                PipeReader.releaseReadLock(requestPipe);
                decReleaseCount(activePipe);
            }
            return false;
        }
    } else {
        // not yet open, this is not an error just an attempt to try again soon.
        return false;
    }
    // this should be done AFTER any handshake logic
    return PipeWriter.hasRoomForWrite(output[activeConnection.requestPipeLineIdx()]);
}
Also used : ClientConnection(com.ociweb.pronghorn.network.ClientConnection) PipeUTF8MutableCharSquence(com.ociweb.pronghorn.pipe.PipeUTF8MutableCharSquence) HandshakeStatus(javax.net.ssl.SSLEngineResult.HandshakeStatus)

Example 2 with ClientConnection

use of com.ociweb.pronghorn.network.ClientConnection in project GreenLightning by oci-pronghorn.

the class HTTPClientRequestTrafficStage method processMessagesForPipe.

@Override
protected void processMessagesForPipe(int activePipe) {
    Pipe<ClientHTTPRequestSchema> requestPipe = input[activePipe];
    while (PipeReader.hasContentToRead(requestPipe) && hasReleaseCountRemaining(activePipe) && isChannelUnBlocked(activePipe) && hasOpenConnection(requestPipe, output, ccm, activePipe) && PipeReader.tryReadFragment(requestPipe)) {
        int msgIdx = PipeReader.getMsgIdx(requestPipe);
        switch(msgIdx) {
            case ClientHTTPRequestSchema.MSG_FASTHTTPGET_200:
                {
                    final byte[] hostBack = Pipe.blob(requestPipe);
                    final int hostPos = PipeReader.readBytesPosition(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_HOST_2);
                    final int hostLen = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_HOST_2);
                    final int hostMask = Pipe.blobMask(requestPipe);
                    int routeId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_DESTINATION_11);
                    int port = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_PORT_1);
                    int userId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_SESSION_10);
                    long connectionId = PipeReader.readLong(requestPipe, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_CONNECTIONID_20);
                    ClientConnection clientConnection;
                    if (-1 != connectionId && null != (clientConnection = (ClientConnection) ccm.connectionForSessionId(connectionId))) {
                        assert (clientConnection.singleUsage(stageId)) : "Only a single Stage may update the clientConnection.";
                        assert (routeId >= 0);
                        clientConnection.recordDestinationRouteId(routeId);
                        publishGet(requestPipe, hostBack, hostPos, hostLen, connectionId, clientConnection, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_PATH_3, ClientHTTPRequestSchema.MSG_FASTHTTPGET_200_FIELD_HEADERS_7);
                    }
                }
                break;
            case ClientHTTPRequestSchema.MSG_HTTPGET_100:
                {
                    final byte[] hostBack = Pipe.blob(requestPipe);
                    final int hostPos = PipeReader.readBytesPosition(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_HOST_2);
                    final int hostLen = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_HOST_2);
                    final int hostMask = Pipe.blobMask(requestPipe);
                    int routeId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_DESTINATION_11);
                    int port = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_PORT_1);
                    int userId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_SESSION_10);
                    long connectionId = ccm.lookup(ccm.lookupHostId(hostBack, hostPos, hostLen, hostMask), port, userId);
                    ClientConnection clientConnection;
                    if (-1 != connectionId && null != (clientConnection = (ClientConnection) ccm.connectionForSessionId(connectionId))) {
                        assert (clientConnection.singleUsage(stageId)) : "Only a single Stage may update the clientConnection.";
                        assert (routeId >= 0);
                        clientConnection.recordDestinationRouteId(routeId);
                        publishGet(requestPipe, hostBack, hostPos, hostLen, connectionId, clientConnection, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_PATH_3, ClientHTTPRequestSchema.MSG_HTTPGET_100_FIELD_HEADERS_7);
                    }
                }
                break;
            case ClientHTTPRequestSchema.MSG_HTTPPOST_101:
                {
                    final byte[] hostBack = Pipe.blob(requestPipe);
                    final int hostPos = PipeReader.readBytesPosition(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_HOST_2);
                    final int hostLen = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_HOST_2);
                    final int hostMask = Pipe.blobMask(requestPipe);
                    int routeId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_DESTINATION_11);
                    int userId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_SESSION_10);
                    int port = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PORT_1);
                    long connectionId = ccm.lookup(ccm.lookupHostId(hostBack, hostPos, hostLen, hostMask), port, userId);
                    // openConnection(activeHost, port, userId, outIdx);
                    ClientConnection clientConnection;
                    if ((-1 != connectionId) && (null != (clientConnection = (ClientConnection) ccm.connectionForSessionId(connectionId)))) {
                        assert (routeId >= 0);
                        clientConnection.recordDestinationRouteId(routeId);
                        int outIdx = clientConnection.requestPipeLineIdx();
                        // count of messages can only be done here.
                        clientConnection.incRequestsSent();
                        Pipe<NetPayloadSchema> outputPipe = output[outIdx];
                        PipeWriter.presumeWriteFragment(outputPipe, NetPayloadSchema.MSG_PLAIN_210);
                        PipeWriter.writeLong(outputPipe, NetPayloadSchema.MSG_PLAIN_210_FIELD_CONNECTIONID_201, connectionId);
                        DataOutputBlobWriter<NetPayloadSchema> activeWriter = PipeWriter.outputStream(outputPipe);
                        DataOutputBlobWriter.openField(activeWriter);
                        DataOutputBlobWriter.encodeAsUTF8(activeWriter, "POST");
                        int len = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PATH_3);
                        int first = PipeReader.readBytesPosition(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PATH_3);
                        boolean prePendSlash = (0 == len) || ('/' != PipeReader.readBytesBackingArray(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PATH_3)[first & Pipe.blobMask(requestPipe)]);
                        if (prePendSlash) {
                            // NOTE: these can be pre-coverted to bytes so we need not convert on each write. may want to improve.
                            DataOutputBlobWriter.encodeAsUTF8(activeWriter, " /");
                        } else {
                            DataOutputBlobWriter.encodeAsUTF8(activeWriter, " ");
                        }
                        // Reading from UTF8 field and writing to UTF8 encoded field so we are doing a direct copy here.
                        PipeReader.readBytes(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PATH_3, activeWriter);
                        HeaderUtil.writeHeaderBeginning(hostBack, hostPos, hostLen, Pipe.blobMask(requestPipe), activeWriter);
                        HeaderUtil.writeHeaderMiddle(activeWriter, implementationVersion);
                        PipeReader.readBytes(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_HEADERS_7, activeWriter);
                        long postLength = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PAYLOAD_5);
                        HeaderUtil.writeHeaderEnding(activeWriter, true, postLength);
                        // TODO: How is chunking supported, that code is not here yet but length must be -1 I think.
                        PipeReader.readBytes(requestPipe, ClientHTTPRequestSchema.MSG_HTTPPOST_101_FIELD_PAYLOAD_5, activeWriter);
                        DataOutputBlobWriter.closeHighLevelField(activeWriter, NetPayloadSchema.MSG_PLAIN_210_FIELD_PAYLOAD_204);
                        PipeWriter.publishWrites(outputPipe);
                    }
                }
                break;
            case ClientHTTPRequestSchema.MSG_CLOSE_104:
                final byte[] hostBack = Pipe.blob(requestPipe);
                final int hostPos = PipeReader.readBytesPosition(requestPipe, ClientHTTPRequestSchema.MSG_CLOSE_104_FIELD_HOST_2);
                final int hostLen = PipeReader.readBytesLength(requestPipe, ClientHTTPRequestSchema.MSG_CLOSE_104_FIELD_HOST_2);
                final int hostMask = Pipe.blobMask(requestPipe);
                final int port = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_CLOSE_104_FIELD_PORT_1);
                final int userId = PipeReader.readInt(requestPipe, ClientHTTPRequestSchema.MSG_CLOSE_104_FIELD_SESSION_10);
                long connectionId = ccm.lookup(ccm.lookupHostId(hostBack, hostPos, hostLen, hostMask), port, userId);
                // only close if we find a live connection
                if ((-1 != connectionId)) {
                    ClientConnection connectionToKill = (ClientConnection) ccm.connectionForSessionId(connectionId);
                    if (null != connectionToKill) {
                        Pipe<NetPayloadSchema> outputPipe = output[connectionToKill.requestPipeLineIdx()];
                        // do not close that will be done by last stage
                        // must be done first before we send the message
                        connectionToKill.beginDisconnect();
                        PipeWriter.presumeWriteFragment(outputPipe, NetPayloadSchema.MSG_DISCONNECT_203);
                        PipeWriter.writeLong(outputPipe, NetPayloadSchema.MSG_DISCONNECT_203_FIELD_CONNECTIONID_201, connectionId);
                        PipeWriter.publishWrites(outputPipe);
                    }
                }
                break;
            default:
                logger.info("not yet supporting message {}", msgIdx);
        }
        PipeReader.releaseReadLock(requestPipe);
        // only do now after we know its not blocked and was completed
        decReleaseCount(activePipe);
    }
}
Also used : ClientHTTPRequestSchema(com.ociweb.pronghorn.network.schema.ClientHTTPRequestSchema) DataOutputBlobWriter(com.ociweb.pronghorn.pipe.DataOutputBlobWriter) NetPayloadSchema(com.ociweb.pronghorn.network.schema.NetPayloadSchema) ClientConnection(com.ociweb.pronghorn.network.ClientConnection) Pipe(com.ociweb.pronghorn.pipe.Pipe)

Aggregations

ClientConnection (com.ociweb.pronghorn.network.ClientConnection)2 ClientHTTPRequestSchema (com.ociweb.pronghorn.network.schema.ClientHTTPRequestSchema)1 NetPayloadSchema (com.ociweb.pronghorn.network.schema.NetPayloadSchema)1 DataOutputBlobWriter (com.ociweb.pronghorn.pipe.DataOutputBlobWriter)1 Pipe (com.ociweb.pronghorn.pipe.Pipe)1 PipeUTF8MutableCharSquence (com.ociweb.pronghorn.pipe.PipeUTF8MutableCharSquence)1 HandshakeStatus (javax.net.ssl.SSLEngineResult.HandshakeStatus)1