Search in sources :

Example 96 with HttpContext

use of org.apache.http.protocol.HttpContext in project nifi by apache.

the class PostHTTP method onTrigger.

@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) {
    FlowFile firstFlowFile = session.get();
    if (firstFlowFile == null) {
        return;
    }
    final ComponentLog logger = getLogger();
    final String url = context.getProperty(URL).evaluateAttributeExpressions(firstFlowFile).getValue();
    try {
        new java.net.URL(url);
    } catch (final MalformedURLException e) {
        logger.error("After substituting attribute values for {}, URL is {}; this is not a valid URL, so routing to failure", new Object[] { firstFlowFile, url });
        firstFlowFile = session.penalize(firstFlowFile);
        session.transfer(firstFlowFile, REL_FAILURE);
        return;
    }
    final List<FlowFile> toSend = new ArrayList<>();
    toSend.add(firstFlowFile);
    final boolean sendAsFlowFile = context.getProperty(SEND_AS_FLOWFILE).asBoolean();
    final int compressionLevel = context.getProperty(COMPRESSION_LEVEL).asInteger();
    final String userAgent = context.getProperty(USER_AGENT).getValue();
    final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
    requestConfigBuilder.setConnectionRequestTimeout(context.getProperty(DATA_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue());
    requestConfigBuilder.setConnectTimeout(context.getProperty(CONNECTION_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue());
    requestConfigBuilder.setRedirectsEnabled(false);
    requestConfigBuilder.setSocketTimeout(context.getProperty(DATA_TIMEOUT).asTimePeriod(TimeUnit.MILLISECONDS).intValue());
    final RequestConfig requestConfig = requestConfigBuilder.build();
    final StreamThrottler throttler = throttlerRef.get();
    final Double maxBatchBytes = context.getProperty(MAX_BATCH_SIZE).asDataSize(DataUnit.B);
    final AtomicLong bytesToSend = new AtomicLong(firstFlowFile.getSize());
    DestinationAccepts destinationAccepts = null;
    CloseableHttpClient client = null;
    final String transactionId = UUID.randomUUID().toString();
    final AtomicReference<String> dnHolder = new AtomicReference<>("none");
    final Config config = getConfig(url, context);
    final HttpClientConnectionManager conMan = config.getConnectionManager();
    final HttpClientBuilder clientBuilder = HttpClientBuilder.create();
    clientBuilder.setConnectionManager(conMan);
    clientBuilder.setUserAgent(userAgent);
    clientBuilder.addInterceptorFirst(new HttpResponseInterceptor() {

        @Override
        public void process(final HttpResponse response, final HttpContext httpContext) throws HttpException, IOException {
            final HttpCoreContext coreContext = HttpCoreContext.adapt(httpContext);
            final ManagedHttpClientConnection conn = coreContext.getConnection(ManagedHttpClientConnection.class);
            if (!conn.isOpen()) {
                return;
            }
            final SSLSession sslSession = conn.getSSLSession();
            if (sslSession != null) {
                final Certificate[] certChain = sslSession.getPeerCertificates();
                if (certChain == null || certChain.length == 0) {
                    throw new SSLPeerUnverifiedException("No certificates found");
                }
                try {
                    final X509Certificate cert = CertificateUtils.convertAbstractX509Certificate(certChain[0]);
                    dnHolder.set(cert.getSubjectDN().getName().trim());
                } catch (CertificateException e) {
                    final String msg = "Could not extract subject DN from SSL session peer certificate";
                    logger.warn(msg);
                    throw new SSLPeerUnverifiedException(msg);
                }
            }
        }
    });
    clientBuilder.disableAutomaticRetries();
    clientBuilder.disableContentCompression();
    final String username = context.getProperty(USERNAME).getValue();
    final String password = context.getProperty(PASSWORD).getValue();
    // set the credentials if appropriate
    if (username != null) {
        final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
        if (password == null) {
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username));
        } else {
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));
        }
        clientBuilder.setDefaultCredentialsProvider(credentialsProvider);
    }
    // Set the proxy if specified
    if (context.getProperty(PROXY_HOST).isSet() && context.getProperty(PROXY_PORT).isSet()) {
        final String host = context.getProperty(PROXY_HOST).getValue();
        final int port = context.getProperty(PROXY_PORT).asInteger();
        clientBuilder.setProxy(new HttpHost(host, port));
    }
    client = clientBuilder.build();
    // determine whether or not destination accepts flowfile/gzip
    destinationAccepts = config.getDestinationAccepts();
    if (destinationAccepts == null) {
        try {
            destinationAccepts = getDestinationAcceptance(sendAsFlowFile, client, url, getLogger(), transactionId);
            config.setDestinationAccepts(destinationAccepts);
        } catch (final IOException e) {
            firstFlowFile = session.penalize(firstFlowFile);
            session.transfer(firstFlowFile, REL_FAILURE);
            logger.error("Unable to communicate with destination {} to determine whether or not it can accept " + "flowfiles/gzip; routing {} to failure due to {}", new Object[] { url, firstFlowFile, e });
            context.yield();
            return;
        }
    }
    // then we can get more flowfiles from the session up to MAX_BATCH_SIZE for the same URL
    if (sendAsFlowFile && (destinationAccepts.isFlowFileV3Accepted() || destinationAccepts.isFlowFileV2Accepted())) {
        toSend.addAll(session.get(new FlowFileFilter() {

            @Override
            public FlowFileFilterResult filter(FlowFile flowFile) {
                // if over MAX_BATCH_SIZE, then stop adding files
                if (bytesToSend.get() + flowFile.getSize() > maxBatchBytes) {
                    return FlowFileFilterResult.REJECT_AND_TERMINATE;
                }
                // check URL to see if this flowfile can be included in the batch
                final String urlToCheck = context.getProperty(URL).evaluateAttributeExpressions(flowFile).getValue();
                if (url.equals(urlToCheck)) {
                    bytesToSend.addAndGet(flowFile.getSize());
                    return FlowFileFilterResult.ACCEPT_AND_CONTINUE;
                } else {
                    return FlowFileFilterResult.REJECT_AND_CONTINUE;
                }
            }
        }));
    }
    final HttpPost post = new HttpPost(url);
    final DestinationAccepts accepts = destinationAccepts;
    final boolean isDestinationLegacyNiFi = accepts.getProtocolVersion() == null;
    final EntityTemplate entity = new EntityTemplate(new ContentProducer() {

        @Override
        public void writeTo(final OutputStream rawOut) throws IOException {
            final OutputStream throttled = throttler == null ? rawOut : throttler.newThrottledOutputStream(rawOut);
            OutputStream wrappedOut = new BufferedOutputStream(throttled);
            if (compressionLevel > 0 && accepts.isGzipAccepted()) {
                wrappedOut = new GZIPOutputStream(wrappedOut, compressionLevel);
            }
            try (final OutputStream out = wrappedOut) {
                for (final FlowFile flowFile : toSend) {
                    session.read(flowFile, new InputStreamCallback() {

                        @Override
                        public void process(final InputStream rawIn) throws IOException {
                            try (final InputStream in = new BufferedInputStream(rawIn)) {
                                FlowFilePackager packager = null;
                                if (!sendAsFlowFile) {
                                    packager = null;
                                } else if (accepts.isFlowFileV3Accepted()) {
                                    packager = new FlowFilePackagerV3();
                                } else if (accepts.isFlowFileV2Accepted()) {
                                    packager = new FlowFilePackagerV2();
                                } else if (accepts.isFlowFileV1Accepted()) {
                                    packager = new FlowFilePackagerV1();
                                }
                                // formats is acceptable if sending as FlowFile.
                                if (packager == null) {
                                    StreamUtils.copy(in, out);
                                } else {
                                    final Map<String, String> flowFileAttributes;
                                    if (isDestinationLegacyNiFi) {
                                        // Old versions of NiFi expect nf.file.name and nf.file.path to indicate filename & path;
                                        // in order to maintain backward compatibility, we copy the filename & path to those attribute keys.
                                        flowFileAttributes = new HashMap<>(flowFile.getAttributes());
                                        flowFileAttributes.put("nf.file.name", flowFile.getAttribute(CoreAttributes.FILENAME.key()));
                                        flowFileAttributes.put("nf.file.path", flowFile.getAttribute(CoreAttributes.PATH.key()));
                                    } else {
                                        flowFileAttributes = flowFile.getAttributes();
                                    }
                                    packager.packageFlowFile(in, out, flowFileAttributes, flowFile.getSize());
                                }
                            }
                        }
                    });
                }
                out.flush();
            }
        }
    }) {

        @Override
        public long getContentLength() {
            if (compressionLevel == 0 && !sendAsFlowFile && !context.getProperty(CHUNKED_ENCODING).asBoolean()) {
                return toSend.get(0).getSize();
            } else {
                return -1;
            }
        }
    };
    if (context.getProperty(CHUNKED_ENCODING).isSet()) {
        entity.setChunked(context.getProperty(CHUNKED_ENCODING).asBoolean());
    }
    post.setEntity(entity);
    post.setConfig(requestConfig);
    final String contentType;
    if (sendAsFlowFile) {
        if (accepts.isFlowFileV3Accepted()) {
            contentType = APPLICATION_FLOW_FILE_V3;
        } else if (accepts.isFlowFileV2Accepted()) {
            contentType = APPLICATION_FLOW_FILE_V2;
        } else if (accepts.isFlowFileV1Accepted()) {
            contentType = APPLICATION_FLOW_FILE_V1;
        } else {
            logger.error("Cannot send data to {} because the destination does not accept FlowFiles and this processor is " + "configured to deliver FlowFiles; rolling back session", new Object[] { url });
            session.rollback();
            context.yield();
            IOUtils.closeQuietly(client);
            return;
        }
    } else {
        final String contentTypeValue = context.getProperty(CONTENT_TYPE).evaluateAttributeExpressions(toSend.get(0)).getValue();
        contentType = StringUtils.isBlank(contentTypeValue) ? DEFAULT_CONTENT_TYPE : contentTypeValue;
    }
    final String attributeHeaderRegex = context.getProperty(ATTRIBUTES_AS_HEADERS_REGEX).getValue();
    if (attributeHeaderRegex != null && !sendAsFlowFile && toSend.size() == 1) {
        final Pattern pattern = Pattern.compile(attributeHeaderRegex);
        final Map<String, String> attributes = toSend.get(0).getAttributes();
        for (final Map.Entry<String, String> entry : attributes.entrySet()) {
            final String key = entry.getKey();
            if (pattern.matcher(key).matches()) {
                post.setHeader(entry.getKey(), entry.getValue());
            }
        }
    }
    post.setHeader(CONTENT_TYPE_HEADER, contentType);
    post.setHeader(FLOWFILE_CONFIRMATION_HEADER, "true");
    post.setHeader(PROTOCOL_VERSION_HEADER, PROTOCOL_VERSION);
    post.setHeader(TRANSACTION_ID_HEADER, transactionId);
    if (compressionLevel > 0 && accepts.isGzipAccepted()) {
        if (sendAsFlowFile) {
            post.setHeader(GZIPPED_HEADER, "true");
        } else {
            post.setHeader(CONTENT_ENCODING_HEADER, CONTENT_ENCODING_GZIP_VALUE);
        }
    }
    // Do the actual POST
    final String flowFileDescription = toSend.size() <= 10 ? toSend.toString() : toSend.size() + " FlowFiles";
    final String uploadDataRate;
    final long uploadMillis;
    CloseableHttpResponse response = null;
    try {
        final StopWatch stopWatch = new StopWatch(true);
        response = client.execute(post);
        // consume input stream entirely, ignoring its contents. If we
        // don't do this, the Connection will not be returned to the pool
        EntityUtils.consume(response.getEntity());
        stopWatch.stop();
        uploadDataRate = stopWatch.calculateDataRate(bytesToSend.get());
        uploadMillis = stopWatch.getDuration(TimeUnit.MILLISECONDS);
    } catch (final IOException e) {
        logger.error("Failed to Post {} due to {}; transferring to failure", new Object[] { flowFileDescription, e });
        context.yield();
        for (FlowFile flowFile : toSend) {
            flowFile = session.penalize(flowFile);
            session.transfer(flowFile, REL_FAILURE);
        }
        return;
    } finally {
        if (response != null) {
            try {
                response.close();
            } catch (final IOException e) {
                getLogger().warn("Failed to close HTTP Response due to {}", new Object[] { e });
            }
        }
    }
    // If we get a 'SEE OTHER' status code and an HTTP header that indicates that the intent
    // of the Location URI is a flowfile hold, we will store this holdUri. This prevents us
    // from posting to some other webservice and then attempting to delete some resource to which
    // we are redirected
    final int responseCode = response.getStatusLine().getStatusCode();
    final String responseReason = response.getStatusLine().getReasonPhrase();
    String holdUri = null;
    if (responseCode == HttpServletResponse.SC_SEE_OTHER) {
        final Header locationUriHeader = response.getFirstHeader(LOCATION_URI_INTENT_NAME);
        if (locationUriHeader != null) {
            if (LOCATION_URI_INTENT_VALUE.equals(locationUriHeader.getValue())) {
                final Header holdUriHeader = response.getFirstHeader(LOCATION_HEADER_NAME);
                if (holdUriHeader != null) {
                    holdUri = holdUriHeader.getValue();
                }
            }
        }
        if (holdUri == null) {
            for (FlowFile flowFile : toSend) {
                flowFile = session.penalize(flowFile);
                logger.error("Failed to Post {} to {}: sent content and received status code {}:{} but no Hold URI", new Object[] { flowFile, url, responseCode, responseReason });
                session.transfer(flowFile, REL_FAILURE);
            }
            return;
        }
    }
    if (holdUri == null) {
        if (responseCode == HttpServletResponse.SC_SERVICE_UNAVAILABLE) {
            for (FlowFile flowFile : toSend) {
                flowFile = session.penalize(flowFile);
                logger.error("Failed to Post {} to {}: response code was {}:{}; will yield processing, " + "since the destination is temporarily unavailable", new Object[] { flowFile, url, responseCode, responseReason });
                session.transfer(flowFile, REL_FAILURE);
            }
            context.yield();
            return;
        }
        if (responseCode >= 300) {
            for (FlowFile flowFile : toSend) {
                flowFile = session.penalize(flowFile);
                logger.error("Failed to Post {} to {}: response code was {}:{}", new Object[] { flowFile, url, responseCode, responseReason });
                session.transfer(flowFile, REL_FAILURE);
            }
            return;
        }
        logger.info("Successfully Posted {} to {} in {} at a rate of {}", new Object[] { flowFileDescription, url, FormatUtils.formatMinutesSeconds(uploadMillis, TimeUnit.MILLISECONDS), uploadDataRate });
        for (final FlowFile flowFile : toSend) {
            session.getProvenanceReporter().send(flowFile, url, "Remote DN=" + dnHolder.get(), uploadMillis, true);
            session.transfer(flowFile, REL_SUCCESS);
        }
        return;
    }
    // 
    // the response indicated a Hold URI; delete the Hold.
    // 
    // determine the full URI of the Flow File's Hold; Unfortunately, the responses that are returned have
    // changed over the past, so we have to take into account a few different possibilities.
    String fullHoldUri = holdUri;
    if (holdUri.startsWith("/contentListener")) {
        // If the Hold URI that we get starts with /contentListener, it may not really be /contentListener,
        // as this really indicates that it should be whatever we posted to -- if posting directly to the
        // ListenHTTP component, it will be /contentListener, but if posting to a proxy/load balancer, we may
        // be posting to some other URL.
        fullHoldUri = url + holdUri.substring(16);
    } else if (holdUri.startsWith("/")) {
        // URL indicates the full path but not hostname or port; use the same hostname & port that we posted
        // to but use the full path indicated by the response.
        int firstSlash = url.indexOf("/", 8);
        if (firstSlash < 0) {
            firstSlash = url.length();
        }
        final String beforeSlash = url.substring(0, firstSlash);
        fullHoldUri = beforeSlash + holdUri;
    } else if (!holdUri.startsWith("http")) {
        // Absolute URL
        fullHoldUri = url + (url.endsWith("/") ? "" : "/") + holdUri;
    }
    final HttpDelete delete = new HttpDelete(fullHoldUri);
    delete.setHeader(TRANSACTION_ID_HEADER, transactionId);
    while (true) {
        try {
            final HttpResponse holdResponse = client.execute(delete);
            EntityUtils.consume(holdResponse.getEntity());
            final int holdStatusCode = holdResponse.getStatusLine().getStatusCode();
            final String holdReason = holdResponse.getStatusLine().getReasonPhrase();
            if (holdStatusCode >= 300) {
                logger.error("Failed to delete Hold that destination placed on {}: got response code {}:{}; routing to failure", new Object[] { flowFileDescription, holdStatusCode, holdReason });
                for (FlowFile flowFile : toSend) {
                    flowFile = session.penalize(flowFile);
                    session.transfer(flowFile, REL_FAILURE);
                }
                return;
            }
            logger.info("Successfully Posted {} to {} in {} milliseconds at a rate of {}", new Object[] { flowFileDescription, url, uploadMillis, uploadDataRate });
            for (final FlowFile flowFile : toSend) {
                session.getProvenanceReporter().send(flowFile, url);
                session.transfer(flowFile, REL_SUCCESS);
            }
            return;
        } catch (final IOException e) {
            logger.warn("Failed to delete Hold that destination placed on {} due to {}", new Object[] { flowFileDescription, e });
        }
        if (!isScheduled()) {
            context.yield();
            logger.warn("Failed to delete Hold that destination placed on {}; Processor has been stopped so routing FlowFile(s) to failure", new Object[] { flowFileDescription });
            for (FlowFile flowFile : toSend) {
                flowFile = session.penalize(flowFile);
                session.transfer(flowFile, REL_FAILURE);
            }
            return;
        }
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) MalformedURLException(java.net.MalformedURLException) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) GZIPOutputStream(org.apache.nifi.stream.io.GZIPOutputStream) BufferedOutputStream(java.io.BufferedOutputStream) OutputStream(java.io.OutputStream) ArrayList(java.util.ArrayList) EntityTemplate(org.apache.http.entity.EntityTemplate) CertificateException(java.security.cert.CertificateException) FlowFilePackager(org.apache.nifi.util.FlowFilePackager) GZIPOutputStream(org.apache.nifi.stream.io.GZIPOutputStream) BufferedInputStream(java.io.BufferedInputStream) HttpHost(org.apache.http.HttpHost) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) HttpClientConnectionManager(org.apache.http.conn.HttpClientConnectionManager) PoolingHttpClientConnectionManager(org.apache.http.impl.conn.PoolingHttpClientConnectionManager) FlowFile(org.apache.nifi.flowfile.FlowFile) RequestConfig(org.apache.http.client.config.RequestConfig) FlowFileFilter(org.apache.nifi.processor.FlowFileFilter) ComponentLog(org.apache.nifi.logging.ComponentLog) X509Certificate(java.security.cert.X509Certificate) UsernamePasswordCredentials(org.apache.http.auth.UsernamePasswordCredentials) Header(org.apache.http.Header) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) LeakyBucketStreamThrottler(org.apache.nifi.stream.io.LeakyBucketStreamThrottler) StreamThrottler(org.apache.nifi.stream.io.StreamThrottler) ContentProducer(org.apache.http.entity.ContentProducer) HttpDelete(org.apache.http.client.methods.HttpDelete) RequestConfig(org.apache.http.client.config.RequestConfig) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) HttpException(org.apache.http.HttpException) BufferedOutputStream(java.io.BufferedOutputStream) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) Pattern(java.util.regex.Pattern) BufferedInputStream(java.io.BufferedInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) HttpContext(org.apache.http.protocol.HttpContext) SSLSession(javax.net.ssl.SSLSession) HttpResponse(org.apache.http.HttpResponse) CloseableHttpResponse(org.apache.http.client.methods.CloseableHttpResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) IOException(java.io.IOException) CredentialsProvider(org.apache.http.client.CredentialsProvider) BasicCredentialsProvider(org.apache.http.impl.client.BasicCredentialsProvider) StopWatch(org.apache.nifi.util.StopWatch) ManagedHttpClientConnection(org.apache.http.conn.ManagedHttpClientConnection) AtomicLong(java.util.concurrent.atomic.AtomicLong) HttpCoreContext(org.apache.http.protocol.HttpCoreContext) HttpResponseInterceptor(org.apache.http.HttpResponseInterceptor) InputStreamCallback(org.apache.nifi.processor.io.InputStreamCallback) FlowFilePackagerV3(org.apache.nifi.util.FlowFilePackagerV3) FlowFilePackagerV2(org.apache.nifi.util.FlowFilePackagerV2) FlowFilePackagerV1(org.apache.nifi.util.FlowFilePackagerV1)

Example 97 with HttpContext

use of org.apache.http.protocol.HttpContext in project nifi by apache.

the class SiteToSiteRestApiClient method openConnectionForSend.

public void openConnectionForSend(final String transactionUrl, final Peer peer) throws IOException {
    final CommunicationsSession commSession = peer.getCommunicationsSession();
    final String flowFilesPath = transactionUrl + "/flow-files";
    final HttpPost post = createPost(flowFilesPath);
    // Set uri so that it'll be used as transit uri.
    ((HttpCommunicationsSession) peer.getCommunicationsSession()).setDataTransferUrl(post.getURI().toString());
    post.setHeader("Content-Type", "application/octet-stream");
    post.setHeader("Accept", "text/plain");
    post.setHeader(HttpHeaders.PROTOCOL_VERSION, String.valueOf(transportProtocolVersionNegotiator.getVersion()));
    setHandshakeProperties(post);
    final CountDownLatch initConnectionLatch = new CountDownLatch(1);
    final URI requestUri = post.getURI();
    final PipedOutputStream outputStream = new PipedOutputStream();
    final PipedInputStream inputStream = new PipedInputStream(outputStream, DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);
    final ReadableByteChannel dataPacketChannel = Channels.newChannel(inputStream);
    final HttpAsyncRequestProducer asyncRequestProducer = new HttpAsyncRequestProducer() {

        private final ByteBuffer buffer = ByteBuffer.allocate(DATA_PACKET_CHANNEL_READ_BUFFER_SIZE);

        private int totalRead = 0;

        private int totalProduced = 0;

        private boolean requestHasBeenReset = false;

        @Override
        public HttpHost getTarget() {
            return URIUtils.extractHost(requestUri);
        }

        @Override
        public HttpRequest generateRequest() throws IOException, HttpException {
            // Pass the output stream so that Site-to-Site client thread can send
            // data packet through this connection.
            logger.debug("sending data to {} has started...", flowFilesPath);
            ((HttpOutput) commSession.getOutput()).setOutputStream(outputStream);
            initConnectionLatch.countDown();
            final BasicHttpEntity entity = new BasicHttpEntity();
            entity.setChunked(true);
            entity.setContentType("application/octet-stream");
            post.setEntity(entity);
            return post;
        }

        private final AtomicBoolean bufferHasRemainingData = new AtomicBoolean(false);

        /**
         * If the proxy server requires authentication, the same POST request has to be sent again.
         * The first request will result 407, then the next one will be sent with auth headers and actual data.
         * This method produces a content only when it's need to be sent, to avoid producing the flow-file contents twice.
         * Whether we need to wait auth is determined heuristically by the previous POST request which creates transaction.
         * See {@link SiteToSiteRestApiClient#initiateTransactionForSend(HttpPost)} for further detail.
         */
        @Override
        public void produceContent(final ContentEncoder encoder, final IOControl ioControl) throws IOException {
            if (shouldCheckProxyAuth() && proxyAuthRequiresResend.get() && !requestHasBeenReset) {
                logger.debug("Need authentication with proxy server. Postpone producing content.");
                encoder.complete();
                return;
            }
            if (bufferHasRemainingData.get()) {
                // If there's remaining buffer last time, send it first.
                writeBuffer(encoder);
                if (bufferHasRemainingData.get()) {
                    return;
                }
            }
            int read;
            // or corresponding outputStream is closed.
            if ((read = dataPacketChannel.read(buffer)) > -1) {
                logger.trace("Read {} bytes from dataPacketChannel. {}", read, flowFilesPath);
                totalRead += read;
                buffer.flip();
                writeBuffer(encoder);
            } else {
                final long totalWritten = commSession.getOutput().getBytesWritten();
                logger.debug("sending data to {} has reached to its end. produced {} bytes by reading {} bytes from channel. {} bytes written in this transaction.", flowFilesPath, totalProduced, totalRead, totalWritten);
                if (totalRead != totalWritten || totalProduced != totalWritten) {
                    final String msg = "Sending data to %s has reached to its end, but produced : read : wrote byte sizes (%d : %d : %d) were not equal. Something went wrong.";
                    throw new RuntimeException(String.format(msg, flowFilesPath, totalProduced, totalRead, totalWritten));
                }
                transferDataLatch.countDown();
                encoder.complete();
                dataPacketChannel.close();
            }
        }

        private void writeBuffer(ContentEncoder encoder) throws IOException {
            while (buffer.hasRemaining()) {
                final int written = encoder.write(buffer);
                logger.trace("written {} bytes to encoder.", written);
                if (written == 0) {
                    logger.trace("Buffer still has remaining. {}", buffer);
                    bufferHasRemainingData.set(true);
                    return;
                }
                totalProduced += written;
            }
            bufferHasRemainingData.set(false);
            buffer.clear();
        }

        @Override
        public void requestCompleted(final HttpContext context) {
            logger.debug("Sending data to {} completed.", flowFilesPath);
            debugProxyAuthState(context);
        }

        @Override
        public void failed(final Exception ex) {
            final String msg = String.format("Failed to send data to %s due to %s", flowFilesPath, ex.toString());
            logger.error(msg, ex);
            eventReporter.reportEvent(Severity.WARNING, EVENT_CATEGORY, msg);
        }

        @Override
        public boolean isRepeatable() {
            // In order to pass authentication, request has to be repeatable.
            return true;
        }

        @Override
        public void resetRequest() throws IOException {
            logger.debug("Sending data request to {} has been reset...", flowFilesPath);
            requestHasBeenReset = true;
        }

        @Override
        public void close() throws IOException {
            logger.debug("Closing sending data request to {}", flowFilesPath);
            closeSilently(outputStream);
            closeSilently(dataPacketChannel);
            stopExtendingTtl();
        }
    };
    postResult = getHttpAsyncClient().execute(asyncRequestProducer, new BasicAsyncResponseConsumer(), null);
    try {
        // Need to wait the post request actually started so that we can write to its output stream.
        if (!initConnectionLatch.await(connectTimeoutMillis, TimeUnit.MILLISECONDS)) {
            throw new IOException("Awaiting initConnectionLatch has been timeout.");
        }
        // Started.
        transferDataLatch = new CountDownLatch(1);
        startExtendingTtl(transactionUrl, dataPacketChannel, null);
    } catch (final InterruptedException e) {
        throw new IOException("Awaiting initConnectionLatch has been interrupted.", e);
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) ReadableByteChannel(java.nio.channels.ReadableByteChannel) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) ContentEncoder(org.apache.http.nio.ContentEncoder) IOControl(org.apache.http.nio.IOControl) HttpContext(org.apache.http.protocol.HttpContext) PipedOutputStream(java.io.PipedOutputStream) BasicHttpEntity(org.apache.http.entity.BasicHttpEntity) CommunicationsSession(org.apache.nifi.remote.protocol.CommunicationsSession) HttpCommunicationsSession(org.apache.nifi.remote.io.http.HttpCommunicationsSession) PipedInputStream(java.io.PipedInputStream) HttpOutput(org.apache.nifi.remote.io.http.HttpOutput) IOException(java.io.IOException) CountDownLatch(java.util.concurrent.CountDownLatch) URI(java.net.URI) ByteBuffer(java.nio.ByteBuffer) HandshakeException(org.apache.nifi.remote.exception.HandshakeException) HttpException(org.apache.http.HttpException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) URISyntaxException(java.net.URISyntaxException) TimeoutException(java.util.concurrent.TimeoutException) JsonParseException(com.fasterxml.jackson.core.JsonParseException) ProtocolException(org.apache.nifi.remote.exception.ProtocolException) JsonMappingException(com.fasterxml.jackson.databind.JsonMappingException) PortNotRunningException(org.apache.nifi.remote.exception.PortNotRunningException) MalformedURLException(java.net.MalformedURLException) UnknownPortException(org.apache.nifi.remote.exception.UnknownPortException) CertificateException(java.security.cert.CertificateException) SSLPeerUnverifiedException(javax.net.ssl.SSLPeerUnverifiedException) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HttpAsyncRequestProducer(org.apache.http.nio.protocol.HttpAsyncRequestProducer) BasicAsyncResponseConsumer(org.apache.http.nio.protocol.BasicAsyncResponseConsumer)

Example 98 with HttpContext

use of org.apache.http.protocol.HttpContext in project Lucee by lucee.

the class HttpGetWithBody method _doEndTag.

private void _doEndTag() throws PageException, IOException {
    long start = System.nanoTime();
    HttpClientBuilder builder = HTTPEngine4Impl.getHttpClientBuilder();
    ssl(builder);
    // redirect
    if (redirect)
        builder.setRedirectStrategy(new DefaultRedirectStrategy());
    else
        builder.disableRedirectHandling();
    // cookies
    BasicCookieStore cookieStore = new BasicCookieStore();
    builder.setDefaultCookieStore(cookieStore);
    ConfigWeb cw = pageContext.getConfig();
    HttpRequestBase req = null;
    HttpContext httpContext = null;
    CacheHandler cacheHandler = null;
    String cacheId = null;
    // HttpRequestBase req = init(pageContext.getConfig(),this,client,params,url,port);
    {
        if (StringUtil.isEmpty(charset, true))
            charset = ((PageContextImpl) pageContext).getWebCharset().name();
        else
            charset = charset.trim();
        // check if has fileUploads
        boolean doUploadFile = false;
        for (int i = 0; i < this.params.size(); i++) {
            if ((this.params.get(i)).getType() == HttpParamBean.TYPE_FILE) {
                doUploadFile = true;
                break;
            }
        }
        // parse url (also query string)
        int len = this.params.size();
        StringBuilder sbQS = new StringBuilder();
        for (int i = 0; i < len; i++) {
            HttpParamBean param = this.params.get(i);
            int type = param.getType();
            // URL
            if (type == HttpParamBean.TYPE_URL) {
                if (sbQS.length() > 0)
                    sbQS.append('&');
                sbQS.append(param.getEncoded() ? urlenc(param.getName(), charset) : param.getName());
                sbQS.append('=');
                sbQS.append(param.getEncoded() ? urlenc(param.getValueAsString(), charset) : param.getValueAsString());
            }
        }
        String host = null;
        HttpHost httpHost;
        try {
            URL _url = HTTPUtil.toURL(url, port, encoded);
            httpHost = new HttpHost(_url.getHost(), _url.getPort());
            host = _url.getHost();
            url = _url.toExternalForm();
            if (sbQS.length() > 0) {
                // no existing QS
                if (StringUtil.isEmpty(_url.getQuery())) {
                    url += "?" + sbQS;
                } else {
                    url += "&" + sbQS;
                }
            }
        } catch (MalformedURLException mue) {
            throw Caster.toPageException(mue);
        }
        // cache
        if (cachedWithin != null) {
            cacheId = createCacheId();
            cacheHandler = pageContext.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_HTTP, null).getInstanceMatchingObject(cachedWithin, null);
            if (cacheHandler instanceof CacheHandlerPro) {
                CacheItem cacheItem = ((CacheHandlerPro) cacheHandler).get(pageContext, cacheId, cachedWithin);
                if (cacheItem instanceof HTTPCacheItem) {
                    pageContext.setVariable(result, ((HTTPCacheItem) cacheItem).getData());
                    return;
                }
            } else if (cacheHandler != null) {
                // TODO this else block can be removed when all cache handlers implement CacheHandlerPro
                CacheItem cacheItem = cacheHandler.get(pageContext, cacheId);
                if (cacheItem instanceof HTTPCacheItem) {
                    pageContext.setVariable(result, ((HTTPCacheItem) cacheItem).getData());
                    return;
                }
            }
        }
        // cache not found, process and cache result if needed
        // select best matching method (get,post, post multpart (file))
        boolean isBinary = false;
        boolean doMultiPart = doUploadFile || this.multiPart;
        HttpEntityEnclosingRequest eeReqPost = null;
        HttpEntityEnclosingRequest eeReq = null;
        if (this.method == METHOD_GET) {
            req = new HttpGetWithBody(url);
            eeReq = (HttpEntityEnclosingRequest) req;
        } else if (this.method == METHOD_HEAD) {
            req = new HttpHead(url);
        } else if (this.method == METHOD_DELETE) {
            isBinary = true;
            req = new HttpDeleteWithBody(url);
            eeReq = (HttpEntityEnclosingRequest) req;
        } else if (this.method == METHOD_PUT) {
            isBinary = true;
            HttpPut put = new HttpPut(url);
            eeReqPost = put;
            req = put;
            eeReq = put;
        } else if (this.method == METHOD_TRACE) {
            isBinary = true;
            req = new HttpTrace(url);
        } else if (this.method == METHOD_OPTIONS) {
            isBinary = true;
            req = new HttpOptions(url);
        } else if (this.method == METHOD_PATCH) {
            isBinary = true;
            eeReq = HTTPPatchFactory.getHTTPPatch(url);
            req = (HttpRequestBase) eeReq;
        } else {
            isBinary = true;
            eeReqPost = new HttpPost(url);
            req = (HttpPost) eeReqPost;
            eeReq = eeReqPost;
        }
        boolean hasForm = false;
        boolean hasBody = false;
        boolean hasContentType = false;
        // Set http params
        ArrayList<FormBodyPart> parts = new ArrayList<FormBodyPart>();
        StringBuilder acceptEncoding = new StringBuilder();
        java.util.List<NameValuePair> postParam = eeReqPost != null ? new ArrayList<NameValuePair>() : null;
        for (int i = 0; i < len; i++) {
            HttpParamBean param = this.params.get(i);
            int type = param.getType();
            // URL
            if (type == HttpParamBean.TYPE_URL) {
            // listQS.add(new BasicNameValuePair(translateEncoding(param.getName(), http.charset),translateEncoding(param.getValueAsString(),
            // http.charset)));
            } else // Form
            if (type == HttpParamBean.TYPE_FORM) {
                hasForm = true;
                if (this.method == METHOD_GET)
                    throw new ApplicationException("httpparam with type formfield can only be used when the method attribute of the parent http tag is set to post");
                if (eeReqPost != null) {
                    if (doMultiPart) {
                        parts.add(new FormBodyPart(param.getName(), new StringBody(param.getValueAsString(), CharsetUtil.toCharset(charset))));
                    } else {
                        postParam.add(new BasicNameValuePair(param.getName(), param.getValueAsString()));
                    }
                }
            // else if(multi!=null)multi.addParameter(param.getName(),param.getValueAsString());
            } else // CGI
            if (type == HttpParamBean.TYPE_CGI) {
                if (param.getEncoded())
                    req.addHeader(urlenc(param.getName(), charset), urlenc(param.getValueAsString(), charset));
                else
                    req.addHeader(param.getName(), param.getValueAsString());
            } else // Header
            if (type == HttpParamBean.TYPE_HEADER) {
                if (param.getName().equalsIgnoreCase("content-type"))
                    hasContentType = true;
                if (param.getName().equalsIgnoreCase("Content-Length")) {
                } else if (param.getName().equalsIgnoreCase("Accept-Encoding")) {
                    acceptEncoding.append(headerValue(param.getValueAsString()));
                    acceptEncoding.append(", ");
                } else
                    req.addHeader(param.getName(), headerValue(param.getValueAsString()));
            } else // Cookie
            if (type == HttpParamBean.TYPE_COOKIE) {
                HTTPEngine4Impl.addCookie(cookieStore, host, param.getName(), param.getValueAsString(), "/", charset);
            } else // File
            if (type == HttpParamBean.TYPE_FILE) {
                hasForm = true;
                if (this.method == METHOD_GET)
                    throw new ApplicationException("httpparam type file can't only be used, when method of the tag http equal post");
                // if(param.getFile()==null) throw new ApplicationException("httpparam type file can't only be used, when method of the tag http equal
                // post");
                String strCT = getContentType(param);
                ContentType ct = HTTPUtil.toContentType(strCT, null);
                String mt = "text/xml";
                if (ct != null && !StringUtil.isEmpty(ct.getMimeType(), true))
                    mt = ct.getMimeType();
                String cs = charset;
                if (ct != null && !StringUtil.isEmpty(ct.getCharset(), true))
                    cs = ct.getCharset();
                if (doMultiPart) {
                    try {
                        Resource res = param.getFile();
                        parts.add(new FormBodyPart(param.getName(), new ResourceBody(res, mt, res.getName(), cs)));
                    // parts.add(new ResourcePart(param.getName(),new ResourcePartSource(param.getFile()),getContentType(param),_charset));
                    } catch (FileNotFoundException e) {
                        throw new ApplicationException("can't upload file, path is invalid", e.getMessage());
                    }
                }
            } else // XML
            if (type == HttpParamBean.TYPE_XML) {
                ContentType ct = HTTPUtil.toContentType(param.getMimeType(), null);
                String mt = "text/xml";
                if (ct != null && !StringUtil.isEmpty(ct.getMimeType(), true))
                    mt = ct.getMimeType();
                String cs = charset;
                if (ct != null && !StringUtil.isEmpty(ct.getCharset(), true))
                    cs = ct.getCharset();
                hasBody = true;
                hasContentType = true;
                req.addHeader("Content-type", mt + "; charset=" + cs);
                if (eeReq == null)
                    throw new ApplicationException("type xml is only supported for methods get, delete, post, and put");
                HTTPEngine4Impl.setBody(eeReq, param.getValueAsString(), mt, cs);
            } else // Body
            if (type == HttpParamBean.TYPE_BODY) {
                ContentType ct = HTTPUtil.toContentType(param.getMimeType(), null);
                String mt = null;
                if (ct != null && !StringUtil.isEmpty(ct.getMimeType(), true))
                    mt = ct.getMimeType();
                String cs = charset;
                if (ct != null && !StringUtil.isEmpty(ct.getCharset(), true))
                    cs = ct.getCharset();
                hasBody = true;
                if (eeReq == null)
                    throw new ApplicationException("type body is only supported for methods get, delete, post, and put");
                HTTPEngine4Impl.setBody(eeReq, param.getValue(), mt, cs);
            } else {
                throw new ApplicationException("invalid type [" + type + "]");
            }
        }
        // post params
        if (postParam != null && postParam.size() > 0)
            eeReqPost.setEntity(new org.apache.http.client.entity.UrlEncodedFormEntity(postParam, charset));
        if (compression) {
            acceptEncoding.append("gzip");
        } else {
            acceptEncoding.append("deflate;q=0");
            req.setHeader("TE", "deflate;q=0");
        }
        req.setHeader("Accept-Encoding", acceptEncoding.toString());
        // multipart
        if (doMultiPart && eeReq != null) {
            hasContentType = true;
            boolean doIt = true;
            if (!this.multiPart && parts.size() == 1) {
                ContentBody body = parts.get(0).getBody();
                if (body instanceof StringBody) {
                    StringBody sb = (StringBody) body;
                    try {
                        org.apache.http.entity.ContentType ct = org.apache.http.entity.ContentType.create(sb.getMimeType(), sb.getCharset());
                        String str = IOUtil.toString(sb.getReader());
                        StringEntity entity = new StringEntity(str, ct);
                        eeReq.setEntity(entity);
                    } catch (IOException e) {
                        throw Caster.toPageException(e);
                    }
                    doIt = false;
                }
            }
            if (doIt) {
                MultipartEntityBuilder mpeBuilder = MultipartEntityBuilder.create().setStrictMode();
                // enabling the line below will append charset=... to the Content-Type header
                // if (!StringUtil.isEmpty(charset, true))
                // mpeBuilder.setCharset(CharsetUtil.toCharset(charset));
                Iterator<FormBodyPart> it = parts.iterator();
                while (it.hasNext()) {
                    FormBodyPart part = it.next();
                    mpeBuilder.addPart(part);
                }
                eeReq.setEntity(mpeBuilder.build());
            }
        // eem.setRequestEntity(new MultipartRequestEntityFlex(parts.toArray(new Part[parts.size()]), eem.getParams(),http.multiPartType));
        }
        if (hasBody && hasForm)
            throw new ApplicationException("mixing httpparam  type file/formfield and body/XML is not allowed");
        if (!hasContentType) {
            if (isBinary) {
                if (hasBody)
                    req.addHeader("Content-type", "application/octet-stream");
                else
                    req.addHeader("Content-type", "application/x-www-form-urlencoded; charset=" + charset);
            } else {
                if (hasBody)
                    req.addHeader("Content-type", "text/html; charset=" + charset);
            }
        }
        // set User Agent
        if (!hasHeaderIgnoreCase(req, "User-Agent"))
            req.setHeader("User-Agent", this.useragent);
        // set timeout
        setTimeout(builder, checkRemainingTimeout());
        // set Username and Password
        if (this.username != null) {
            if (this.password == null)
                this.password = "";
            if (AUTH_TYPE_NTLM == this.authType) {
                if (StringUtil.isEmpty(this.workStation, true))
                    throw new ApplicationException("attribute workstation is required when authentication type is [NTLM]");
                if (StringUtil.isEmpty(this.domain, true))
                    throw new ApplicationException("attribute domain is required when authentication type is [NTLM]");
                HTTPEngine4Impl.setNTCredentials(builder, this.username, this.password, this.workStation, this.domain);
            } else
                httpContext = HTTPEngine4Impl.setCredentials(builder, httpHost, this.username, this.password, preauth);
        }
        // set Proxy
        ProxyData proxy = null;
        if (!StringUtil.isEmpty(this.proxyserver)) {
            proxy = ProxyDataImpl.getInstance(this.proxyserver, this.proxyport, this.proxyuser, this.proxypassword);
        }
        if (pageContext.getConfig().isProxyEnableFor(host)) {
            proxy = pageContext.getConfig().getProxyData();
        }
        HTTPEngine4Impl.setProxy(builder, req, proxy);
    }
    CloseableHttpClient client = null;
    try {
        if (httpContext == null)
            httpContext = new BasicHttpContext();
        Struct cfhttp = new StructImpl();
        cfhttp.setEL(ERROR_DETAIL, "");
        pageContext.setVariable(result, cfhttp);
        // ///////////////////////////////////////// EXECUTE /////////////////////////////////////////////////
        client = builder.build();
        Executor4 e = new Executor4(pageContext, this, client, httpContext, req, redirect);
        HTTPResponse4Impl rsp = null;
        if (timeout == null || timeout.getMillis() <= 0) {
            try {
                rsp = e.execute(httpContext);
            } catch (Throwable t) {
                ExceptionUtil.rethrowIfNecessary(t);
                if (!throwonerror) {
                    if (t instanceof SocketTimeoutException)
                        setRequestTimeout(cfhttp);
                    else
                        setUnknownHost(cfhttp, t);
                    return;
                }
                throw toPageException(t, rsp);
            }
        } else {
            e.start();
            try {
                synchronized (this) {
                    // print.err(timeout);
                    this.wait(timeout.getMillis());
                }
            } catch (InterruptedException ie) {
                throw Caster.toPageException(ie);
            }
            if (e.t != null) {
                if (!throwonerror) {
                    setUnknownHost(cfhttp, e.t);
                    return;
                }
                throw toPageException(e.t, rsp);
            }
            rsp = e.response;
            if (!e.done) {
                req.abort();
                if (throwonerror)
                    throw new HTTPException("408 Request Time-out", "a timeout occurred in tag http", 408, "Time-out", rsp == null ? null : rsp.getURL());
                setRequestTimeout(cfhttp);
                return;
            // throw new ApplicationException("timeout");
            }
        }
        // ///////////////////////////////////////// EXECUTE /////////////////////////////////////////////////
        Charset responseCharset = CharsetUtil.toCharset(rsp.getCharset());
        int statCode = 0;
        // Write Response Scope
        // String rawHeader=httpMethod.getStatusLine().toString();
        String mimetype = null;
        String contentEncoding = null;
        // status code
        cfhttp.set(STATUSCODE, ((rsp.getStatusCode() + " " + rsp.getStatusText()).trim()));
        cfhttp.set(STATUS_CODE, new Double(statCode = rsp.getStatusCode()));
        cfhttp.set(STATUS_TEXT, (rsp.getStatusText()));
        cfhttp.set(HTTP_VERSION, (rsp.getProtocolVersion()));
        // responseHeader
        lucee.commons.net.http.Header[] headers = rsp.getAllHeaders();
        StringBuffer raw = new StringBuffer(rsp.getStatusLine() + " ");
        Struct responseHeader = new StructImpl();
        Struct cookie;
        Array setCookie = new ArrayImpl();
        Query cookies = new QueryImpl(new String[] { "name", "value", "path", "domain", "expires", "secure", "httpOnly" }, 0, "cookies");
        for (int i = 0; i < headers.length; i++) {
            lucee.commons.net.http.Header header = headers[i];
            // print.ln(header);
            raw.append(header.toString() + " ");
            if (header.getName().equalsIgnoreCase("Set-Cookie")) {
                setCookie.append(header.getValue());
                parseCookie(cookies, header.getValue());
            } else {
                // print.ln(header.getName()+"-"+header.getValue());
                Object value = responseHeader.get(KeyImpl.getInstance(header.getName()), null);
                if (value == null)
                    responseHeader.set(KeyImpl.getInstance(header.getName()), header.getValue());
                else {
                    Array arr = null;
                    if (value instanceof Array) {
                        arr = (Array) value;
                    } else {
                        arr = new ArrayImpl();
                        responseHeader.set(KeyImpl.getInstance(header.getName()), arr);
                        arr.appendEL(value);
                    }
                    arr.appendEL(header.getValue());
                }
            }
            // Content-Type
            if (header.getName().equalsIgnoreCase("Content-Type")) {
                mimetype = header.getValue();
                if (mimetype == null)
                    mimetype = NO_MIMETYPE;
            }
            // Content-Encoding
            if (header.getName().equalsIgnoreCase("Content-Encoding")) {
                contentEncoding = header.getValue();
            }
        }
        cfhttp.set(RESPONSEHEADER, responseHeader);
        cfhttp.set(KeyConstants._cookies, cookies);
        responseHeader.set(STATUS_CODE, new Double(statCode = rsp.getStatusCode()));
        responseHeader.set(EXPLANATION, (rsp.getStatusText()));
        if (setCookie.size() > 0)
            responseHeader.set(SET_COOKIE, setCookie);
        // is text
        boolean isText = mimetype == null || mimetype == NO_MIMETYPE || HTTPUtil.isTextMimeType(mimetype);
        // is multipart
        boolean isMultipart = MultiPartResponseUtils.isMultipart(mimetype);
        cfhttp.set(KeyConstants._text, Caster.toBoolean(isText));
        // boolean responseProvideCharset=false;
        if (!StringUtil.isEmpty(mimetype, true)) {
            if (isText) {
                String[] types = HTTPUtil.splitMimeTypeAndCharset(mimetype, null);
                if (types[0] != null)
                    cfhttp.set(KeyConstants._mimetype, types[0]);
                if (types[1] != null)
                    cfhttp.set(CHARSET, types[1]);
            } else
                cfhttp.set(KeyConstants._mimetype, mimetype);
        } else
            cfhttp.set(KeyConstants._mimetype, NO_MIMETYPE);
        // File
        Resource file = null;
        if (strFile != null && strPath != null) {
            file = ResourceUtil.toResourceNotExisting(pageContext, strPath).getRealResource(strFile);
        } else if (strFile != null) {
            file = ResourceUtil.toResourceNotExisting(pageContext, strFile);
        } else if (strPath != null) {
            file = ResourceUtil.toResourceNotExisting(pageContext, strPath);
            // Resource dir = file.getParentResource();
            if (file.isDirectory()) {
                // TODO was getName()
                file = file.getRealResource(req.getURI().getPath());
            // ->http://hc.apache.org/httpclient-3.x/apidocs/org/apache/commons/httpclient/URI.html#getName()
            }
        }
        if (file != null)
            pageContext.getConfig().getSecurityManager().checkFileLocation(file);
        // filecontent
        InputStream is = null;
        if (isText && getAsBinary != GET_AS_BINARY_YES) {
            String str;
            try {
                // read content
                if (method != METHOD_HEAD) {
                    is = rsp.getContentAsStream();
                    if (is != null && isGzipEncoded(contentEncoding))
                        is = rsp.getStatusCode() != 200 ? new CachingGZIPInputStream(is) : new GZIPInputStream(is);
                }
                try {
                    try {
                        str = is == null ? "" : IOUtil.toString(is, responseCharset, checkRemainingTimeout().getMillis());
                    } catch (EOFException eof) {
                        if (is instanceof CachingGZIPInputStream) {
                            str = IOUtil.toString(is = ((CachingGZIPInputStream) is).getRawData(), responseCharset, checkRemainingTimeout().getMillis());
                        } else
                            throw eof;
                    }
                } catch (UnsupportedEncodingException uee) {
                    str = IOUtil.toString(is, (Charset) null, checkRemainingTimeout().getMillis());
                }
            } catch (IOException ioe) {
                throw Caster.toPageException(ioe);
            } finally {
                IOUtil.closeEL(is);
            }
            if (str == null)
                str = "";
            if (resolveurl) {
                // if(e.redirectURL!=null)url=e.redirectURL.toExternalForm();
                str = new URLResolver().transform(str, e.response.getTargetURL(), false);
            }
            cfhttp.set(KeyConstants._filecontent, str);
            try {
                if (file != null) {
                    IOUtil.write(file, str, ((PageContextImpl) pageContext).getWebCharset(), false);
                }
            } catch (IOException e1) {
            }
            if (name != null) {
                Query qry = CSVParser.toQuery(str, delimiter, textqualifier, columns, firstrowasheaders);
                pageContext.setVariable(name, qry);
            }
        } else // Binary
        {
            byte[] barr = null;
            if (isGzipEncoded(contentEncoding)) {
                if (method != METHOD_HEAD) {
                    is = rsp.getContentAsStream();
                    is = rsp.getStatusCode() != 200 ? new CachingGZIPInputStream(is) : new GZIPInputStream(is);
                }
                try {
                    try {
                        barr = is == null ? new byte[0] : IOUtil.toBytes(is);
                    } catch (EOFException eof) {
                        if (is instanceof CachingGZIPInputStream)
                            barr = IOUtil.toBytes(((CachingGZIPInputStream) is).getRawData());
                        else
                            throw eof;
                    }
                } catch (IOException t) {
                    throw Caster.toPageException(t);
                } finally {
                    IOUtil.closeEL(is);
                }
            } else {
                try {
                    if (method != METHOD_HEAD)
                        barr = rsp.getContentAsByteArray();
                    else
                        barr = new byte[0];
                } catch (IOException t) {
                    throw Caster.toPageException(t);
                }
            }
            // IF Multipart response get file content and parse parts
            if (barr != null) {
                if (isMultipart) {
                    cfhttp.set(KeyConstants._filecontent, MultiPartResponseUtils.getParts(barr, mimetype));
                } else {
                    cfhttp.set(KeyConstants._filecontent, barr);
                }
            } else
                cfhttp.set(KeyConstants._filecontent, "");
            if (file != null) {
                try {
                    if (barr != null)
                        IOUtil.copy(new ByteArrayInputStream(barr), file, true);
                } catch (IOException ioe) {
                    throw Caster.toPageException(ioe);
                }
            }
        }
        // header
        cfhttp.set(KeyConstants._header, raw.toString());
        if (!isStatusOK(rsp.getStatusCode())) {
            String msg = rsp.getStatusCode() + " " + rsp.getStatusText();
            cfhttp.setEL(ERROR_DETAIL, msg);
            if (throwonerror) {
                throw new HTTPException(msg, null, rsp.getStatusCode(), rsp.getStatusText(), rsp.getURL());
            }
        }
        // TODO: check if we can use statCode instead of rsp.getStatusCode() everywhere and cleanup the code
        if (cacheHandler != null && rsp.getStatusCode() == 200) {
            // add to cache
            cacheHandler.set(pageContext, cacheId, cachedWithin, new HTTPCacheItem(cfhttp, url, System.nanoTime() - start));
        }
    } finally {
        if (client != null)
            client.close();
    }
}
Also used : HttpPost(org.apache.http.client.methods.HttpPost) HttpRequestBase(org.apache.http.client.methods.HttpRequestBase) MalformedURLException(java.net.MalformedURLException) MultipartEntityBuilder(org.apache.http.entity.mime.MultipartEntityBuilder) ContentType(lucee.commons.lang.mimetype.ContentType) Query(lucee.runtime.type.Query) ArrayImpl(lucee.runtime.type.ArrayImpl) HttpOptions(org.apache.http.client.methods.HttpOptions) ArrayList(java.util.ArrayList) FileNotFoundException(java.io.FileNotFoundException) HttpPut(org.apache.http.client.methods.HttpPut) StringEntity(org.apache.http.entity.StringEntity) ProxyData(lucee.runtime.net.proxy.ProxyData) HttpHost(org.apache.http.HttpHost) HttpEntityEnclosingRequest(org.apache.http.HttpEntityEnclosingRequest) BasicNameValuePair(org.apache.http.message.BasicNameValuePair) CachingGZIPInputStream(lucee.commons.net.http.httpclient.CachingGZIPInputStream) EOFException(java.io.EOFException) ArrayList(java.util.ArrayList) List(java.util.List) Header(lucee.commons.net.http.Header) HTTPCacheItem(lucee.runtime.cache.tag.http.HTTPCacheItem) Resource(lucee.commons.io.res.Resource) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ResourceBody(lucee.commons.net.http.httpclient.ResourceBody) BasicCookieStore(org.apache.http.impl.client.BasicCookieStore) SocketTimeoutException(java.net.SocketTimeoutException) ContentBody(org.apache.http.entity.mime.content.ContentBody) Header(lucee.commons.net.http.Header) ByteArrayInputStream(java.io.ByteArrayInputStream) HTTPResponse4Impl(lucee.commons.net.http.httpclient.HTTPResponse4Impl) CacheHandler(lucee.runtime.cache.tag.CacheHandler) URLResolver(lucee.runtime.util.URLResolver) HTTPException(lucee.runtime.exp.HTTPException) BasicHttpContext(org.apache.http.protocol.BasicHttpContext) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder) URL(java.net.URL) HttpHead(org.apache.http.client.methods.HttpHead) Struct(lucee.runtime.type.Struct) FormBodyPart(org.apache.http.entity.mime.FormBodyPart) GZIPInputStream(java.util.zip.GZIPInputStream) CachingGZIPInputStream(lucee.commons.net.http.httpclient.CachingGZIPInputStream) QueryImpl(lucee.runtime.type.QueryImpl) CacheHandlerPro(lucee.runtime.cache.tag.CacheHandlerPro) Iterator(java.util.Iterator) DefaultRedirectStrategy(org.apache.http.impl.client.DefaultRedirectStrategy) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) GZIPInputStream(java.util.zip.GZIPInputStream) CachingGZIPInputStream(lucee.commons.net.http.httpclient.CachingGZIPInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) FileInputStream(java.io.FileInputStream) InputStream(java.io.InputStream) HttpContext(org.apache.http.protocol.HttpContext) BasicHttpContext(org.apache.http.protocol.BasicHttpContext) Charset(java.nio.charset.Charset) PageContextImpl(lucee.runtime.PageContextImpl) IOException(java.io.IOException) ConfigWeb(lucee.runtime.config.ConfigWeb) Array(lucee.runtime.type.Array) HttpTrace(org.apache.http.client.methods.HttpTrace) ApplicationException(lucee.runtime.exp.ApplicationException) StructImpl(lucee.runtime.type.StructImpl) StringBody(org.apache.http.entity.mime.content.StringBody) CacheItem(lucee.runtime.cache.tag.CacheItem) HTTPCacheItem(lucee.runtime.cache.tag.http.HTTPCacheItem)

Example 99 with HttpContext

use of org.apache.http.protocol.HttpContext in project Lucee by lucee.

the class HTTPEngine4Impl method _invoke.

private static HTTPResponse _invoke(URL url, HttpUriRequest request, String username, String password, long timeout, boolean redirect, String charset, String useragent, ProxyData proxy, lucee.commons.net.http.Header[] headers, Map<String, String> formfields) throws IOException {
    HttpClientBuilder builder = getHttpClientBuilder();
    // redirect
    if (redirect)
        builder.setRedirectStrategy(new DefaultRedirectStrategy());
    else
        builder.disableRedirectHandling();
    HttpHost hh = new HttpHost(url.getHost(), url.getPort());
    setHeader(request, headers);
    if (CollectionUtil.isEmpty(formfields))
        setContentType(request, charset);
    setFormFields(request, formfields, charset);
    setUserAgent(request, useragent);
    if (timeout > 0)
        Http.setTimeout(builder, TimeSpanImpl.fromMillis(timeout));
    HttpContext context = setCredentials(builder, hh, username, password, false);
    setProxy(builder, request, proxy);
    CloseableHttpClient client = builder.build();
    if (context == null)
        context = new BasicHttpContext();
    return new HTTPResponse4Impl(url, context, request, client.execute(request, context));
}
Also used : CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) HttpHost(org.apache.http.HttpHost) BasicHttpContext(org.apache.http.protocol.BasicHttpContext) BasicHttpContext(org.apache.http.protocol.BasicHttpContext) HttpContext(org.apache.http.protocol.HttpContext) DefaultRedirectStrategy(org.apache.http.impl.client.DefaultRedirectStrategy) HttpClientBuilder(org.apache.http.impl.client.HttpClientBuilder)

Example 100 with HttpContext

use of org.apache.http.protocol.HttpContext in project uavstack by uavorg.

the class ApacheAsyncHttpClientIT method doAsyncStart.

/**
 * for async http client
 *
 * @param args
 * @return
 */
@SuppressWarnings({ "rawtypes", "unused", "unchecked" })
public FutureCallback doAsyncStart(Object[] args) {
    HttpAsyncRequestProducer requestProducer = null;
    HttpAsyncResponseConsumer responseConsumer = null;
    HttpContext context = null;
    FutureCallback callback = null;
    Map mObj = null;
    if (args.length == 4) {
        requestProducer = (HttpAsyncRequestProducer) args[0];
        responseConsumer = (HttpAsyncResponseConsumer) args[1];
        context = (HttpContext) args[2];
        callback = (FutureCallback) args[3];
    } else if (args.length == 5) {
        requestProducer = (HttpAsyncRequestProducer) args[1];
        responseConsumer = (HttpAsyncResponseConsumer) args[2];
        context = (HttpContext) args[3];
        callback = (FutureCallback) args[4];
    }
    String httpAction = null;
    try {
        HttpRequest hr = requestProducer.generateRequest();
        /**
         * 呵呵,就是把UAV的客户端标记加到http header里面,接收方就知道是哪个东东调用的了,便于实现来源快速匹配,这个模式只适合直连模式
         *
         * 对于代理模式,只匹配代理源即可
         */
        hr.addHeader("UAV-Client-Src", MonitorServerUtil.getUAVClientSrc(this.applicationId));
        RequestLine rl = hr.getRequestLine();
        httpAction = rl.getMethod();
        targetURL = rl.getUri();
    } catch (IOException e) {
        // ignore thie exception
        return null;
    } catch (HttpException e) {
        // ignore thie exception
        return null;
    }
    Map<String, Object> params = new HashMap<String, Object>();
    params.put(CaptureConstants.INFO_CLIENT_REQUEST_URL, targetURL);
    params.put(CaptureConstants.INFO_CLIENT_REQUEST_ACTION, httpAction);
    params.put(CaptureConstants.INFO_CLIENT_APPID, this.applicationId);
    params.put(CaptureConstants.INFO_CLIENT_TYPE, "apache.http.AsyncClient");
    if (logger.isDebugable()) {
        logger.debug("Invoke START:" + targetURL + "," + httpAction + "," + this.applicationId, null);
    }
    /**
     * for async, as not in the same thread
     */
    ccMap = UAVServer.instance().runMonitorAsyncCaptureOnServerCapPoint(CaptureConstants.CAPPOINT_APP_CLIENT, Monitor.CapturePhase.PRECAP, params, null);
    // register invokechain adapter
    UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "registerAdapter", ApacheAsyncHttpClientAdapter.class);
    ccMap4Chain = (Map<String, Object>) UAVServer.instance().runSupporter("com.creditease.uav.apm.supporters.InvokeChainSupporter", "runCap", InvokeChainConstants.CHAIN_APP_CLIENT, InvokeChainConstants.CapturePhase.PRECAP, params, ApacheAsyncHttpClientAdapter.class, args);
    if (callback == null) {
        return null;
    }
    callback = JDKProxyInvokeUtil.newProxyInstance(HttpContext.class.getClassLoader(), new Class<?>[] { FutureCallback.class }, new JDKProxyInvokeHandler<FutureCallback>(callback, new FutureCallbackProxyInvokeProcessor(ccMap4Chain)));
    return callback;
}
Also used : HttpRequest(org.apache.http.HttpRequest) HashMap(java.util.HashMap) JDKProxyInvokeHandler(com.creditease.monitor.proxy.spi.JDKProxyInvokeHandler) HttpContext(org.apache.http.protocol.HttpContext) HttpAsyncResponseConsumer(org.apache.http.nio.protocol.HttpAsyncResponseConsumer) IOException(java.io.IOException) RequestLine(org.apache.http.RequestLine) HttpAsyncRequestProducer(org.apache.http.nio.protocol.HttpAsyncRequestProducer) HttpException(org.apache.http.HttpException) HashMap(java.util.HashMap) Map(java.util.Map) FutureCallback(org.apache.http.concurrent.FutureCallback)

Aggregations

HttpContext (org.apache.http.protocol.HttpContext)169 HttpResponse (org.apache.http.HttpResponse)77 IOException (java.io.IOException)72 HttpRequest (org.apache.http.HttpRequest)55 BasicHttpContext (org.apache.http.protocol.BasicHttpContext)47 HttpException (org.apache.http.HttpException)30 Test (org.junit.Test)29 HttpGet (org.apache.http.client.methods.HttpGet)27 HttpHost (org.apache.http.HttpHost)26 HttpPost (org.apache.http.client.methods.HttpPost)26 ArrayList (java.util.ArrayList)22 Header (org.apache.http.Header)21 StringEntity (org.apache.http.entity.StringEntity)21 NameValuePair (org.apache.http.NameValuePair)18 BasicNameValuePair (org.apache.http.message.BasicNameValuePair)18 ProtocolException (org.apache.http.ProtocolException)17 UrlEncodedFormEntity (org.apache.http.client.entity.UrlEncodedFormEntity)17 DefaultHttpClient (org.apache.http.impl.client.DefaultHttpClient)17 URI (java.net.URI)16 HttpUriRequest (org.apache.http.client.methods.HttpUriRequest)16